diff --git a/HLTrigger/Timer/interface/FastTimerService.h b/HLTrigger/Timer/interface/FastTimerService.h index 6e67266ac1279..cbd18929caa5b 100644 --- a/HLTrigger/Timer/interface/FastTimerService.h +++ b/HLTrigger/Timer/interface/FastTimerService.h @@ -365,7 +365,7 @@ class FastTimerService { struct ProcessDescription { std::string name; std::string first_path; // the framework does not provide a pre/postPaths or pre/postEndPaths signal, - std::string last_path; // so we emulate them keeping track of the first and last Path and EndPath + std::string last_path; // so we emulate them keeping track of the first and last non-empty Path and EndPath std::string first_endpath; std::string last_endpath; edm::ParameterSetID pset; @@ -759,6 +759,9 @@ class FastTimerService { // associate to a path all the modules it contains void fillPathMap(unsigned int pid, std::string const & name, std::vector const & modules); + // find the first and last non-empty paths, optionally skipping the first one + std::pair findFirstLast(unsigned int pid, std::vector const & paths, bool skip = false); + // print a timing summary for the run or job void printSummary(Timing const & summary, std::string const & label) const; void printProcessSummary(Timing const & total, TimingPerProcess const & summary, std::string const & label, std::string const & process) const; diff --git a/HLTrigger/Timer/src/FastTimerService.cc b/HLTrigger/Timer/src/FastTimerService.cc index e6f89222e5d54..2a6119232329b 100644 --- a/HLTrigger/Timer/src/FastTimerService.cc +++ b/HLTrigger/Timer/src/FastTimerService.cc @@ -183,27 +183,6 @@ void FastTimerService::preGlobalBeginRun(edm::GlobalContext const & gc) edm::service::TriggerNamesService & tns = * edm::Service(); - // cache the names of the first and last path and endpath - if (m_process.size() <= pid) - m_process.resize(pid+1); - m_process[pid].name = gc.processContext()->processName(); - if (m_skip_first_path and pid == 0) { - // skip the first path - if (tns.getTrigPaths().size() > 1) { - m_process[pid].first_path = tns.getTrigPaths().at(1); - m_process[pid].last_path = tns.getTrigPaths().back(); - } - } else { - if (not tns.getTrigPaths().empty()) { - m_process[pid].first_path = tns.getTrigPaths().front(); - m_process[pid].last_path = tns.getTrigPaths().back(); - } - } - if (not tns.getEndPaths().empty()) { - m_process[pid].first_endpath = tns.getEndPaths().front(); - m_process[pid].last_endpath = tns.getEndPaths().back(); - } - uint32_t size_p = tns.getTrigPaths().size(); uint32_t size_e = tns.getEndPaths().size(); uint32_t size = size_p + size_e; @@ -253,6 +232,13 @@ void FastTimerService::preGlobalBeginRun(edm::GlobalContext const & gc) fillPathMap( pid, tns.getTrigPath(i), tns.getTrigPathModules(i) ); for (uint32_t i = 0; i < tns.getEndPaths().size(); ++i) fillPathMap( pid, tns.getEndPath(i), tns.getEndPathModules(i) ); + + // cache the names of the process, and of first and last non-empty path and endpath + if (m_process.size() <= pid) + m_process.resize(pid+1); + m_process[pid].name = gc.processContext()->processName(); + std::tie(m_process[pid].first_path, m_process[pid].last_path) = findFirstLast(pid, tns.getTrigPaths(), m_skip_first_path and pid == 0); + std::tie(m_process[pid].first_endpath, m_process[pid].last_endpath) = findFirstLast(pid, tns.getEndPaths()); } void FastTimerService::preStreamBeginRun(edm::StreamContext const & sc) @@ -1285,6 +1271,29 @@ void FastTimerService::fillPathMap(unsigned int pid, std::string const & name, s } } +// find the first and last non-empty paths, optionally skipping the first one +std::pair FastTimerService::findFirstLast(unsigned int pid, std::vector const & paths, bool skip) { + std::vector p(paths.size(), nullptr); + + // mark the empty paths + auto address_if_non_empty = [&](std::string const & name){ + return m_stream.front().paths[pid][name].modules.empty() ? nullptr : & name; + }; + std::transform(paths.begin(), paths.end(), p.begin(), address_if_non_empty); + + // optionally, skip the first path + if (skip and not p.empty()) + p.erase(p.begin()); + + // remove the empty paths + p.erase(std::remove(p.begin(), p.end(), nullptr), p.end()); + + // return the first and last non-empty paths, if there are any + if (not p.empty()) + return std::make_pair(* p.front(), * p.back()); + else + return std::make_pair(std::string(), std::string()); +} // query the current module/path/event // Note: these functions incur in a "per-call timer overhead" (see above), currently of the order of 340ns