Belle II Software  release-06-00-14
StatisticsTimingHLTDQMModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <hlt/softwaretrigger/modules/dqm/StatisticsTimingHLTDQMModule.h>
9 #include <hlt/softwaretrigger/modules/dqm/SoftwareTriggerHLTDQMModule.h>
10 
11 #include <framework/datastore/StoreObjPtr.h>
12 #include <framework/core/ProcessStatistics.h>
13 #include <framework/core/ModuleStatistics.h>
14 #include <framework/gearbox/Unit.h>
15 
16 #include <TDirectory.h>
17 
18 #include <TH1F.h>
19 
20 #include <fstream>
21 
22 using namespace Belle2;
23 using namespace SoftwareTrigger;
24 
25 REG_MODULE(StatisticsTimingHLTDQM)
26 
28 {
29  setDescription("Monitor reconstruction runtime on HLT");
30  setPropertyFlags(c_ParallelProcessingCertified);
31 
32  addParam("histogramDirectoryName", m_param_histogramDirectoryName,
33  "Runtime DQM histograms on HLT will be put into this directory", m_param_histogramDirectoryName);
34 
35  addParam("m_param_overviewModuleList", m_param_overviewModuleList,
36  "Which modules should be shown in the overview mean list", m_param_overviewModuleList);
37 
38  addParam("createHLTUnitHistograms", m_param_create_hlt_unit_histograms,
39  "Create HLT unit histograms?",
40  false);
41 }
42 
44 {
45  // Create a separate histogram directory and cd into it.
46  TDirectory* oldDirectory = nullptr;
47 
48  if (!m_param_histogramDirectoryName.empty()) {
49  oldDirectory = gDirectory;
50  TDirectory* histDir = oldDirectory->mkdir(m_param_histogramDirectoryName.c_str());
51  histDir->cd();
52  }
53 
54  m_meanTimeHistogram = new TH1F("meanTimeHistogram", "Mean Processing Time [ms]", m_param_overviewModuleList.size(), 0,
56  m_meanTimeHistogram->SetStats(false);
57  m_meanMemoryHistogram = new TH1F("meanMemoryHistogram", "Mean Memory Change [MB]", m_param_overviewModuleList.size(), 0,
59  m_meanMemoryHistogram->SetStats(false);
60  m_fullTimeHistogram = new TH1F("fullTimeHistogram", "Budget Time [ms]", m_fullTimeNBins, 0, m_fullTimeMax);
61  m_fullTimeHistogram->StatOverflows(true);
62  m_processingTimeHistogram = new TH1F("processingTimeHistogram", "Processing Time [ms]", m_processingTimeNBins, 0,
64  m_processingTimeHistogram->StatOverflows(true);
65  m_fullMemoryHistogram = new TH1F("fullMemoryHistogram", "Total memory used [MB]", m_fullMemoryNBins, 0,
67  m_fullMemoryHistogram->StatOverflows(true);
68 
69  for (unsigned int index = 0; index < m_param_overviewModuleList.size(); index++) {
70  const std::string& moduleName = m_param_overviewModuleList[index];
71  m_meanTimeHistogram->GetXaxis()->SetBinLabel(index + 1, moduleName.c_str());
72  m_meanMemoryHistogram->GetXaxis()->SetBinLabel(index + 1, moduleName.c_str());
73  m_moduleTimeHistograms.emplace(moduleName, new TH1F((moduleName + "_time").c_str(),
74  ("Time spent in: " + moduleName + " [ms]").c_str(), m_processingTimeNBins, 0, m_processingTimeMax));
75  m_moduleTimeHistograms[moduleName]->StatOverflows(true);
76  m_lastModuleTimeSum.emplace(moduleName, 0);
77  m_moduleMemoryHistograms.emplace(moduleName, new TH1F((moduleName + "_memory").c_str(),
78  ("Memory used in: " + moduleName + " [MB]").c_str(), m_fullMemoryNBins, 0, m_fullMemoryMax));
79  m_moduleMemoryHistograms[moduleName]->StatOverflows(true);
80  }
81 
83  m_fullTimeMeanPerUnitHistogram = new TH1F("fullTimeMeanPerUnitHistogram", "Mean Budget Time Per Unit [ms]",
86  m_fullTimeMeanPerUnitHistogram->SetStats(false);
87  m_fullTimeMeanPerUnitHistogram->SetXTitle("HLT unit number");
88  m_processingTimeMeanPerUnitHistogram = new TH1F("processingTimeMeanPerUnitHistogram", "Mean Processing Time Per Unit [ms]",
91  m_processingTimeMeanPerUnitHistogram->SetStats(false);
92  m_processingTimeMeanPerUnitHistogram->SetXTitle("HLT unit number");
93 
94  for (unsigned int index = 1; index <= HLTUnit::max_hlt_units; index++) {
95  m_fullTimePerUnitHistograms.emplace(index, new TH1F(("fullTimePerUnitHistogram_HLT" + std::to_string(index)).c_str(),
96  ("Budget Time Per Unit: HLT" + std::to_string(index) + " [ms]").c_str(), m_fullTimeNBins, 0, m_fullTimeMax));
97  m_fullTimePerUnitHistograms[index]->StatOverflows(true);
98  m_lastFullTimeSumPerUnit.emplace(index, 0);
99  m_processingTimePerUnitHistograms.emplace(index, new TH1F(("processingTimePerUnitHistogram_HLT" + std::to_string(index)).c_str(),
100  ("Processing Time Per Unit: HLT" + std::to_string(index) + " [ms]").c_str(), m_processingTimeNBins, 0, m_processingTimeMax));
101  m_processingTimePerUnitHistograms[index]->StatOverflows(true);
102  m_lastProcessingTimeSumPerUnit.emplace(index, 0);
103  m_fullMemoryPerUnitHistograms.emplace(index, new TH1F(("fullMemoryPerUnitHistogram_HLT" + std::to_string(index)).c_str(),
104  ("Total Memory Used Per Unit: HLT" + std::to_string(index) + " [MB]").c_str(), m_fullMemoryNBins, 0, m_fullMemoryMax));
105  m_fullMemoryPerUnitHistograms[index]->StatOverflows(true);
106  }
107 
108  m_processesPerUnitHistogram = new TH1F("processesPerUnitHistogram", "Number of Processes Per Unit",
109  HLTUnit::max_hlt_units + 1, 0,
111  m_processesPerUnitHistogram->SetXTitle("HLT unit number");
112  }
113 
114  if (oldDirectory) {
115  oldDirectory->cd();
116  }
117 }
118 
119 
121 {
122  // Register histograms (calls back defineHisto)
123  REG_HISTOGRAM
124 
126  std::ifstream file;
127  file.open(HLTUnit::hlt_unit_file);
128  if (file.good()) {
129  std::string host;
130  getline(file, host);
131  m_hlt_unit = atoi(host.substr(3, 2).c_str());
132  file.close();
133  } else {
134  B2WARNING("HLT unit number not found");
135  }
136  }
137 }
138 
140 {
142 
143  if (not stats.isValid()) {
144  return;
145  }
146 
147  const std::vector<ModuleStatistics>& moduleStatisticsList = stats->getAll();
148 
149  std::vector<double> meanTimes(m_param_overviewModuleList.size(), 0);
150  std::vector<double> meanMemories(m_param_overviewModuleList.size(), 0);
151 
152  for (const ModuleStatistics& moduleStatistics : moduleStatisticsList) {
153  const std::string& statisticsName = moduleStatistics.getName();
154  const auto m_param_overviewModuleListIterator = std::find(m_param_overviewModuleList.begin(), m_param_overviewModuleList.end(),
155  statisticsName);
156  if (m_param_overviewModuleListIterator == m_param_overviewModuleList.end()) {
157  continue;
158  }
159 
160  const double statisticsTime = moduleStatistics.getTimeMean(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
161  const double statisticsMemory = moduleStatistics.getMemoryMean(ModuleStatistics::EStatisticCounters::c_Total) / 1024;
162  const double statisticsTime_sum = moduleStatistics.getTimeSum(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
163  const double statisticsMemory_sum = moduleStatistics.getMemorySum(ModuleStatistics::EStatisticCounters::c_Total) / 1024;
164 
165  const int m_param_overviewModuleListIndex = std::distance(m_param_overviewModuleList.begin(), m_param_overviewModuleListIterator);
166  meanTimes[m_param_overviewModuleListIndex] += statisticsTime;
167  meanMemories[m_param_overviewModuleListIndex] += statisticsMemory;
168 
169  m_moduleTimeHistograms[statisticsName]->Fill(statisticsTime_sum - m_lastModuleTimeSum[statisticsName]);
170  m_lastModuleTimeSum[statisticsName] = statisticsTime_sum;
171  m_moduleMemoryHistograms[statisticsName]->Fill(statisticsMemory_sum);
172  }
173 
174  for (unsigned int index = 0; index < m_param_overviewModuleList.size(); index++) {
175  m_meanTimeHistogram->SetBinContent(index + 1, meanTimes[index]);
176  m_meanMemoryHistogram->SetBinContent(index + 1, meanMemories[index]);
177  }
178 
179  double processingTimeSum = 0.0;
180  double processingTimeMean = 0.0;
181 
182  for (const ModuleStatistics& moduleStatistics : moduleStatisticsList) {
183  const std::string& statisticsName = moduleStatistics.getName();
184  const auto m_summaryModuleListIterator = std::find(m_summaryModuleList.begin(), m_summaryModuleList.end(),
185  statisticsName);
186  if (m_summaryModuleListIterator == m_summaryModuleList.end()) {
187  continue;
188  }
189  processingTimeSum += moduleStatistics.getTimeSum(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
190  processingTimeMean += moduleStatistics.getTimeMean(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
191  }
192  m_processingTimeHistogram->Fill(processingTimeSum - m_lastProcessingTimeSum);
193  m_lastProcessingTimeSum = processingTimeSum;
194 
195  const ModuleStatistics& fullStatistics = stats->getGlobal();
196  const double fullTimeSum = fullStatistics.getTimeSum(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
197  m_fullTimeHistogram->Fill(fullTimeSum - m_lastFullTimeSum);
198  m_lastFullTimeSum = fullTimeSum;
199  const double fullMemorySum = fullStatistics.getMemorySum(ModuleStatistics::EStatisticCounters::c_Total) / 1024;
200  m_fullMemoryHistogram->Fill(fullMemorySum);
201 
203  if (0 < m_hlt_unit) {
204  m_processingTimeMeanPerUnitHistogram->SetBinContent(m_hlt_unit + 1, processingTimeMean);
205 
207  m_lastProcessingTimeSumPerUnit[m_hlt_unit] = processingTimeSum;
208 
209  const double fullTimeMean = fullStatistics.getTimeMean(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
210  m_fullTimeMeanPerUnitHistogram->SetBinContent(m_hlt_unit + 1, fullTimeMean);
211 
213  m_lastFullTimeSumPerUnit[m_hlt_unit] = fullTimeSum;
214 
215  m_fullMemoryPerUnitHistograms[m_hlt_unit]->Fill(fullMemorySum);
216  }
217  }
218 }
219 
221 {
223  B2FATAL("Histograms were not created. Did you setup a HistoManager?");
224  }
225 
226  m_meanTimeHistogram->Reset();
227  m_meanMemoryHistogram->Reset();
228  std::for_each(m_moduleTimeHistograms.begin(), m_moduleTimeHistograms.end(),
229  [](auto & it) { it.second->Reset(); });
230  std::for_each(m_moduleMemoryHistograms.begin(), m_moduleMemoryHistograms.end(),
231  [](auto & it) { it.second->Reset(); });
232  m_fullTimeHistogram->Reset();
233  m_processingTimeHistogram->Reset();
234  m_fullMemoryHistogram->Reset();
238  std::for_each(m_fullTimePerUnitHistograms.begin(), m_fullTimePerUnitHistograms.end(),
239  [](auto & it) { it.second->Reset(); });
241  [](auto & it) { it.second->Reset(); });
243  [](auto & it) { it.second->Reset(); });
245 
247  }
248 }
249 
@ c_Persistent
Object is available during entire execution time.
Definition: DataStore.h:60
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
Keep track of time and memory consumption during processing.
value_type getMemorySum(EStatisticCounters type=c_Total) const
return the total used memory for a given counter
value_type getTimeSum(EStatisticCounters type=c_Total) const
return the sum of all execution times for a given counter
value_type getTimeMean(EStatisticCounters type=c_Total) const
return the mean execution time for a given counter
std::map< std::string, TH1F * > m_moduleTimeHistograms
Time distribution of certain modules.
TH1F * m_fullMemoryHistogram
Total memory usage distribution of all events.
const double m_processingTimeNBins
Number of bins for the histograms of processingTime.
std::map< unsigned int, double > m_lastProcessingTimeSumPerUnit
Storage for the last processing time sum per unit.
int m_hlt_unit
Store HLT unit number on initialization.
const double m_processingTimeMax
Maximum for the histograms of processingTime.
std::map< unsigned int, TH1F * > m_processingTimePerUnitHistograms
Processing time distribution of events per unit.
double m_lastProcessingTimeSum
Storage for the last processing time sum.
const double m_fullMemoryMax
Maximum for the histograms of fullMemory.
std::vector< std::string > m_param_overviewModuleList
Parameter: which modules should be shown in the overview list.
TH1F * m_fullTimeMeanPerUnitHistogram
Mean budget time of events per unit.
const double m_fullTimeNBins
Number of bins for the histograms of fullTime.
TH1F * m_processingTimeHistogram
Processing time distribution of all events.
std::map< std::string, double > m_lastModuleTimeSum
Storage for the last time sum of certain modules.
TH1F * m_processingTimeMeanPerUnitHistogram
Mean processing time of events per unit.
bool m_param_create_hlt_unit_histograms
Parameter: Create HLT unit number histograms?
std::map< unsigned int, double > m_lastFullTimeSumPerUnit
Storage for the last full time sum per unit.
double m_lastFullTimeSum
Storage for the last full time sum.
std::map< unsigned int, TH1F * > m_fullTimePerUnitHistograms
Budget time distribution of events per unit.
const double m_fullTimeMax
Maximum for the histograms of fullTime.
std::string m_param_histogramDirectoryName
Parameter: Directory to put the generated histograms.
std::vector< std::string > m_summaryModuleList
Summary modules of the actual processing.
std::map< std::string, TH1F * > m_moduleMemoryHistograms
Memory distribution of certain modules.
const double m_fullMemoryNBins
Number of bins for the histograms of fullMemory.
TH1F * m_fullTimeHistogram
Budget time distribution of all events.
std::map< unsigned int, TH1F * > m_fullMemoryPerUnitHistograms
Total memory distribution of events per unit.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
static const double ms
[millisecond]
Definition: Unit.h:96
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
static constexpr char hlt_unit_file[]
Location of HLT unit number information.
static constexpr unsigned int max_hlt_units
Maximum number of HLT units used during the experiment.
Abstract base class for different kinds of events.