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