CMS 3D CMS Logo

SystemTimeKeeper.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWCore/Framework
4 // Class : SystemTimeKeeper
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones
10 // Created: Mon, 07 Jul 2014 14:37:32 GMT
11 //
12 
13 // system include files
14 #include <algorithm>
15 
16 // user include files
28 
29 using namespace edm;
30 
31 namespace {
32  bool lessModuleDescription(const ModuleDescription* iLHS, const ModuleDescription* iRHS) {
33  return iLHS->id() < iRHS->id();
34  }
35 } // namespace
36 //
37 // constants, enums and typedefs
38 //
39 
40 //
41 // static data member definitions
42 //
43 
44 //
45 // constructors and destructor
46 //
47 SystemTimeKeeper::SystemTimeKeeper(unsigned int iNumStreams,
48  std::vector<const ModuleDescription*> const& iModules,
49  service::TriggerNamesService const& iNamesService,
50  ProcessContext const* iProcessContext)
51  : m_streamEventTimer(iNumStreams),
52  m_streamPathTiming(iNumStreams),
53  m_modules(iModules),
54  m_processContext(iProcessContext),
55  m_minModuleID(0),
56  m_numberOfEvents(0) {
57  std::sort(m_modules.begin(), m_modules.end(), lessModuleDescription);
58  if (not m_modules.empty()) {
59  m_minModuleID = m_modules.front()->id();
60  unsigned int numModuleSlots = m_modules.back()->id() - m_minModuleID + 1;
61  m_streamModuleTiming.resize(iNumStreams);
62  for (auto& stream : m_streamModuleTiming) {
63  stream.resize(numModuleSlots);
64  }
65  }
66 
67  std::vector<unsigned int> numModulesInPath;
68  std::vector<unsigned int> numModulesInEndPath;
69 
70  const unsigned int numPaths = iNamesService.getTrigPaths().size();
71  const unsigned int numEndPaths = iNamesService.getEndPaths().size();
72  m_pathNames.reserve(numPaths + numEndPaths);
73  std::copy(iNamesService.getTrigPaths().begin(), iNamesService.getTrigPaths().end(), std::back_inserter(m_pathNames));
74  std::copy(iNamesService.getEndPaths().begin(), iNamesService.getEndPaths().end(), std::back_inserter(m_pathNames));
75 
76  numModulesInPath.reserve(numPaths);
77  numModulesInEndPath.reserve(numEndPaths);
78 
79  m_modulesOnPaths.reserve(numPaths + numEndPaths);
80 
81  for (unsigned int i = 0; i < numPaths; ++i) {
82  numModulesInPath.push_back(iNamesService.getTrigPathModules(i).size());
83  m_modulesOnPaths.push_back(iNamesService.getTrigPathModules(i));
84  }
85  for (unsigned int i = 0; i < numEndPaths; ++i) {
86  numModulesInEndPath.push_back(iNamesService.getEndPathModules(i).size());
87  m_modulesOnPaths.push_back(iNamesService.getEndPathModules(i));
88  }
89 
90  m_endPathOffset = numModulesInPath.size();
91 
92  for (auto& stream : m_streamPathTiming) {
93  unsigned int index = 0;
94  stream.resize(numModulesInPath.size() + numModulesInEndPath.size());
95  for (unsigned int numMods : numModulesInPath) {
96  stream[index].m_moduleTiming.resize(numMods);
97  ++index;
98  }
99  for (unsigned int numMods : numModulesInEndPath) {
100  stream[index].m_moduleTiming.resize(numMods);
101  ++index;
102  }
103  }
104 }
105 
106 //
107 // member functions
108 //
110  // The deletion of a module is signaled to all (Sub)Processes, even
111  // though the module exists in only one of them.
112  auto found = std::lower_bound(m_modules.begin(), m_modules.end(), &module, lessModuleDescription);
113  if (*found == &module) {
114  m_modules.erase(found);
115  }
116 }
117 
119  unsigned int offset = 0;
120  if (iPath.isEndPath()) {
122  }
123  assert(iPath.pathID() + offset < m_streamPathTiming[iStream.streamID().value()].size());
124  return m_streamPathTiming[iStream.streamID().value()][iPath.pathID() + offset];
125 }
126 
127 //NOTE: Have to check bounds rather than ProcessContext on the
128 // module callbacks because the ProcessContext could be for a
129 // SubProcess which requested an usncheduled execution of a
130 // module in a parent process. In that case the ProcessContext
131 // is for the SubProcess but the module is is for the parent process.
132 inline bool SystemTimeKeeper::checkBounds(unsigned int id) const {
133  return id >= m_minModuleID and id < m_streamModuleTiming.front().size() + m_minModuleID;
134 }
135 
138  m_streamEventTimer[iID.value()].start();
139 }
140 
142  m_streamEventTimer[iContext.streamID().value()].stop();
143 }
144 
145 void SystemTimeKeeper::startPath(StreamContext const& iStream, PathContext const& iPath) {
146  if (m_processContext == iStream.processContext()) {
147  auto& timing = pathTiming(iStream, iPath);
148  timing.m_timer.start();
149  }
150 }
151 
152 void SystemTimeKeeper::stopPath(StreamContext const& iStream, PathContext const& iPath, HLTPathStatus const& iStatus) {
153  if (m_processContext == iStream.processContext()) {
154  auto& timing = pathTiming(iStream, iPath);
155  timing.m_timer.stop();
156 
157  //mark all modules up to and including the decision module as being visited
158  auto& modsOnPath = timing.m_moduleTiming;
159  for (unsigned int i = 0; i < iStatus.index() + 1; ++i) {
160  ++modsOnPath[i].m_timesVisited;
161  }
162  }
163 }
164 
166  if (checkBounds(iModule.moduleDescription()->id())) {
167  auto& mod = m_streamModuleTiming[iStream.streamID().value()][iModule.moduleDescription()->id() - m_minModuleID];
168  mod.m_timer.start();
169  ++(mod.m_timesRun);
170  }
171 }
173  if (checkBounds(iModule.moduleDescription()->id())) {
174  auto& mod = m_streamModuleTiming[iStream.streamID().value()][iModule.moduleDescription()->id() - m_minModuleID];
175  auto times = mod.m_timer.stop();
176 
177  if (iModule.type() == ParentContext::Type::kPlaceInPath) {
178  auto place = iModule.placeInPathContext();
179 
180  auto& modTiming = pathTiming(iStream, *(place->pathContext())).m_moduleTiming[place->placeInPath()];
181  modTiming.m_realTime += times;
182  }
183  }
184 }
186  if (checkBounds(iModule.moduleDescription()->id())) {
187  auto& mod = m_streamModuleTiming[iStream.streamID().value()][iModule.moduleDescription()->id() - m_minModuleID];
188  auto times = mod.m_timer.stop();
189 
190  if (iModule.type() == ParentContext::Type::kPlaceInPath) {
191  auto place = iModule.placeInPathContext();
192 
193  auto& modTiming = pathTiming(iStream, *(place->pathContext())).m_moduleTiming[place->placeInPath()];
194  modTiming.m_realTime += times;
195  }
196  }
197 }
199  if (checkBounds(iModule.moduleDescription()->id())) {
200  auto& mod = m_streamModuleTiming[iStream.streamID().value()][iModule.moduleDescription()->id() - m_minModuleID];
201  mod.m_timer.start();
202  }
203 }
204 
208 }
209 
213 }
214 
215 static void fillPathSummary(unsigned int iStartIndex,
216  unsigned int iEndIndex,
217  std::vector<std::string> const& iPathNames,
218  std::vector<std::vector<std::string>> const& iModulesOnPaths,
219  std::vector<std::vector<SystemTimeKeeper::PathTiming>> const& iPathTimings,
220  std::vector<PathTimingSummary>& iSummary) {
221  iSummary.resize(iEndIndex - iStartIndex);
222 
223  for (auto const& stream : iPathTimings) {
224  auto it = iSummary.begin();
225  for (unsigned int index = iStartIndex; index < iEndIndex; ++index, ++it) {
226  auto const& pathTiming = stream[index];
227  it->name = iPathNames[index];
228  it->bitPosition = index - iStartIndex;
229  if (not pathTiming.m_moduleTiming.empty()) {
230  it->timesRun += pathTiming.m_moduleTiming[0].m_timesVisited;
231  }
232  it->realTime += pathTiming.m_timer.realTime();
233  if (it->moduleInPathSummaries.empty()) {
234  it->moduleInPathSummaries.resize(pathTiming.m_moduleTiming.size());
235  }
236  for (unsigned int modIndex = 0; modIndex < pathTiming.m_moduleTiming.size(); ++modIndex) {
237  auto const& modTiming = pathTiming.m_moduleTiming[modIndex];
238  auto& modSummary = it->moduleInPathSummaries[modIndex];
239  if (modSummary.moduleLabel.empty()) {
240  modSummary.moduleLabel = iModulesOnPaths[index][modIndex];
241  }
242  modSummary.timesVisited += modTiming.m_timesVisited;
243  modSummary.realTime += modTiming.m_realTime;
244  }
245  }
246  }
247 }
248 
250  {
251  rep.eventSummary.totalEvents = m_numberOfEvents;
252  double sumEventTime = 0.;
253  for (auto const& stream : m_streamEventTimer) {
254  sumEventTime += stream.realTime();
255  }
256  rep.eventSummary.realTime = m_processingLoopTimer.realTime();
258  rep.eventSummary.sumStreamRealTime = sumEventTime;
259  }
260 
261  //Per module summary
262  {
263  auto& summary = rep.workerSummaries;
264  summary.resize(m_modules.size());
265  //Figure out how often a module was visited
266  std::map<std::string, unsigned int> visited;
267  for (auto const& stream : m_streamPathTiming) {
268  unsigned int pathIndex = 0;
269  for (auto const& path : stream) {
270  unsigned int modIndex = 0;
271  for (auto const& mod : path.m_moduleTiming) {
272  visited[m_modulesOnPaths[pathIndex][modIndex]] += mod.m_timesVisited;
273  ++modIndex;
274  }
275  ++pathIndex;
276  }
277  }
278 
279  unsigned int modIndex = 0;
280  for (auto const& mod : m_modules) {
281  auto& outMod = summary[modIndex];
282  outMod.moduleLabel = mod->moduleLabel();
283  outMod.realTime = 0.;
284 
285  auto moduleId = mod->id() - m_minModuleID;
286  for (auto const& stream : m_streamModuleTiming) {
287  auto const& timing = stream[moduleId];
288  outMod.realTime += timing.m_timer.realTime();
289  outMod.timesRun += timing.m_timesRun;
290  }
291  outMod.timesVisited = visited[mod->moduleLabel()];
292  if (0 == outMod.timesVisited) {
293  outMod.timesVisited = outMod.timesRun;
294  }
295  ++modIndex;
296  }
297  }
298  sort_all(rep.workerSummaries);
299 
300  //Per path summary
301  {
305  m_pathNames,
308  rep.endPathSummaries);
309  }
310 }
311 
312 //
313 // const member functions
314 //
315 
316 //
317 // static member functions
318 //
size
Write out results.
std::vector< std::vector< std::string > > m_modulesOnPaths
ModuleDescription const * moduleDescription() const
ChildrenCPUTimer m_processingLoopChildrenTimer
void stopEvent(StreamContext const &)
std::atomic< unsigned int > m_numberOfEvents
void start()
Definition: CPUTimer.cc:68
void restartModuleEvent(StreamContext const &, ModuleCallingContext const &)
void startModuleEvent(StreamContext const &, ModuleCallingContext const &)
SystemTimeKeeper(unsigned int iNumStreams, std::vector< const ModuleDescription *> const &iModules, service::TriggerNamesService const &iNameService, ProcessContext const *iProcessContext)
void removeModuleIfExists(ModuleDescription const &module)
unsigned int index() const
Definition: HLTPathStatus.h:52
std::vector< ModuleInPathTiming > m_moduleTiming
std::vector< std::vector< ModuleTiming > > m_streamModuleTiming
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
double cpuTime() const
Definition: CPUTimer.cc:146
assert(be >=bs)
std::vector< std::string > m_pathNames
Strings const & getTrigPathModules(std::string const &name) const
PlaceInPathContext const * placeInPathContext() const
unsigned int id() const
std::vector< const ModuleDescription * > m_modules
Strings const & getTrigPaths() const
StreamID const & streamID() const
Definition: StreamContext.h:54
ProcessContext const * m_processContext
static void fillPathSummary(Path const &path, PathSummary &sum)
Strings const & getEndPathModules(std::string const &name) const
ProcessContext const * processContext() const
Definition: StreamContext.h:63
Times stop()
Definition: CPUTimer.cc:87
rep
Definition: cuy.py:1189
void stopPath(StreamContext const &, PathContext const &, HLTPathStatus const &)
void stopModuleEvent(StreamContext const &, ModuleCallingContext const &)
unsigned int pathID() const
Definition: PathContext.h:32
Strings const & getEndPaths() const
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:92
void startPath(StreamContext const &, PathContext const &)
double realTime() const
Definition: CPUTimer.cc:139
void fillTriggerTimingReport(TriggerTimingReport &rep) const
void pauseModuleEvent(StreamContext const &, ModuleCallingContext const &)
HLT enums.
std::vector< WallclockTimer > m_streamEventTimer
uint16_t *__restrict__ uint16_t const *__restrict__ uint32_t const *__restrict__ uint32_t *__restrict__ uint32_t const *__restrict__ moduleId
PathTiming & pathTiming(StreamContext const &, PathContext const &)
unsigned int m_endPathOffset
unsigned int value() const
Definition: StreamID.h:43
bool isEndPath() const
Definition: PathContext.h:35
bool checkBounds(unsigned int id) const
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
std::vector< std::vector< PathTiming > > m_streamPathTiming