00001
00002
00003
00004
00005
00006 #ifdef __linux
00007 #include <time.h>
00008 #else
00009 typedef int clockid_t;
00010 #define CLOCK_REALTIME 0
00011 #define CLOCK_MONOTONIC 1
00012 #define CLOCK_PROCESS_CPUTIME_ID 2
00013 #define CLOCK_THREAD_CPUTIME_ID 3
00014 #endif
00015
00016
00017 #include <cmath>
00018 #include <limits>
00019 #include <iostream>
00020 #include <iomanip>
00021 #include <string>
00022 #include <sstream>
00023 #include <tr1/unordered_set>
00024 #include <tr1/unordered_map>
00025
00026
00027 #include <boost/format.hpp>
00028
00029
00030 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00031 #include "FWCore/ServiceRegistry/interface/Service.h"
00032 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00033 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00034 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00035 #include "FWCore/Framework/interface/Event.h"
00036 #include "FWCore/Framework/interface/LuminosityBlock.h"
00037 #include "FWCore/Framework/interface/TriggerNamesService.h"
00038 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00039 #include "DataFormats/Common/interface/HLTPathStatus.h"
00040 #include "DataFormats/Provenance/interface/EventID.h"
00041 #include "DataFormats/Provenance/interface/Timestamp.h"
00042 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00043 #include "DQMServices/Core/interface/DQMStore.h"
00044 #include "DQMServices/Core/interface/MonitorElement.h"
00045 #include "HLTrigger/Timer/interface/FastTimerService.h"
00046 #include "HLTrigger/Timer/interface/CPUAffinity.h"
00047
00048
00049
00050 static
00051 void fill_dups(std::vector<std::string> & dups, unsigned int size) {
00052 dups.reserve(size);
00053 for (unsigned int i = dups.size(); i < size; ++i)
00054 dups.push_back( (boost::format("(dup.) (%d)") % i).str() );
00055 }
00056
00057
00058 FastTimerService::FastTimerService(const edm::ParameterSet & config, edm::ActivityRegistry & registry) :
00059
00060 m_timer_id( config.getUntrackedParameter<bool>( "useRealTimeClock" ) ? CLOCK_REALTIME : CLOCK_THREAD_CPUTIME_ID),
00061 m_is_cpu_bound( false ),
00062 m_enable_timing_paths( config.getUntrackedParameter<bool>( "enableTimingPaths" ) ),
00063 m_enable_timing_modules( config.getUntrackedParameter<bool>( "enableTimingModules" ) ),
00064 m_enable_timing_exclusive( config.getUntrackedParameter<bool>( "enableTimingExclusive" ) ),
00065 m_enable_timing_summary( config.getUntrackedParameter<bool>( "enableTimingSummary" ) ),
00066 m_skip_first_path( config.getUntrackedParameter<bool>( "skipFirstPath" ) ),
00067
00068 m_enable_dqm( config.getUntrackedParameter<bool>( "enableDQM" ) ),
00069 m_enable_dqm_bypath_active( config.getUntrackedParameter<bool>( "enableDQMbyPathActive" ) ),
00070 m_enable_dqm_bypath_total( config.getUntrackedParameter<bool>( "enableDQMbyPathTotal" ) ),
00071 m_enable_dqm_bypath_overhead( config.getUntrackedParameter<bool>( "enableDQMbyPathOverhead" ) ),
00072 m_enable_dqm_bypath_details( config.getUntrackedParameter<bool>( "enableDQMbyPathDetails" ) ),
00073 m_enable_dqm_bypath_counters( config.getUntrackedParameter<bool>( "enableDQMbyPathCounters" ) ),
00074 m_enable_dqm_bypath_exclusive( config.getUntrackedParameter<bool>( "enableDQMbyPathExclusive" ) ),
00075 m_enable_dqm_bymodule( config.getUntrackedParameter<bool>( "enableDQMbyModule" ) ),
00076 m_enable_dqm_bylumi( config.getUntrackedParameter<bool>( "enableDQMbyLumi" ) ),
00077 m_dqm_eventtime_range( config.getUntrackedParameter<double>( "dqmTimeRange" ) ),
00078 m_dqm_eventtime_resolution( config.getUntrackedParameter<double>( "dqmTimeResolution" ) ),
00079 m_dqm_pathtime_range( config.getUntrackedParameter<double>( "dqmPathTimeRange" ) ),
00080 m_dqm_pathtime_resolution( config.getUntrackedParameter<double>( "dqmPathTimeResolution" ) ),
00081 m_dqm_moduletime_range( config.getUntrackedParameter<double>( "dqmModuleTimeRange" ) ),
00082 m_dqm_moduletime_resolution( config.getUntrackedParameter<double>( "dqmModuleTimeResolution" ) ),
00083 m_dqm_lumi_range( config.getUntrackedParameter<uint32_t>( "dqmLumiSectionsRange" ) ),
00084 m_dqm_path( config.getUntrackedParameter<std::string>("dqmPath" ) ),
00085
00086 m_first_path(0),
00087 m_last_path(0),
00088 m_first_endpath(0),
00089 m_last_endpath(0),
00090 m_is_first_module(false),
00091
00092 m_event(0.),
00093 m_source(0.),
00094 m_all_paths(0.),
00095 m_all_endpaths(0.),
00096
00097 m_summary_events(0),
00098 m_summary_event(0.),
00099 m_summary_source(0.),
00100 m_summary_all_paths(0.),
00101 m_summary_all_endpaths(0.),
00102
00103 m_dqms(0),
00104 m_dqm_event(0),
00105 m_dqm_source(0),
00106 m_dqm_all_paths(0),
00107 m_dqm_all_endpaths(0),
00108 m_dqm_paths_active_time(0),
00109 m_dqm_paths_total_time(0),
00110 m_dqm_paths_exclusive_time(0),
00111
00112 m_dqm_bylumi_event(0),
00113 m_dqm_bylumi_source(0),
00114 m_dqm_bylumi_all_paths(0),
00115 m_dqm_bylumi_all_endpaths(0),
00116
00117 m_current_path(0),
00118 m_paths(),
00119 m_modules(),
00120 m_cache_paths(),
00121 m_cache_modules()
00122 {
00123
00124 m_enable_timing_paths = m_enable_timing_paths or m_enable_dqm_bypath_active or m_enable_dqm_bypath_total or m_enable_dqm_bypath_overhead or m_enable_dqm_bypath_details or m_enable_dqm_bypath_counters or m_enable_dqm_bypath_exclusive;
00125 m_enable_timing_modules = m_enable_timing_modules or m_enable_dqm_bymodule or m_enable_dqm_bypath_total or m_enable_dqm_bypath_overhead or m_enable_dqm_bypath_details or m_enable_dqm_bypath_counters or m_enable_dqm_bypath_exclusive;
00126 m_enable_timing_exclusive = m_enable_timing_exclusive or m_enable_dqm_bypath_exclusive;
00127
00128 registry.watchPreModuleBeginJob( this, & FastTimerService::preModuleBeginJob );
00129 registry.watchPostBeginJob( this, & FastTimerService::postBeginJob );
00130 registry.watchPostEndJob( this, & FastTimerService::postEndJob );
00131 registry.watchPrePathBeginRun( this, & FastTimerService::prePathBeginRun) ;
00132 registry.watchPreProcessEvent( this, & FastTimerService::preProcessEvent );
00133 registry.watchPostProcessEvent( this, & FastTimerService::postProcessEvent );
00134 registry.watchPreSource( this, & FastTimerService::preSource );
00135 registry.watchPostSource( this, & FastTimerService::postSource );
00136
00137 registry.watchPreProcessPath( this, & FastTimerService::preProcessPath );
00138 registry.watchPostProcessPath( this, & FastTimerService::postProcessPath );
00139
00140 if (m_enable_timing_modules) {
00141 registry.watchPreModule( this, & FastTimerService::preModule );
00142 registry.watchPostModule( this, & FastTimerService::postModule );
00143 }
00144
00145 #if defined(__APPLE__) || defined (__MACH__)
00146 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &m_clock_port);
00147 #endif // defined(__APPLE__) || defined(__MACH__)
00148 }
00149
00150 FastTimerService::~FastTimerService()
00151 {
00152 #if defined(__APPLE__) || defined (__MACH__)
00153 mach_port_deallocate(mach_task_self(), m_clock_port);
00154 #endif // defined(__APPLE__) || defined(__MACH__)
00155 }
00156
00157 void FastTimerService::postBeginJob() {
00158
00159
00160
00161
00162 m_is_cpu_bound = CPUAffinity::isCpuBound();
00163 if ((m_timer_id != CLOCK_REALTIME) and not m_is_cpu_bound)
00164
00165 edm::LogError("FastTimerService") << "this process is NOT bound to a single CPU, the results of the FastTimerService may be undefined";
00166
00167 edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00168 uint32_t size_p = tns.getTrigPaths().size();
00169 uint32_t size_e = tns.getEndPaths().size();
00170 uint32_t size = size_p + size_e;
00171 for (uint32_t i = 0; i < size_p; ++i) {
00172 std::string const & label = tns.getTrigPath(i);
00173 m_paths[label].index = i;
00174 }
00175 for (uint32_t i = 0; i < size_e; ++i) {
00176 std::string const & label = tns.getEndPath(i);
00177 m_paths[label].index = size_p + i;
00178 }
00179
00180
00181 m_cache_paths.reserve(m_paths.size());
00182 for (auto & keyval: m_paths)
00183 m_cache_paths.push_back(& keyval.second);
00184
00185
00186 m_cache_modules.reserve(m_modules.size());
00187 for (auto & keyval: m_modules)
00188 m_cache_modules.push_back(& keyval.second);
00189
00190
00191 for (uint32_t i = 0; i < tns.getTrigPaths().size(); ++i)
00192 fillPathMap( tns.getTrigPath(i), tns.getTrigPathModules(i) );
00193 for (uint32_t i = 0; i < tns.getEndPaths().size(); ++i)
00194 fillPathMap( tns.getEndPath(i), tns.getEndPathModules(i) );
00195
00196 if (m_enable_dqm)
00197
00198 m_dqms = edm::Service<DQMStore>().operator->();
00199
00200 if (m_dqms) {
00201
00202 int eventbins = (int) std::ceil(m_dqm_eventtime_range / m_dqm_eventtime_resolution);
00203 int pathbins = (int) std::ceil(m_dqm_pathtime_range / m_dqm_pathtime_resolution);
00204 int modulebins = (int) std::ceil(m_dqm_moduletime_range / m_dqm_moduletime_resolution);
00205
00206 m_dqms->setCurrentFolder(m_dqm_path);
00207
00208
00209 m_dqm_event = m_dqms->book1D("event", "Event processing time", eventbins, 0., m_dqm_eventtime_range)->getTH1F();
00210 m_dqm_event ->StatOverflows(true);
00211 m_dqm_event ->SetXTitle("processing time [ms]");
00212 m_dqm_source = m_dqms->book1D("source", "Source processing time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00213 m_dqm_source ->StatOverflows(true);
00214 m_dqm_source ->SetXTitle("processing time [ms]");
00215 m_dqm_all_paths = m_dqms->book1D("all_paths", "Paths processing time", eventbins, 0., m_dqm_eventtime_range)->getTH1F();
00216 m_dqm_all_paths ->StatOverflows(true);
00217 m_dqm_all_paths ->SetXTitle("processing time [ms]");
00218 m_dqm_all_endpaths = m_dqms->book1D("all_endpaths", "EndPaths processing time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00219 m_dqm_all_endpaths ->StatOverflows(true);
00220 m_dqm_all_endpaths ->SetXTitle("processing time [ms]");
00221
00222
00223 m_dqm_paths_active_time = m_dqms->bookProfile("paths_active_time", "Additional time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00224 m_dqm_paths_active_time ->StatOverflows(true);
00225 m_dqm_paths_active_time ->SetYTitle("processing time [ms]");
00226 m_dqm_paths_total_time = m_dqms->bookProfile("paths_total_time", "Total time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00227 m_dqm_paths_total_time ->StatOverflows(true);
00228 m_dqm_paths_total_time ->SetYTitle("processing time [ms]");
00229 m_dqm_paths_exclusive_time = m_dqms->bookProfile("paths_exclusive_time", "Exclusive time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00230 m_dqm_paths_exclusive_time ->StatOverflows(true);
00231 m_dqm_paths_exclusive_time ->SetYTitle("processing time [ms]");
00232
00233 for (uint32_t i = 0; i < size_p; ++i) {
00234 std::string const & label = tns.getTrigPath(i);
00235 m_dqm_paths_active_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00236 m_dqm_paths_total_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00237 m_dqm_paths_exclusive_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
00238 }
00239 for (uint32_t i = 0; i < size_e; ++i) {
00240 std::string const & label = tns.getEndPath(i);
00241 m_dqm_paths_active_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00242 m_dqm_paths_total_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00243 m_dqm_paths_exclusive_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
00244 }
00245
00246
00247 if (m_enable_dqm_bylumi) {
00248 m_dqm_bylumi_event = m_dqms->bookProfile("event_bylumi", "Event processing time, by Lumisection", m_dqm_lumi_range, 0.5, m_dqm_lumi_range+0.5, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00249 m_dqm_bylumi_event ->StatOverflows(true);
00250 m_dqm_bylumi_event ->SetYTitle("processing time [ms]");
00251 m_dqm_bylumi_source = m_dqms->bookProfile("source_bylumi", "Source processing time, by Lumisection", m_dqm_lumi_range, 0.5, m_dqm_lumi_range+0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00252 m_dqm_bylumi_source ->StatOverflows(true);
00253 m_dqm_bylumi_source ->SetYTitle("processing time [ms]");
00254 m_dqm_bylumi_all_paths = m_dqms->bookProfile("all_paths_bylumi", "Paths processing time, by Lumisection", m_dqm_lumi_range, 0.5, m_dqm_lumi_range+0.5, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00255 m_dqm_bylumi_all_paths ->StatOverflows(true);
00256 m_dqm_bylumi_all_paths ->SetYTitle("processing time [ms]");
00257 m_dqm_bylumi_all_endpaths = m_dqms->bookProfile("all_endpaths_bylumi", "EndPaths processing time, by Lumisection", m_dqm_lumi_range, 0.5, m_dqm_lumi_range+0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
00258 m_dqm_bylumi_all_endpaths ->StatOverflows(true);
00259 m_dqm_bylumi_all_endpaths ->SetYTitle("processing time [ms]");
00260 }
00261
00262
00263 if (m_enable_timing_paths) {
00264 m_dqms->setCurrentFolder((m_dqm_path + "/Paths"));
00265 for (auto & keyval: m_paths) {
00266 std::string const & pathname = keyval.first;
00267 PathInfo & pathinfo = keyval.second;
00268
00269 if (m_enable_dqm_bypath_active) {
00270 pathinfo.dqm_active = m_dqms->book1D(pathname + "_active", pathname + " active time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00271 pathinfo.dqm_active ->StatOverflows(true);
00272 pathinfo.dqm_active ->SetXTitle("processing time [ms]");
00273 }
00274
00275 if (m_enable_dqm_bypath_total) {
00276 pathinfo.dqm_total = m_dqms->book1D(pathname + "_total", pathname + " total time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00277 pathinfo.dqm_total ->StatOverflows(true);
00278 pathinfo.dqm_total ->SetXTitle("processing time [ms]");
00279 }
00280
00281 if (m_enable_dqm_bypath_overhead) {
00282 pathinfo.dqm_premodules = m_dqms->book1D(pathname + "_premodules", pathname + " pre-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00283 pathinfo.dqm_premodules ->StatOverflows(true);
00284 pathinfo.dqm_premodules ->SetXTitle("processing time [ms]");
00285 pathinfo.dqm_intermodules = m_dqms->book1D(pathname + "_intermodules", pathname + " inter-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00286 pathinfo.dqm_intermodules ->StatOverflows(true);
00287 pathinfo.dqm_intermodules ->SetXTitle("processing time [ms]");
00288 pathinfo.dqm_postmodules = m_dqms->book1D(pathname + "_postmodules", pathname + " post-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00289 pathinfo.dqm_postmodules ->StatOverflows(true);
00290 pathinfo.dqm_postmodules ->SetXTitle("processing time [ms]");
00291 pathinfo.dqm_overhead = m_dqms->book1D(pathname + "_overhead", pathname + " overhead time", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00292 pathinfo.dqm_overhead ->StatOverflows(true);
00293 pathinfo.dqm_overhead ->SetXTitle("processing time [ms]");
00294 }
00295
00296 if (m_enable_dqm_bypath_details or m_enable_dqm_bypath_counters) {
00297
00298
00299
00300 uint32_t id;
00301 std::vector<std::string> const & modules = ((id = tns.findTrigPath(pathname)) != tns.getTrigPaths().size()) ? tns.getTrigPathModules(id) :
00302 ((id = tns.findEndPath(pathname)) != tns.getEndPaths().size()) ? tns.getEndPathModules(id) :
00303 std::vector<std::string>();
00304
00305 static std::vector<std::string> dup;
00306 if (modules.size() > dup.size())
00307 fill_dups(dup, modules.size());
00308
00309 std::vector<const char *> labels(modules.size(), nullptr);
00310 for (uint32_t i = 0; i < modules.size(); ++i)
00311 labels[i] = (pathinfo.modules[i]) ? modules[i].c_str() : dup[i].c_str();
00312
00313
00314 if (m_enable_dqm_bypath_counters) {
00315 pathinfo.dqm_module_counter = m_dqms->book1D(pathname + "_module_counter", pathname + " module counter", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00316
00317 for (uint32_t i = 0; i < modules.size(); ++i) {
00318 pathinfo.dqm_module_counter->GetXaxis()->SetBinLabel( i+1, labels[i] );
00319 }
00320 }
00321
00322 if (m_enable_dqm_bypath_details) {
00323 pathinfo.dqm_module_active = m_dqms->book1D(pathname + "_module_active", pathname + " module active", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00324 pathinfo.dqm_module_active ->SetYTitle("cumulative processing time [ms]");
00325 pathinfo.dqm_module_total = m_dqms->book1D(pathname + "_module_total", pathname + " module total", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
00326 pathinfo.dqm_module_total ->SetYTitle("cumulative processing time [ms]");
00327
00328 for (uint32_t i = 0; i < modules.size(); ++i) {
00329 pathinfo.dqm_module_active ->GetXaxis()->SetBinLabel( i+1, labels[i] );
00330 pathinfo.dqm_module_total ->GetXaxis()->SetBinLabel( i+1, labels[i] );
00331 }
00332 }
00333 }
00334
00335
00336 if (m_enable_dqm_bypath_exclusive) {
00337 pathinfo.dqm_exclusive = m_dqms->book1D(pathname + "_exclusive", pathname + " exclusive time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
00338 pathinfo.dqm_exclusive ->StatOverflows(true);
00339 pathinfo.dqm_exclusive ->SetYTitle("processing time [ms]");
00340 }
00341
00342 }
00343 }
00344
00345 if (m_enable_dqm_bymodule) {
00346 m_dqms->setCurrentFolder((m_dqm_path + "/Modules"));
00347 for (auto & keyval: m_modules) {
00348 std::string const & label = keyval.first->moduleLabel();
00349 ModuleInfo & module = keyval.second;
00350 module.dqm_active = m_dqms->book1D(label, label, modulebins, 0., m_dqm_moduletime_range)->getTH1F();
00351 module.dqm_active->StatOverflows(true);
00352 module.dqm_active->SetYTitle("processing time [ms]");
00353 }
00354 }
00355
00356 }
00357 }
00358
00359 void FastTimerService::postEndJob() {
00360
00361
00362 if (m_enable_timing_summary) {
00363
00364 edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00365
00366 std::ostringstream out;
00367 out << std::fixed << std::setprecision(6);
00368 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << '\n';
00369 out << "FastReport " << std::right << std::setw(10) << m_summary_source / (double) m_summary_events << " Source" << '\n';
00370 out << "FastReport " << std::right << std::setw(10) << m_summary_event / (double) m_summary_events << " Event" << '\n';
00371 out << "FastReport " << std::right << std::setw(10) << m_summary_all_paths / (double) m_summary_events << " all Paths" << '\n';
00372 out << "FastReport " << std::right << std::setw(10) << m_summary_all_endpaths / (double) m_summary_events << " all EndPaths" << '\n';
00373 if (m_enable_timing_modules) {
00374 double modules_total = 0.;
00375 for (auto & keyval: m_modules)
00376 modules_total += keyval.second.summary_active;
00377 out << "FastReport " << std::right << std::setw(10) << modules_total / (double) m_summary_events << " all Modules" << '\n';
00378 }
00379 out << '\n';
00380 if (m_enable_timing_paths and not m_enable_timing_modules) {
00381 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Path" << '\n';
00382 for (auto const & name: tns.getTrigPaths())
00383 out << "FastReport "
00384 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00385 << name << '\n';
00386 out << '\n';
00387 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active EndPath" << '\n';
00388 for (auto const & name: tns.getEndPaths())
00389 out << "FastReport "
00390 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00391 << name << '\n';
00392 } else if (m_enable_timing_paths and m_enable_timing_modules) {
00393 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Pre- Inter- Post-mods Overhead Total Path" << '\n';
00394 for (auto const & name: tns.getTrigPaths()) {
00395 out << "FastReport "
00396 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00397 << std::right << std::setw(10) << m_paths[name].summary_premodules / (double) m_summary_events << " "
00398 << std::right << std::setw(10) << m_paths[name].summary_intermodules / (double) m_summary_events << " "
00399 << std::right << std::setw(10) << m_paths[name].summary_postmodules / (double) m_summary_events << " "
00400 << std::right << std::setw(10) << m_paths[name].summary_overhead / (double) m_summary_events << " "
00401 << std::right << std::setw(10) << m_paths[name].summary_total / (double) m_summary_events << " "
00402 << name << '\n';
00403 }
00404 out << '\n';
00405 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Pre- Inter- Post-mods Overhead Total EndPath" << '\n';
00406 for (auto const & name: tns.getEndPaths()) {
00407 out << "FastReport "
00408 << std::right << std::setw(10) << m_paths[name].summary_active / (double) m_summary_events << " "
00409 << std::right << std::setw(10) << m_paths[name].summary_premodules / (double) m_summary_events << " "
00410 << std::right << std::setw(10) << m_paths[name].summary_intermodules / (double) m_summary_events << " "
00411 << std::right << std::setw(10) << m_paths[name].summary_postmodules / (double) m_summary_events << " "
00412 << std::right << std::setw(10) << m_paths[name].summary_overhead / (double) m_summary_events << " "
00413 << std::right << std::setw(10) << m_paths[name].summary_total / (double) m_summary_events << " "
00414 << name << '\n';
00415 }
00416 }
00417 out << '\n';
00418 if (m_enable_timing_modules) {
00419 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
00420 for (auto & keyval: m_modules) {
00421 std::string const & label = keyval.first->moduleLabel();
00422 ModuleInfo const & module = keyval.second;
00423 out << "FastReport " << std::right << std::setw(10) << module.summary_active / (double) m_summary_events << " " << label << '\n';
00424 }
00425 out << "FastReport " << (m_timer_id == CLOCK_REALTIME ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
00426 }
00427 out << '\n';
00428 edm::LogVerbatim("FastReport") << out.str();
00429 }
00430
00431
00432 reset();
00433 }
00434
00435 void FastTimerService::reset() {
00436
00437 m_first_path = 0;
00438 m_last_path = 0;
00439 m_first_endpath = 0;
00440 m_last_endpath = 0;
00441 m_is_first_module = false;
00442
00443 m_event = 0.;
00444 m_source = 0.;
00445 m_all_paths = 0.;
00446 m_all_endpaths = 0.;
00447
00448 m_summary_events = 0;
00449 m_summary_event = 0.;
00450 m_summary_source = 0.;
00451 m_summary_all_paths = 0.;
00452 m_summary_all_endpaths = 0.;
00453
00454 m_dqms = 0;
00455
00456 m_dqm_event = 0;
00457 m_dqm_source = 0;
00458 m_dqm_all_paths = 0;
00459 m_dqm_all_endpaths = 0;
00460
00461 m_current_path = 0;
00462 m_paths.clear();
00463 m_modules.clear();
00464 m_cache_paths.clear();
00465 m_cache_modules.clear();
00466 }
00467
00468 void FastTimerService::preModuleBeginJob(edm::ModuleDescription const & module) {
00469
00470
00471
00472
00473 m_modules[& module];
00474 }
00475
00476 void FastTimerService::preProcessEvent(edm::EventID const & id, edm::Timestamp const & stamp) {
00477
00478
00479
00480 start(m_timer_event);
00481
00482
00483 m_event = 0;
00484 m_all_paths = 0;
00485 m_all_endpaths = 0;
00486 for (PathInfo * path: m_cache_paths) {
00487 path->time_active = 0.;
00488 path->time_premodules = 0.;
00489 path->time_intermodules = 0.;
00490 path->time_postmodules = 0.;
00491 path->time_total = 0.;
00492 }
00493 for (ModuleInfo * module: m_cache_modules) {
00494 module->time_active = 0.;
00495 module->has_just_run = false;
00496 module->is_exclusive = false;
00497 }
00498 }
00499
00500 void FastTimerService::postProcessEvent(edm::Event const & event, edm::EventSetup const & setup) {
00501
00502
00503 if (m_enable_timing_exclusive) {
00504 for (auto & keyval: m_paths) {
00505 PathInfo & pathinfo = keyval.second;
00506 float exclusive = pathinfo.time_overhead;
00507
00508 for (uint32_t i = 0; i <= pathinfo.last_run; ++i) {
00509 ModuleInfo * module = pathinfo.modules[i];
00510 if (module == 0)
00511
00512 continue;
00513 if (module->is_exclusive)
00514 exclusive += module->time_active;
00515 }
00516
00517 m_dqm_paths_exclusive_time->Fill(pathinfo.index, exclusive * 1000.);
00518 if (m_enable_dqm_bypath_exclusive) {
00519
00520 pathinfo.dqm_exclusive->Fill(exclusive * 1000.);
00521 }
00522 }
00523 }
00524
00525
00526 stop(m_timer_event);
00527 m_event = delta(m_timer_event);
00528 m_summary_event += m_event;
00529 if (m_dqms) {
00530
00531 m_dqm_event->Fill(m_event * 1000.);
00532
00533 if (m_enable_dqm_bylumi) {
00534 unsigned int lumi = event.getLuminosityBlock().luminosityBlock();
00535
00536 m_dqm_bylumi_event ->Fill(lumi, m_event * 1000.);
00537
00538 m_dqm_bylumi_source ->Fill(lumi, m_source * 1000.);
00539
00540 m_dqm_bylumi_all_paths ->Fill(lumi, m_all_paths * 1000.);
00541
00542 m_dqm_bylumi_all_endpaths ->Fill(lumi, m_all_endpaths * 1000.);
00543 }
00544 }
00545 }
00546
00547 void FastTimerService::preSource() {
00548
00549
00550 start(m_timer_source);
00551
00552
00553 m_source = 0;
00554
00555
00556 ++m_summary_events;
00557 }
00558
00559 void FastTimerService::postSource() {
00560
00561
00562 stop(m_timer_source);
00563 m_source = delta(m_timer_source);
00564 m_summary_source += m_source;
00565 if (m_dqms) {
00566
00567 m_dqm_source->Fill(m_source * 1000.);
00568 }
00569 }
00570
00571 void FastTimerService::prePathBeginRun(std::string const & path ) {
00572
00573
00574
00575 edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
00576 if (not m_skip_first_path and not tns.getTrigPaths().empty()) {
00577 if (path == tns.getTrigPaths().front())
00578 m_first_path = & path;
00579 if (path == tns.getTrigPaths().back())
00580 m_last_path = & path;
00581 }
00582 else if (m_skip_first_path and tns.getTrigPaths().size() > 1) {
00583 if (path == tns.getTrigPaths().at(1))
00584 m_first_path = & path;
00585 if (path == tns.getTrigPaths().back())
00586 m_last_path = & path;
00587 }
00588 if (not tns.getEndPaths().empty()) {
00589 if (path == tns.getEndPaths().front())
00590 m_first_endpath = & path;
00591 if (path == tns.getEndPaths().back())
00592 m_last_endpath = & path;
00593 }
00594 }
00595
00596 void FastTimerService::preProcessPath(std::string const & path ) {
00597
00598
00599
00600 m_is_first_module = true;
00601
00602 PathMap<PathInfo>::iterator keyval = m_paths.find(path);
00603 if (keyval != m_paths.end()) {
00604 m_current_path = & keyval->second;
00605
00606 if (m_enable_timing_modules) {
00607
00608 for (ModuleInfo * module: m_current_path->modules)
00609 if (module)
00610 module->has_just_run = false;
00611 }
00612 } else {
00613
00614 m_current_path = 0;
00615 edm::LogError("FastTimerService") << "FastTimerService::preProcessPath: unexpected path " << path;
00616 }
00617
00618
00619 start(m_timer_path);
00620
00621 if (& path == m_first_path) {
00622
00623 m_timer_paths.first = m_timer_path.first;
00624 } else if (& path == m_first_endpath) {
00625
00626 m_timer_endpaths.first = m_timer_path.first;
00627 }
00628 }
00629
00630 void FastTimerService::postProcessPath(std::string const & path, edm::HLTPathStatus const & status) {
00631
00632
00633
00634 stop(m_timer_path);
00635
00636 double active = delta(m_timer_path);
00637
00638
00639 if (m_enable_timing_paths) {
00640
00641 PathInfo & pathinfo = * m_current_path;
00642 pathinfo.time_active = active;
00643 pathinfo.summary_active += active;
00644
00645 if (m_dqms) {
00646
00647 m_dqm_paths_active_time->Fill(pathinfo.index, active * 1000.);
00648 if (m_enable_dqm_bypath_active) {
00649
00650 pathinfo.dqm_active->Fill(active * 1000.);
00651 }
00652 }
00653
00654
00655 if (m_enable_timing_modules) {
00656 double pre = 0.;
00657 double inter = 0.;
00658 double post = 0.;
00659 double overhead = 0.;
00660 double current = 0.;
00661 double total = active;
00662
00663
00664
00665
00666
00667
00668
00669 uint32_t last_run = status.index();
00670 for (uint32_t i = 0; i <= last_run; ++i) {
00671 ModuleInfo * module = pathinfo.modules[i];
00672
00673
00674 if (m_enable_dqm_bypath_counters) {
00675
00676 pathinfo.dqm_module_counter->Fill(i);
00677 }
00678
00679 if (module == 0)
00680
00681 continue;
00682
00683 if (module->has_just_run) {
00684 current += module->time_active;
00685 module->is_exclusive = true;
00686 } else {
00687 total += module->time_active;
00688 module->is_exclusive = false;
00689 }
00690
00691
00692 if (m_enable_dqm_bypath_details) {
00693
00694
00695 pathinfo.dqm_module_total->Fill(i, module->time_active * 1000.);
00696 if (module->has_just_run) {
00697
00698
00699 pathinfo.dqm_module_active->Fill(i, module->time_active * 1000.);
00700 }
00701 }
00702
00703 }
00704
00705 if (status.accept())
00706 if (m_enable_dqm_bypath_counters) {
00707
00708 pathinfo.dqm_module_counter->Fill(pathinfo.modules.size());
00709 }
00710
00711 if (m_is_first_module) {
00712
00713 pre = 0.;
00714 inter = 0.;
00715 post = active;
00716 overhead = active;
00717 } else {
00718
00719 pre = delta(m_timer_path.first, m_timer_first_module);
00720 post = delta(m_timer_module.second, m_timer_path.second);
00721 inter = active - pre - current - post;
00722
00723 if (std::abs(inter) < 1e-9)
00724 inter = 0.;
00725 overhead = active - current;
00726
00727 if (std::abs(overhead) < 1e-9)
00728 overhead = 0.;
00729 }
00730
00731 pathinfo.time_premodules = pre;
00732 pathinfo.time_intermodules = inter;
00733 pathinfo.time_postmodules = post;
00734 pathinfo.time_overhead = overhead;
00735 pathinfo.time_total = total;
00736 pathinfo.summary_premodules += pre;
00737 pathinfo.summary_intermodules += inter;
00738 pathinfo.summary_postmodules += post;
00739 pathinfo.summary_overhead += overhead;
00740 pathinfo.summary_total += total;
00741 pathinfo.last_run = last_run;
00742 if (m_dqms) {
00743 if (m_enable_dqm_bypath_overhead) {
00744
00745 pathinfo.dqm_premodules ->Fill(pre * 1000.);
00746 pathinfo.dqm_intermodules->Fill(inter * 1000.);
00747 pathinfo.dqm_postmodules ->Fill(post * 1000.);
00748 pathinfo.dqm_overhead ->Fill(overhead * 1000.);
00749 }
00750
00751 m_dqm_paths_total_time->Fill(pathinfo.index, total * 1000.);
00752 if (m_enable_dqm_bypath_total) {
00753
00754 pathinfo.dqm_total ->Fill(total * 1000.);
00755 }
00756 }
00757 }
00758 }
00759
00760 if (& path == m_last_path) {
00761
00762 m_timer_paths.second = m_timer_path.second;
00763 m_all_paths = delta(m_timer_paths);
00764 m_summary_all_paths += m_all_paths;
00765 if (m_dqms) {
00766
00767 m_dqm_all_paths->Fill(m_all_paths * 1000.);
00768 }
00769 } else if (& path == m_last_endpath) {
00770
00771 m_timer_endpaths.second = m_timer_path.second;
00772 m_all_endpaths = delta(m_timer_endpaths);
00773 m_summary_all_endpaths += m_all_endpaths;
00774 if (m_dqms) {
00775
00776 m_dqm_all_endpaths->Fill(m_all_endpaths * 1000.);
00777 }
00778 }
00779
00780 }
00781
00782 void FastTimerService::preModule(edm::ModuleDescription const & module) {
00783
00784
00785
00786 assert(m_enable_timing_modules);
00787
00788
00789 start(m_timer_module);
00790
00791 if (m_is_first_module) {
00792 m_is_first_module = false;
00793
00794
00795 m_timer_first_module = m_timer_module.first;
00796 }
00797 }
00798
00799 void FastTimerService::postModule(edm::ModuleDescription const & module) {
00800
00801
00802
00803 assert(m_enable_timing_modules);
00804
00805
00806 stop(m_timer_module);
00807
00808 ModuleMap<ModuleInfo>::iterator keyval = m_modules.find(& module);
00809 if (keyval != m_modules.end()) {
00810 double time = delta(m_timer_module);
00811 ModuleInfo & module = keyval->second;
00812 module.has_just_run = true;
00813 module.time_active = time;
00814 module.summary_active += time;
00815
00816 if (m_dqms and m_enable_dqm_bymodule) {
00817
00818 module.dqm_active->Fill(time * 1000.);
00819 }
00820 } else {
00821
00822 edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected module " << module.moduleLabel();
00823 }
00824 }
00825
00826
00827 edm::ModuleDescription const * FastTimerService::findModuleDescription(const std::string & label) const {
00828
00829 if (label.empty())
00830 return 0;
00831
00832
00833 std::string const & target = (label[0] == '!' or label[0] == '-') ? label.substr(1) : label;
00834
00835 for (auto const & keyval: m_modules) {
00836 if (keyval.first == 0) {
00837
00838 edm::LogError("FastTimerService") << "FastTimerService::findModuleDescription: invalid entry detected in ModuleMap<ModuleInfo> m_modules, skipping";
00839 continue;
00840 }
00841 if (keyval.first->moduleLabel() == target) {
00842 return keyval.first;
00843 }
00844 }
00845
00846 return 0;
00847 }
00848
00849
00850 void FastTimerService::fillPathMap(std::string const & name, std::vector<std::string> const & modules) {
00851 std::vector<ModuleInfo *> & pathmap = m_paths[name].modules;
00852 pathmap.reserve( modules.size() );
00853 std::tr1::unordered_set<edm::ModuleDescription const *> pool;
00854 for (auto const & module: modules) {
00855 edm::ModuleDescription const * md = findModuleDescription(module);
00856 if (md == 0) {
00857
00858 pathmap.push_back( 0 );
00859 } else if (pool.insert(md).second) {
00860
00861 pathmap.push_back( & m_modules[md] );
00862 } else {
00863
00864 pathmap.push_back( 0 );
00865 }
00866 }
00867 }
00868
00869
00870
00871
00872
00873
00874 double FastTimerService::currentModuleTime() const {
00875 struct timespec now;
00876 gettime(now);
00877 return delta(m_timer_module.first, now);
00878 }
00879
00880
00881 double FastTimerService::currentPathTime() const {
00882 struct timespec now;
00883 gettime(now);
00884 return delta(m_timer_path.first, now);
00885 }
00886
00887
00888 double FastTimerService::currentEventTime() const {
00889 struct timespec now;
00890 gettime(now);
00891 return delta(m_timer_event.first, now);
00892 }
00893
00894
00895 double FastTimerService::queryModuleTime(const edm::ModuleDescription & module) const {
00896 ModuleMap<ModuleInfo>::const_iterator keyval = m_modules.find(& module);
00897 if (keyval != m_modules.end()) {
00898 return keyval->second.time_active;
00899 } else {
00900 edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected module " << module.moduleLabel();
00901 return 0.;
00902 }
00903 }
00904
00905
00906 double FastTimerService::queryPathActiveTime(const std::string & path) const {
00907 PathMap<PathInfo>::const_iterator keyval = m_paths.find(path);
00908 if (keyval != m_paths.end()) {
00909 return keyval->second.time_active;
00910 } else {
00911 edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected path " << path;
00912 return 0.;
00913 }
00914 }
00915
00916
00917 double FastTimerService::queryPathTotalTime(const std::string & path) const {
00918 PathMap<PathInfo>::const_iterator keyval = m_paths.find(path);
00919 if (keyval != m_paths.end()) {
00920 return keyval->second.time_total;
00921 } else {
00922 edm::LogError("FastTimerService") << "FastTimerService::postModule: unexpected path " << path;
00923 return 0.;
00924 }
00925 }
00926
00927
00928 double FastTimerService::querySourceTime() const {
00929 return m_source;
00930 }
00931
00932
00933 double FastTimerService::queryPathsTime() const {
00934 return m_all_paths;
00935 }
00936
00937
00938 double FastTimerService::queryEndPathsTime() const {
00939 return m_all_endpaths;
00940 }
00941
00942
00943 double FastTimerService::queryEventTime() const {
00944 return m_event;
00945 }
00946
00947
00948 void FastTimerService::fillDescriptions(edm::ConfigurationDescriptions & descriptions) {
00949 edm::ParameterSetDescription desc;
00950 desc.addUntracked<bool>( "useRealTimeClock", true);
00951 desc.addUntracked<bool>( "enableTimingPaths", true);
00952 desc.addUntracked<bool>( "enableTimingModules", true);
00953 desc.addUntracked<bool>( "enableTimingExclusive", false);
00954 desc.addUntracked<bool>( "enableTimingSummary", false);
00955 desc.addUntracked<bool>( "skipFirstPath", false),
00956 desc.addUntracked<bool>( "enableDQM", true);
00957 desc.addUntracked<bool>( "enableDQMbyPathActive", false);
00958 desc.addUntracked<bool>( "enableDQMbyPathTotal", true);
00959 desc.addUntracked<bool>( "enableDQMbyPathOverhead", false);
00960 desc.addUntracked<bool>( "enableDQMbyPathDetails", false);
00961 desc.addUntracked<bool>( "enableDQMbyPathCounters", true);
00962 desc.addUntracked<bool>( "enableDQMbyPathExclusive", false);
00963 desc.addUntracked<bool>( "enableDQMbyModule", false);
00964 desc.addUntracked<bool>( "enableDQMbyLumi", false);
00965 desc.addUntracked<double>( "dqmTimeRange", 1000. );
00966 desc.addUntracked<double>( "dqmTimeResolution", 5. );
00967 desc.addUntracked<double>( "dqmPathTimeRange", 100. );
00968 desc.addUntracked<double>( "dqmPathTimeResolution", 0.5);
00969 desc.addUntracked<double>( "dqmModuleTimeRange", 40. );
00970 desc.addUntracked<double>( "dqmModuleTimeResolution", 0.2);
00971 desc.addUntracked<uint32_t>( "dqmLumiSectionsRange", 2500 );
00972 desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
00973 descriptions.add("FastTimerService", desc);
00974 }