Belle II Software  release-08-02-06
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 
9 #include <hlt/softwaretrigger/modules/dqm/StatisticsTimingHLTDQMModule.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 #include <hlt/utilities/Units.h>
16 
17 #include <TDirectory.h>
18 
19 #include <TH1F.h>
20 #include <TH2F.h>
21 
22 #include <fstream>
23 
24 using namespace Belle2;
25 using namespace SoftwareTrigger;
26 
27 REG_MODULE(StatisticsTimingHLTDQM);
28 
30 {
31  setDescription("Monitor reconstruction runtime on HLT");
33 
34  addParam("histogramDirectoryName", m_param_histogramDirectoryName,
35  "Runtime DQM histograms on HLT will be put into this directory", m_param_histogramDirectoryName);
36 
37  addParam("m_param_overviewModuleList", m_param_overviewModuleList,
38  "Which modules should be shown in the overview mean list", m_param_overviewModuleList);
39 
40  addParam("createHLTUnitHistograms", m_param_create_hlt_unit_histograms,
41  "Create HLT unit histograms?",
42  false);
43 }
44 
46 {
47  // Create a separate histogram directory and cd into it.
48  TDirectory* oldDirectory = nullptr;
49 
50  if (!m_param_histogramDirectoryName.empty()) {
51  oldDirectory = gDirectory;
52  TDirectory* histDir = oldDirectory->mkdir(m_param_histogramDirectoryName.c_str());
53  histDir->cd();
54  }
55 
56  m_meanTimeHistogram = new TH1F("meanTimeHistogram", "Mean Processing Time [ms]", m_param_overviewModuleList.size(), 0,
58  m_meanTimeHistogram->SetStats(false);
59  m_meanMemoryHistogram = new TH1F("meanMemoryHistogram", "Mean Memory Change [MB]", m_param_overviewModuleList.size(), 0,
61  m_meanMemoryHistogram->SetStats(false);
62  m_fullTimeHistogram = new TH1F("fullTimeHistogram", "Budget Time [ms]", m_fullTimeNBins, 0, m_fullTimeMax);
63  m_fullTimeHistogram->StatOverflows(true);
64  m_processingTimeHistogram = new TH1F("processingTimeHistogram", "Processing Time [ms]", m_processingTimeNBins, 0,
66  m_processingTimeHistogram->StatOverflows(true);
67  m_fullMemoryHistogram = new TH1F("fullMemoryHistogram", "Total memory used [MB]", m_fullMemoryNBins, 0,
69  m_fullMemoryHistogram->StatOverflows(true);
70 
71  for (unsigned int index = 0; index < m_param_overviewModuleList.size(); index++) {
72  const std::string& moduleName = m_param_overviewModuleList[index];
73  m_meanTimeHistogram->GetXaxis()->SetBinLabel(index + 1, moduleName.c_str());
74  m_meanMemoryHistogram->GetXaxis()->SetBinLabel(index + 1, moduleName.c_str());
75  m_moduleTimeHistograms.emplace(moduleName, new TH1F((moduleName + "_time").c_str(),
76  ("Time spent in: " + moduleName + " [ms]").c_str(), m_processingTimeNBins, 0, m_processingTimeMax));
77  m_moduleTimeHistograms[moduleName]->StatOverflows(true);
78  m_lastModuleTimeSum.emplace(moduleName, 0);
79  m_moduleMemoryHistograms.emplace(moduleName, new TH1F((moduleName + "_memory").c_str(),
80  ("Memory used in: " + moduleName + " [MB]").c_str(), m_fullMemoryNBins, 0, m_fullMemoryMax));
81  m_moduleMemoryHistograms[moduleName]->StatOverflows(true);
82  }
83 
85  m_fullTimeMeanPerUnitHistogram = new TH1F("fullTimeMeanPerUnitHistogram", "Mean Budget Time Per Unit [ms]",
86  HLTUnits::max_hlt_units + 1, 0,
87  HLTUnits::max_hlt_units + 1);
88  m_fullTimeMeanPerUnitHistogram->SetStats(false);
89  m_fullTimeMeanPerUnitHistogram->SetXTitle("HLT unit number");
90  m_processingTimeMeanPerUnitHistogram = new TH1F("processingTimeMeanPerUnitHistogram", "Mean Processing Time Per Unit [ms]",
91  HLTUnits::max_hlt_units + 1, 0,
92  HLTUnits::max_hlt_units + 1);
93  m_processingTimeMeanPerUnitHistogram->SetStats(false);
94  m_processingTimeMeanPerUnitHistogram->SetXTitle("HLT unit number");
95 
96  for (unsigned int index = 1; index <= HLTUnits::max_hlt_units; index++) {
97  m_fullTimePerUnitHistograms.emplace(index, new TH1F(("fullTimePerUnitHistogram_HLT" + std::to_string(index)).c_str(),
98  ("Budget Time Per Unit: HLT" + std::to_string(index) + " [ms]").c_str(), m_fullTimeNBins, 0, m_fullTimeMax));
99  m_fullTimePerUnitHistograms[index]->StatOverflows(true);
100  m_lastFullTimeSumPerUnit.emplace(index, 0);
101  m_processingTimePerUnitHistograms.emplace(index, new TH1F(("processingTimePerUnitHistogram_HLT" + std::to_string(index)).c_str(),
102  ("Processing Time Per Unit: HLT" + std::to_string(index) + " [ms]").c_str(), m_processingTimeNBins, 0, m_processingTimeMax));
103  m_processingTimePerUnitHistograms[index]->StatOverflows(true);
104  m_lastProcessingTimeSumPerUnit.emplace(index, 0);
105  m_fullMemoryPerUnitHistograms.emplace(index, new TH1F(("fullMemoryPerUnitHistogram_HLT" + std::to_string(index)).c_str(),
106  ("Total Memory Used Per Unit: HLT" + std::to_string(index) + " [MB]").c_str(), m_fullMemoryNBins, 0, m_fullMemoryMax));
107  m_fullMemoryPerUnitHistograms[index]->StatOverflows(true);
108  }
109 
110  m_processesPerUnitHistogram = new TH1F("processesPerUnitHistogram", "Number of Processes Per Unit",
111  HLTUnits::max_hlt_units + 1, 0,
112  HLTUnits::max_hlt_units + 1);
113  m_processesPerUnitHistogram->SetXTitle("HLT unit number");
114  }
115  m_processingTimePassiveVeto = new TH1F("processingTimePassiveVeto", "Processing Time of events passing passive veto [ms]",
118  m_processingTimePassiveVeto->StatOverflows(true);
119  m_processingTimeNotPassiveVeto = new TH1F("processingTimeNotPassiveVeto", "Processing Time of events not passing passive veto [ms]",
122  m_processingTimeNotPassiveVeto->StatOverflows(true);
123 
124  m_procTimeVsnSVDShaperDigitsPassiveVeto = new TH2F("procTimeVsnSVDShaperDigitsPassiveVeto",
125  "Processing time [ms] vs nSVDShaperDigits of events passing passive veto",
128  m_procTimeVsnSVDShaperDigitsPassiveVeto->StatOverflows(true);
129  m_procTimeVsnSVDShaperDigitsPassiveVeto->SetXTitle("nSVDShaperDigits");
130  m_procTimeVsnSVDShaperDigitsPassiveVeto->SetYTitle("Processing time [ms]");
131  m_procTimeVsnSVDShaperDigitsNotPassiveVeto = new TH2F("procTimeVsnSVDShaperDigitsNotPassiveVeto",
132  "Processing time [ms] vs nSVDShaperDigits of events not passing passive veto",
135  m_procTimeVsnSVDShaperDigitsNotPassiveVeto->StatOverflows(true);
136  m_procTimeVsnSVDShaperDigitsNotPassiveVeto->SetXTitle("nSVDShaperDigits");
137  m_procTimeVsnSVDShaperDigitsNotPassiveVeto->SetYTitle("Processing time [ms]");
138  m_procTimeVsnCDCHitsPassiveVeto = new TH2F("procTimeVsnCDCHitsPassiveVeto",
139  "Processing time [ms] vs nCDCHits of events passing passive veto",
142  m_procTimeVsnCDCHitsPassiveVeto->StatOverflows(true);
143  m_procTimeVsnCDCHitsPassiveVeto->SetXTitle("nCDCHits");
144  m_procTimeVsnCDCHitsPassiveVeto->SetYTitle("Processing time [ms]");
145  m_procTimeVsnCDCHitsNotPassiveVeto = new TH2F("procTimeVsnCDCHitsNotPassiveVeto",
146  "Processing time [ms] vs nCDCHits of events not passing passive veto",
149  m_procTimeVsnCDCHitsNotPassiveVeto->StatOverflows(true);
150  m_procTimeVsnCDCHitsNotPassiveVeto->SetXTitle("nCDCHits");
151  m_procTimeVsnCDCHitsNotPassiveVeto->SetYTitle("Processing time [ms]");
152  m_procTimeVsnECLDigitsPassiveVeto = new TH2F("procTimeVsnECLDigitsPassiveVeto",
153  "Processing time [ms] vs nECLDigits of events passing passive veto",
156  m_procTimeVsnECLDigitsPassiveVeto->StatOverflows(true);
157  m_procTimeVsnECLDigitsPassiveVeto->SetXTitle("nECLDigits");
158  m_procTimeVsnECLDigitsPassiveVeto->SetYTitle("Processing time [ms]");
159  m_procTimeVsnECLDigitsNotPassiveVeto = new TH2F("procTimeVsnECLDigitsNotPassiveVeto",
160  "Processing time [ms] vs nECLDigits of events not passing passive veto",
163  m_procTimeVsnECLDigitsNotPassiveVeto->StatOverflows(true);
164  m_procTimeVsnECLDigitsNotPassiveVeto->SetXTitle("nECLDigits");
165  m_procTimeVsnECLDigitsNotPassiveVeto->SetYTitle("Processing time [ms]");
166 
167  if (oldDirectory) {
168  oldDirectory->cd();
169  }
170 }
171 
172 
174 {
175  m_trgSummary.isOptional();
176  m_svdShaperDigits.isOptional();
177  m_cdcHits.isOptional();
178  m_eclDigits.isOptional();
179 
180  // Register histograms (calls back defineHisto)
181  REG_HISTOGRAM
182 
184  // Read the HLT unit's hostname straight from the HLT worker
185  FILE* pipe = popen("hostname -d", "r");
186  if (pipe) {
187  char buffer[128];
188  std::string host = "";
189 
190  while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
191  host += buffer;
192  }
193 
194  pclose(pipe);
195 
196  if (host.length() == 5) {
197  m_hlt_unit = atoi(host.substr(3, 2).c_str());
198  } else {
199  B2WARNING("HLT unit number not found");
200  }
201  } else {
202  B2WARNING("HLT unit number not found");
203  }
204  }
205 }
206 
208 {
210 
211  if (not stats.isValid()) {
212  return;
213  }
214 
215  const std::vector<ModuleStatistics>& moduleStatisticsList = stats->getAll();
216 
217  std::vector<double> meanTimes(m_param_overviewModuleList.size(), 0);
218  std::vector<double> meanMemories(m_param_overviewModuleList.size(), 0);
219 
220  for (const ModuleStatistics& moduleStatistics : moduleStatisticsList) {
221  const std::string& statisticsName = moduleStatistics.getName();
222  const auto m_param_overviewModuleListIterator = std::find(m_param_overviewModuleList.begin(), m_param_overviewModuleList.end(),
223  statisticsName);
224  if (m_param_overviewModuleListIterator == m_param_overviewModuleList.end()) {
225  continue;
226  }
227 
228  const double statisticsTime = moduleStatistics.getTimeMean(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
229  const double statisticsMemory = moduleStatistics.getMemoryMean(ModuleStatistics::EStatisticCounters::c_Total) / 1024;
230  const double statisticsTime_sum = moduleStatistics.getTimeSum(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
231  const double statisticsMemory_sum = moduleStatistics.getMemorySum(ModuleStatistics::EStatisticCounters::c_Total) / 1024;
232 
233  const int m_param_overviewModuleListIndex = std::distance(m_param_overviewModuleList.begin(), m_param_overviewModuleListIterator);
234  meanTimes[m_param_overviewModuleListIndex] += statisticsTime;
235  meanMemories[m_param_overviewModuleListIndex] += statisticsMemory;
236 
237  m_moduleTimeHistograms[statisticsName]->Fill(statisticsTime_sum - m_lastModuleTimeSum[statisticsName]);
238  m_lastModuleTimeSum[statisticsName] = statisticsTime_sum;
239  m_moduleMemoryHistograms[statisticsName]->Fill(statisticsMemory_sum);
240  }
241 
242  for (unsigned int index = 0; index < m_param_overviewModuleList.size(); index++) {
243  m_meanTimeHistogram->SetBinContent(index + 1, meanTimes[index]);
244  m_meanMemoryHistogram->SetBinContent(index + 1, meanMemories[index]);
245  }
246 
247  double processingTimeSum = 0.0;
248  double processingTimeMean = 0.0;
249 
250  for (const ModuleStatistics& moduleStatistics : moduleStatisticsList) {
251  const std::string& statisticsName = moduleStatistics.getName();
252  const auto m_summaryModuleListIterator = std::find(m_summaryModuleList.begin(), m_summaryModuleList.end(),
253  statisticsName);
254  if (m_summaryModuleListIterator == m_summaryModuleList.end()) {
255  continue;
256  }
257  processingTimeSum += moduleStatistics.getTimeSum(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
258  processingTimeMean += moduleStatistics.getTimeMean(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
259  }
260  m_processingTimeHistogram->Fill(processingTimeSum - m_lastProcessingTimeSum);
261 
262  const ModuleStatistics& fullStatistics = stats->getGlobal();
263  const double fullTimeSum = fullStatistics.getTimeSum(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
264  m_fullTimeHistogram->Fill(fullTimeSum - m_lastFullTimeSum);
265  m_lastFullTimeSum = fullTimeSum;
266  const double fullMemorySum = fullStatistics.getMemorySum(ModuleStatistics::EStatisticCounters::c_Total) / 1024;
267  m_fullMemoryHistogram->Fill(fullMemorySum);
268 
270  if (0 < m_hlt_unit) {
271  m_processingTimeMeanPerUnitHistogram->SetBinContent(m_hlt_unit + 1, processingTimeMean);
272 
274  m_lastProcessingTimeSumPerUnit[m_hlt_unit] = processingTimeSum;
275 
276  const double fullTimeMean = fullStatistics.getTimeMean(ModuleStatistics::EStatisticCounters::c_Event) / Unit::ms;
277  m_fullTimeMeanPerUnitHistogram->SetBinContent(m_hlt_unit + 1, fullTimeMean);
278 
280  m_lastFullTimeSumPerUnit[m_hlt_unit] = fullTimeSum;
281 
282  m_fullMemoryPerUnitHistograms[m_hlt_unit]->Fill(fullMemorySum);
283  }
284  }
285 
286  const uint32_t nCDCHits = m_cdcHits.isOptional() ? m_cdcHits.getEntries() : 0;
287  const uint32_t nSVDShaperDigits = m_svdShaperDigits.isOptional() ? m_svdShaperDigits.getEntries() : 0;
288  const uint32_t nECLDigits = m_eclDigits.isOptional() ? m_eclDigits.getEntries() : 0;
289  if (!m_trgSummary.isValid()) {
290  return;
291  }
292  try {
293  if (m_trgSummary->testInput("passive_veto") == 0) { // These events would stay even with just passive veto
294  m_processingTimePassiveVeto->Fill(processingTimeSum - m_lastProcessingTimeSum);
295 
296  m_procTimeVsnSVDShaperDigitsPassiveVeto->Fill(nSVDShaperDigits, processingTimeSum - m_lastProcessingTimeSum);
297  m_procTimeVsnCDCHitsPassiveVeto->Fill(nCDCHits, processingTimeSum - m_lastProcessingTimeSum);
298  m_procTimeVsnECLDigitsPassiveVeto->Fill(nECLDigits, processingTimeSum - m_lastProcessingTimeSum);
299  } else {
300  m_processingTimeNotPassiveVeto->Fill(processingTimeSum - m_lastProcessingTimeSum);
301 
302  m_procTimeVsnSVDShaperDigitsNotPassiveVeto->Fill(nSVDShaperDigits, processingTimeSum - m_lastProcessingTimeSum);
303  m_procTimeVsnCDCHitsNotPassiveVeto->Fill(nCDCHits, processingTimeSum - m_lastProcessingTimeSum);
304  m_procTimeVsnECLDigitsNotPassiveVeto->Fill(nECLDigits, processingTimeSum - m_lastProcessingTimeSum);
305  }
306  } catch (const std::exception&) {
307  return;
308  }
309 
310  m_lastProcessingTimeSum = processingTimeSum;
311 }
312 
314 {
316  B2FATAL("Histograms were not created. Did you setup a HistoManager?");
317  }
318 
319  m_meanTimeHistogram->Reset();
320  m_meanMemoryHistogram->Reset();
321  std::for_each(m_moduleTimeHistograms.begin(), m_moduleTimeHistograms.end(),
322  [](auto & it) { it.second->Reset(); });
323  std::for_each(m_moduleMemoryHistograms.begin(), m_moduleMemoryHistograms.end(),
324  [](auto & it) { it.second->Reset(); });
325  m_fullTimeHistogram->Reset();
326  m_processingTimeHistogram->Reset();
327  m_fullMemoryHistogram->Reset();
331  std::for_each(m_fullTimePerUnitHistograms.begin(), m_fullTimePerUnitHistograms.end(),
332  [](auto & it) { it.second->Reset(); });
334  [](auto & it) { it.second->Reset(); });
336  [](auto & it) { it.second->Reset(); });
338 
340  }
349 
350 }
351 
@ 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
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
std::map< std::string, TH1F * > m_moduleTimeHistograms
Time distribution of certain modules.
const double m_nSVDShaperDigitsNBins
Number of bins for the histograms of nSVDShaperDigits.
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_nECLDigitsMax
Maximum for the histograms of nECLDigits.
TH2F * m_procTimeVsnCDCHitsNotPassiveVeto
Processing time vs nCDCHits distribution of events not passing passive injection veto.
TH2F * m_procTimeVsnSVDShaperDigitsPassiveVeto
Processing time vs nSVDShaperDigits distribution of events passing passive injection veto.
TH1F * m_processingTimeNotPassiveVeto
Processing time distribution of events not passing passive injection veto.
TH2F * m_procTimeVsnCDCHitsPassiveVeto
Processing time vs nCDCHits distribution of events passing passive injection veto.
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.
TH2F * m_procTimeVsnECLDigitsNotPassiveVeto
Processing time vs nECLDigits distribution of events not passing passive injection veto.
const double m_fullTimeNBins
Number of bins for the histograms of fullTime.
TH2F * m_procTimeVsnSVDShaperDigitsNotPassiveVeto
Processing time vs nSVDShaperDigits distribution of events not passing passive injection veto.
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.
const double m_nSVDShaperDigitsMax
Maximum for the histograms of nSVDShaperDigits.
double m_lastFullTimeSum
Storage for the last full time sum.
const double m_nCDCHitsNBins
Number of bins for the histograms of nCDCHits.
std::map< unsigned int, TH1F * > m_fullTimePerUnitHistograms
Budget time distribution of events per unit.
TH1F * m_processingTimePassiveVeto
Processing time distribution of events passing passive injection veto.
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.
const double m_nCDCHitsMax
Maximum for the histograms of nCDCHits.
std::map< std::string, TH1F * > m_moduleMemoryHistograms
Memory distribution of certain modules.
const double m_fullMemoryNBins
Number of bins for the histograms of fullMemory.
const double m_nECLDigitsNBins
Number of bins for the histograms of nECLDigits.
TH2F * m_procTimeVsnECLDigitsPassiveVeto
Processing time vs nECLDigits distribution of events passing passive injection veto.
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:96
static const double ms
[millisecond]
Definition: Unit.h:96
REG_MODULE(arichBtest)
Register the Module.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
Abstract base class for different kinds of events.