CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DQMStoreStats.cc
Go to the documentation of this file.
1 /*
2  * \file DQMStoreStats.cc
3  * \author Andreas Meyer
4  * Last Update:
5  *
6  * Description: Print out statistics of histograms in DQMStore
7 */
8 
9 #include "DQMStoreStats.h"
12 
13 using namespace std;
14 using namespace edm;
15 
16 template <class T>
17 static unsigned int getEmptyMetric(T* array, int lenx, int leny, int lenz) {
18  // len{x,y,z} MUST include under/overflow bins.
19  unsigned int len = lenx + leny + lenz;
20  unsigned int result = 0;
21  // start from 1 to exclude underflow bin. The comparison is accurate
22  // since it takes properly into account under/overflow bins, for all
23  // kind of histograms.
24  for (unsigned int i = 1; i < len; ++i) {
25  // get rid of under/overflow bins for x,y,z axis, to have a correct statistics.
26  if (i % (lenx - 1) == 0)
27  continue;
28  if (i % lenx == 0)
29  continue;
30  if (i % (lenx + leny - 1) == 0)
31  continue;
32  if (i % (lenx + leny) == 0)
33  continue;
34  if (i % (lenx + leny + lenz - 1) == 0)
35  continue;
36 
37  if (array[i] == 0)
38  result += 1;
39  }
40 
41  return result;
42 }
43 
44 //==================================================================//
45 //================= Constructor and Destructor =====================//
46 //==================================================================//
48  : subsystem_(""),
49  subfolder_(""),
50  nbinsglobal_(0),
51  nbinssubsys_(0),
52  nmeglobal_(0),
53  nmesubsys_(0),
54  maxbinsglobal_(0),
55  maxbinssubsys_(0),
56  maxbinsmeglobal_(""),
57  maxbinsmesubsys_(""),
58  statsdepth_(1),
59  pathnamematch_(""),
60  verbose_(0) {
61  parameters_ = ps;
63  statsdepth_ = ps.getUntrackedParameter<int>("statsDepth", statsdepth_);
64  verbose_ = ps.getUntrackedParameter<int>("verbose", verbose_);
65  dumpMemHistory_ = ps.getUntrackedParameter<bool>("dumpMemoryHistory", false);
66  runonendrun_ = ps.getUntrackedParameter<bool>("runOnEndRun", true);
67  runonendjob_ = ps.getUntrackedParameter<bool>("runOnEndJob", false);
68  runonendlumi_ = ps.getUntrackedParameter<bool>("runOnEndLumi", false);
69  runineventloop_ = ps.getUntrackedParameter<bool>("runInEventLoop", false);
70  dumpToFWJR_ = ps.getUntrackedParameter<bool>("dumpToFWJR", false);
71 
72  startingTime_ = time(nullptr);
73 }
74 
76 
78  std::ofstream stream("dqm-bin-stats.sql");
79  stream << ""
80  " PRAGMA journal_mode=OFF;"
81  " PRAGMA count_changes=OFF;"
82  " DROP TABLE IF EXISTS files;"
83  " DROP TABLE IF EXISTS symbols;"
84  " DROP TABLE IF EXISTS mainrows;"
85  " DROP TABLE IF EXISTS children;"
86  " DROP TABLE IF EXISTS parents;"
87  " DROP TABLE IF EXISTS summary;"
88  " CREATE TABLE children ("
89  " self_id INTEGER CONSTRAINT self_exists REFERENCES mainrows(id),"
90  " parent_id INTEGER CONSTRAINT parent_exists REFERENCES mainrows(id),"
91  " from_parent_count INTEGER,"
92  " from_parent_calls INTEGER,"
93  " from_parent_paths INTEGER,"
94  " pct REAL"
95  " );"
96  " CREATE TABLE files ("
97  " id,"
98  " name TEXT"
99  " );"
100  " CREATE TABLE mainrows ("
101  " id INTEGER PRIMARY KEY,"
102  " symbol_id INTEGER CONSTRAINT symbol_id_exists REFERENCES symbols(id),"
103  " self_count INTEGER,"
104  " cumulative_count INTEGER,"
105  " kids INTEGER,"
106  " self_calls INTEGER,"
107  " total_calls INTEGER,"
108  " self_paths INTEGER,"
109  " total_paths INTEGER,"
110  " pct REAL"
111  " );"
112  " CREATE TABLE parents ("
113  " self_id INTEGER CONSTRAINT self_exists REFERENCES mainrows(id),"
114  " child_id INTEGER CONSTRAINT child_exists REFERENCES mainrows(id),"
115  " to_child_count INTEGER,"
116  " to_child_calls INTEGER,"
117  " to_child_paths INTEGER,"
118  " pct REAL"
119  " );"
120  " CREATE TABLE summary ("
121  " counter TEXT,"
122  " total_count INTEGER,"
123  " total_freq INTEGER,"
124  " tick_period REAL"
125  " );"
126  " CREATE TABLE symbols ("
127  " id,"
128  " name TEXT,"
129  " filename_id INTEGER CONSTRAINT file_id_exists REFERENCES files(id)"
130  " );"
131  " CREATE UNIQUE INDEX fileIndex ON files (id);"
132  " CREATE INDEX selfCountIndex ON mainrows(self_count);"
133  " CREATE UNIQUE INDEX symbolsIndex ON symbols (id);"
134  " CREATE INDEX totalCountIndex ON mainrows(cumulative_count);"
135  << std::endl;
136 
137  std::string sql_statement("");
138 
139  root.files(sql_statement);
140  root.symbols(sql_statement);
141  root.mainrows_cumulative(sql_statement);
142  root.summary(sql_statement);
143  VIterator<Folder*> subsystems = root.CreateIterator();
144  size_t ii = 0;
145  for (subsystems.First(); !subsystems.IsDone(); subsystems.Next(), ++ii) {
146  subsystems.CurrentItem()->mainrows(sql_statement);
147  subsystems.CurrentItem()->parents(sql_statement);
148  subsystems.CurrentItem()->children(sql_statement);
149  }
150  stream << sql_statement << std::endl;
151 }
152 
161  nbinsglobal_ = 0;
162  nbinssubsys_ = 0;
163  maxbinsglobal_ = 0;
164  maxbinssubsys_ = 0;
165  std::string path = "";
166  std::string subsystemname = "";
167  std::string subfoldername = "";
168  size_t subsysStringEnd = 0, subfolderStringBegin = 0, subfolderStringEnd = 0;
169 
170  std::vector<MonitorElement*> melist;
172 
173  Folder dbeFolder("root");
174  DQMStoreStatsTopLevel dqmStoreStatsTopLevel;
175 
176  // loop all ME
177  for (auto& it : melist) {
178  // consider only ME with getLumiFlag() == true ?
179  if (mode == DQMStoreStats::considerOnlyLumiProductME && !(it->getLumiFlag()))
180  continue;
181 
182  // figure out subsystem/subfolder names
183  const std::string& path = it->getPathname();
184 
185  subfolderStringBegin = 0;
186  Folder* curr = &dbeFolder;
187  while (true) {
188  subfolderStringEnd = path.find('/', subfolderStringBegin);
189  if (std::string::npos == subfolderStringEnd) {
190  curr = curr->cd(path.substr(subfolderStringBegin, path.size() - subfolderStringBegin));
191  break;
192  }
193  curr = curr->cd(path.substr(subfolderStringBegin, subfolderStringEnd - subfolderStringBegin));
194  subfolderStringBegin = ++subfolderStringEnd < path.size() ? subfolderStringEnd : path.size();
195  }
196 
197  // protection against ghost ME with empty paths
198  if (path.empty())
199  continue;
200 
201  subsysStringEnd = path.find('/', 0);
202  if (std::string::npos == subsysStringEnd)
203  subsysStringEnd = path.size(); // no subfolder
204 
205  // new subsystem?
206  if (path.substr(0, subsysStringEnd) != subsystemname) {
207  DQMStoreStatsSubsystem aSubsystem;
208  subsystemname = path.substr(0, subsysStringEnd);
209  aSubsystem.subsystemName_ = subsystemname;
210  dqmStoreStatsTopLevel.push_back(aSubsystem);
211  subfoldername = "";
212  }
213 
214  // get subfolder name (if there is one..)
215  if (path.size() == subsysStringEnd) {
216  // no subfolders in subsystem, make dummy
217  DQMStoreStatsSubfolder aSubfolder;
218  aSubfolder.subfolderName_ = subsystemname; // <-- for tagging this case
219  dqmStoreStatsTopLevel.back().push_back(aSubfolder);
220  }
221 
222  else {
223  // there is a subfolder, get its name
224  subfolderStringEnd = path.find('/', subsysStringEnd + 1);
225  if (std::string::npos == subfolderStringEnd)
226  subfolderStringEnd = path.size();
227 
228  // new subfolder?
229  if (path.substr(subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1) != subfoldername) {
230  subfoldername = path.substr(subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1);
231  DQMStoreStatsSubfolder aSubfolder;
232  aSubfolder.subfolderName_ = subfoldername;
233  dqmStoreStatsTopLevel.back().push_back(aSubfolder);
234  }
235  }
236 
237  // shortcut
238  DQMStoreStatsSubfolder& currentSubfolder = dqmStoreStatsTopLevel.back().back();
239 
240  switch (it->kind()) {
241  // one-dim ME
243  currentSubfolder.AddBinsF(it->getNbinsX(), getEmptyMetric(it->getTH1F()->GetArray(), it->getTH1F()->fN, 0, 0));
244  curr->update(it->getNbinsX(),
245  getEmptyMetric(it->getTH1F()->GetArray(), it->getTH1F()->fN, 0, 0),
246  it->getNbinsX() * sizeof(float));
247  break;
249  currentSubfolder.AddBinsS(it->getNbinsX(), getEmptyMetric(it->getTH1S()->GetArray(), it->getTH1S()->fN, 0, 0));
250  curr->update(it->getNbinsX(),
251  getEmptyMetric(it->getTH1S()->GetArray(), it->getTH1S()->fN, 0, 0),
252  it->getNbinsX() * sizeof(short));
253  break;
255  currentSubfolder.AddBinsD(it->getNbinsX(), getEmptyMetric(it->getTH1D()->GetArray(), it->getTH1D()->fN, 0, 0));
256  curr->update(it->getNbinsX(),
257  getEmptyMetric(it->getTH1D()->GetArray(), it->getTH1D()->fN, 0, 0),
258  it->getNbinsX() * sizeof(double));
259  break;
261  currentSubfolder.AddBinsI(it->getNbinsX(), getEmptyMetric(it->getTH1I()->GetArray(), it->getTH1I()->fN, 0, 0));
262  curr->update(it->getNbinsX(),
263  getEmptyMetric(it->getTH1I()->GetArray(), it->getTH1I()->fN, 0, 0),
264  it->getNbinsX() * sizeof(int));
265  break;
267  currentSubfolder.AddBinsD(it->getNbinsX(),
268  getEmptyMetric(it->getTProfile()->GetArray(), it->getTProfile()->fN, 0, 0));
269  curr->update(it->getNbinsX(),
270  getEmptyMetric(it->getTProfile()->GetArray(), it->getTProfile()->fN, 0, 0),
271  it->getNbinsX() * sizeof(double));
272  break;
273 
274  // two-dim ME
276  currentSubfolder.AddBinsF(
277  it->getNbinsX() * it->getNbinsY(),
278  getEmptyMetric(it->getTH2F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
279  curr->update(it->getNbinsX() * it->getNbinsY(),
280  getEmptyMetric(it->getTH2F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
281  it->getNbinsX() * it->getNbinsY() * sizeof(float));
282  break;
284  currentSubfolder.AddBinsS(
285  it->getNbinsX() * it->getNbinsY(),
286  getEmptyMetric(it->getTH2S()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
287  curr->update(it->getNbinsX() * it->getNbinsY(),
288  getEmptyMetric(it->getTH2S()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
289  it->getNbinsX() * it->getNbinsY() * sizeof(short));
290  break;
292  currentSubfolder.AddBinsD(
293  it->getNbinsX() * it->getNbinsY(),
294  getEmptyMetric(it->getTH2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
295  curr->update(it->getNbinsX() * it->getNbinsY(),
296  getEmptyMetric(it->getTH2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
297  it->getNbinsX() * it->getNbinsY() * sizeof(double));
298  break;
300  currentSubfolder.AddBinsI(
301  it->getNbinsX() * it->getNbinsY(),
302  getEmptyMetric(it->getTH2I()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
303  curr->update(it->getNbinsX() * it->getNbinsY(),
304  getEmptyMetric(it->getTH2I()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
305  it->getNbinsX() * it->getNbinsY() * sizeof(int));
306  break;
308  currentSubfolder.AddBinsD(
309  it->getNbinsX() * it->getNbinsY(),
310  getEmptyMetric(it->getTProfile2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
311  curr->update(it->getNbinsX() * it->getNbinsY(),
312  getEmptyMetric(it->getTProfile2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
313  it->getNbinsX() * it->getNbinsY() * sizeof(double));
314  break;
315 
316  // three-dim ME
318  currentSubfolder.AddBinsF(
319  it->getNbinsX() * it->getNbinsY() * it->getNbinsZ(),
320  getEmptyMetric(it->getTH3F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, it->getNbinsZ() + 2));
321  curr->update(
322  it->getNbinsX() * it->getNbinsY() * it->getNbinsZ(),
323  getEmptyMetric(it->getTH3F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, it->getNbinsZ() + 2),
324  it->getNbinsX() * it->getNbinsY() * it->getNbinsZ() * sizeof(float));
325  break;
326 
327  default: {
328  }
329  // here we have a DQM_KIND_INVALID, DQM_KIND_INT, DQM_KIND_REAL or DQM_KIND_STRING
330  // which we don't care much about. Alternatively:
331 
332  // std::cerr << "[DQMStoreStats::calcstats] ** WARNING: monitor element of kind: "
333  // << (*it)->kind() << ", name: \"" << (*it)->getName() << "\"\n"
334  // << " in path: \"" << path << "\" not considered." << std::endl;
335  }
336  }
337 
339  calcIgProfDump(dbeFolder);
340 
341  // OUTPUT
342 
343  std::cout << endl;
344  std::cout << "==========================================================================================="
345  << std::endl;
346  std::cout << "[DQMStoreStats::calcstats] -- Dumping stats results ";
348  std::cout << "FOR ALL ME" << std::endl;
350  std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl;
351  std::cout << "==========================================================================================="
352  << std::endl;
353  std::cout << endl;
354 
355  std::cout << "------------------------------------------------------------------------------------------"
356  << std::endl;
357  std::cout << "Configuration:" << std::endl;
358  std::cout << "------------------------------------------------------------------------------------------"
359  << std::endl;
360  std::cout << " > running ";
361  if (runonendrun_)
362  std::cout << "on run end." << std::endl;
363  if (runonendlumi_)
364  std::cout << "on lumi end." << std::endl;
365  if (runonendjob_)
366  std::cout << "on job end." << std::endl;
367  if (runineventloop_)
368  std::cout << "in event loop." << std::endl;
369  std::cout << " > pathNameMatch = \"" << pathnamematch_ << "\"" << std::endl;
370  std::cout << std::endl;
371 
372  // dump folder structure
373  std::cout << "------------------------------------------------------------------------------------------"
374  << std::endl;
375  std::cout << "Top level folder tree:" << std::endl;
376  std::cout << "------------------------------------------------------------------------------------------"
377  << std::endl;
378  for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) {
379  std::cout << it0->subsystemName_ << " (subsystem)" << std::endl;
380 
381  for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) {
382  std::cout << " |--> " << it1->subfolderName_ << " (subfolder)" << std::endl;
383  }
384  }
385 
386  // dump mem/bin table
387 
388  unsigned int overallNHistograms = 0, overallNBins = 0, overallNEmptyBins = 0, overallNBytes = 0;
389 
390  std::cout << std::endl;
391  std::cout << "------------------------------------------------------------------------------------------"
392  << std::endl;
393  std::cout << "Detailed ressource usage information ";
395  std::cout << "FOR ALL ME" << std::endl;
397  std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl;
398  std::cout << "------------------------------------------------------------------------------------------"
399  << std::endl;
400  std::cout << "subsystem/folder histograms bins Empty bins Empty/Total "
401  "bins per MB kB per"
402  << std::endl;
403  std::cout << " (total) (total) (total) "
404  "histogram (total) histogram "
405  << std::endl;
406  std::cout << "------------------------------------------------------------------------------------------"
407  << std::endl;
408  for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) {
409  std::cout << it0->subsystemName_ << std::endl;
410 
411  unsigned int nHistograms = 0, nBins = 0, nEmptyBins = 0, nBytes = 0;
412 
413  for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) {
414  // fixed-size working copy
415  std::string thisSubfolderName(it1->subfolderName_);
416  if (thisSubfolderName.size() > 30) {
417  thisSubfolderName.resize(30);
418  thisSubfolderName.replace(thisSubfolderName.size() - 3, 3, 3, '.');
419  }
420 
421  std::cout << " -> " << std::setw(30) << std::left << thisSubfolderName;
422  std::cout << std::setw(14) << std::right << it1->totalHistos_;
423  std::cout << std::setw(14) << std::right << it1->totalBins_;
424  std::cout << std::setw(14) << std::right << it1->totalEmptyBins_;
425  std::cout << std::setw(14) << std::right << std::setprecision(3)
426  << (float)it1->totalEmptyBins_ / (float)it1->totalBins_;
427 
428  // bins/histogram, need to catch nan if histos=0
429  if (it1->totalHistos_) {
430  std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalBins_ / float(it1->totalHistos_);
431  } else
432  std::cout << std::setw(14) << std::right << "-";
433 
434  std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalMemory_ / 1024. / 1024.;
435 
436  // mem/histogram, need to catch nan if histos=0
437  if (it1->totalHistos_) {
438  std::cout << std::setw(14) << std::right << std::setprecision(3)
439  << it1->totalMemory_ / 1024. / it1->totalHistos_;
440  } else
441  std::cout << std::setw(14) << std::right << "-";
442 
443  std::cout << std::endl;
444 
445  // collect totals
446  nHistograms += it1->totalHistos_;
447  nBins += it1->totalBins_;
448  nEmptyBins += it1->totalEmptyBins_;
449  nBytes += it1->totalMemory_;
450  }
451 
452  overallNHistograms += nHistograms;
453  overallNBins += nBins;
454  overallNEmptyBins += nEmptyBins;
455  overallNBytes += nBytes;
456 
457  // display totals
458  std::cout << " " << std::setw(30) << std::left << "SUBSYSTEM TOTAL";
459  std::cout << std::setw(14) << std::right << nHistograms;
460  std::cout << std::setw(14) << std::right << nBins;
461  std::cout << std::setw(14) << std::right << nEmptyBins;
462  std::cout << std::setw(14) << std::right << (float)nEmptyBins / (float)nBins;
463  std::cout << std::setw(14) << std::right << std::setprecision(3) << nBins / float(nHistograms);
464  std::cout << std::setw(14) << std::right << std::setprecision(3) << nBytes / 1024. / 1000.;
465  std::cout << std::setw(14) << std::right << std::setprecision(3) << nBytes / 1024. / nHistograms;
466  std::cout << std::endl;
467 
468  std::cout << ".........................................................................................."
469  << std::endl;
470  }
471 
472  // dump total
473  std::cout << std::endl;
474  std::cout << "------------------------------------------------------------------------------------------"
475  << std::endl;
476  std::cout << "Grand total ";
478  std::cout << "FOR ALL ME:" << std::endl;
480  std::cout << "FOR LUMI PRODUCTS ONLY:" << std::endl;
481  std::cout << "------------------------------------------------------------------------------------------"
482  << std::endl;
483  std::cout << "Number of subsystems: " << dqmStoreStatsTopLevel.size() << std::endl;
484  std::cout << "Total number of histograms: " << overallNHistograms << " with: " << overallNBins << " bins alltogether"
485  << std::endl;
486  std::cout << "Total memory occupied by histograms (excl. overhead): " << overallNBytes / 1024. / 1000. << " MB"
487  << std::endl;
488 
489  std::cout << endl;
490  std::cout << "==========================================================================================="
491  << std::endl;
492  std::cout << "[DQMStoreStats::calcstats] -- End of output ";
494  std::cout << "FOR ALL ME." << std::endl;
496  std::cout << "FOR LUMI PRODUCTS ONLY." << std::endl;
497  std::cout << "==========================================================================================="
498  << std::endl;
499  std::cout << endl;
500 
501  // Put together a simplified version of the complete dump that is
502  // sent to std::cout. Just dump the very basic information,
503  // i.e. summary for each folder, both for run and LS products.
504  if (dumpToFWJR_) {
506  // Do not even try if the FWJR service is not available.
507  if (!jr.isAvailable())
508  return 0;
509  // Prepare appropriate map to store FWJR output.
510  std::map<std::string, std::string> jrInfo;
511  unsigned int overallNHistograms = 0, overallNBins = 0, overallNBytes = 0;
512 
513  jrInfo["Source"] = "DQMServices/Components";
514  jrInfo["FileClass"] = "DQMStoreStats";
515  if (runonendrun_)
516  jrInfo["DumpType"] = "EndRun";
517  if (runonendlumi_)
518  jrInfo["DumpType"] = "EndLumi";
519  if (runonendjob_)
520  jrInfo["DumpType"] = "EndJob";
521  if (runineventloop_)
522  jrInfo["DumpType"] = "EventLoop";
524  jrInfo["Type"] = "RunProduct";
526  jrInfo["Type"] = "LumiProduct";
527 
528  jrInfo["pathNameMatch"] = pathnamematch_;
529 
530  for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) {
531  unsigned int nHistograms = 0, nBins = 0, nEmptyBins = 0, nBytes = 0;
532  for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) {
533  // collect totals
534  nHistograms += it1->totalHistos_;
535  nBins += it1->totalBins_;
536  nEmptyBins += it1->totalEmptyBins_;
537  nBytes += it1->totalMemory_;
538  }
539  overallNHistograms += nHistograms;
540  overallNBins += nBins;
541  overallNBytes += nBytes;
542  std::stringstream iss("");
543  iss << nHistograms;
544  jrInfo[it0->subsystemName_ + std::string("_h")] = iss.str();
545  iss.str("");
546  iss << nBins;
547  jrInfo[it0->subsystemName_ + std::string("_b")] = iss.str();
548  iss.str("");
549  iss << nEmptyBins;
550  jrInfo[it0->subsystemName_ + std::string("_be")] = iss.str();
551  iss.str("");
552  iss << ((float)nEmptyBins / (float)nBins);
553  jrInfo[it0->subsystemName_ + std::string("_fbe")] = iss.str();
554  iss.str("");
555  iss << ((float)nBins / (float)nHistograms);
556  jrInfo[it0->subsystemName_ + std::string("_b_h")] = iss.str();
557  iss.str("");
558  iss << nBytes / 1024. / 1024.;
559  jrInfo[it0->subsystemName_ + std::string("_MB")] = iss.str();
560  iss.str("");
561  iss << nBytes / 1024. / nHistograms;
562  jrInfo[it0->subsystemName_ + std::string("_Kb_h")] = iss.str();
563  }
564  jr->reportAnalysisFile("DQMStatsReport", jrInfo);
565  }
566 
567  return 0;
568 }
569 
574  std::cout << std::endl;
575  std::cout << "------------------------------------------------------------------------------------------"
576  << std::endl;
577  std::cout << "Memory profile:" << std::endl;
578  std::cout << "------------------------------------------------------------------------------------------"
579  << std::endl;
580 
581  // determine virtual memory maximum
582  std::pair<time_t, unsigned int> maxItem(0, 0);
583  for (auto it = memoryHistoryVector_.begin(); it < memoryHistoryVector_.end(); ++it) {
584  if (it->second > maxItem.second) {
585  maxItem = *it;
586  }
587  }
588 
589  std::stringstream rootOutputFileName;
590  rootOutputFileName << "dqmStoreStats_memProfile_" << getpid() << ".root";
591 
592  // dump memory history to root file
594  TFile outputFile(rootOutputFileName.str().c_str(), "RECREATE");
595 
596  int aTime;
597  float aMb;
598 
599  TTree memHistoryTree("dqmstorestats_memhistory", "memory history");
600  memHistoryTree.Branch("seconds", &aTime, "seconds/I");
601  memHistoryTree.Branch("megabytes", &aMb, "megabytes/F");
602  for (auto it = memoryHistoryVector_.begin(); it < memoryHistoryVector_.end(); ++it) {
603  aTime = it->first - startingTime_;
604  aMb = it->second / 1000.;
605  memHistoryTree.Fill();
606  }
607 
608  outputFile.Write();
609  outputFile.Close();
610  }
611 
612  std::cout << "Approx. maximum total virtual memory size of job: ";
614  std::cout << maxItem.second / 1000. << " MB (reached " << maxItem.first - startingTime_
615  << " sec. after constructor called)," << std::endl;
616  std::cout << " memory history written to: " << rootOutputFileName.str() << " (" << memoryHistoryVector_.size()
617  << " samples)" << std::endl;
618  } else {
619  std::cout << "(could not be determined)" << std::endl;
620  }
621 
622  std::cout << std::endl << std::endl;
623 }
624 
629  // subsystem info printout
630  std::cout << " ---------- " << subsystem_ << " ---------- " << std::endl;
631  std::cout << " " << subfolder_ << ": ";
632  std::cout << nmesubsys_ << " histograms with " << nbinssubsys_ << " bins. ";
633  if (nmesubsys_ > 0)
634  std::cout << nbinssubsys_ / nmesubsys_ << " bins/histogram ";
635  std::cout << std::endl;
636  std::cout << " Largest histogram: " << maxbinsmesubsys_ << " with " << maxbinssubsys_ << " bins." << std::endl;
637 }
638 
642 std::pair<unsigned int, unsigned int> DQMStoreStats::readMemoryEntry() const {
643  // see if initial test reading was successful
645  std::ifstream procFile(procFileName_.str().c_str(), ios::in);
646 
647  std::string readBuffer("");
648  unsigned int memSize = 0;
649 
650  // scan procfile
651  while (!procFile.eof()) {
652  procFile >> readBuffer;
653  if (std::string("VmSize:") == readBuffer) {
654  procFile >> memSize;
655  break;
656  }
657  }
658 
659  procFile.close();
660  return std::pair<time_t, unsigned int>(time(nullptr), memSize);
661  }
662 
663  return std::pair<time_t, unsigned int>(0, 0);
664 }
665 
666 //==================================================================//
667 //========================= beginJob ===============================//
668 //==================================================================//
672 
673  // access the proc/ folder for memory information
674  procFileName_ << "/proc/" << getpid() << "/status";
675 
676  // open for a test
677  std::ifstream procFile(procFileName_.str().c_str(), ios::in);
678 
679  if (procFile.good()) {
681  } else {
682  std::cerr << " [DQMStoreStats::beginJob] ** WARNING: could not open file: " << procFileName_.str() << std::endl;
683  std::cerr << " Total memory profile will not be available." << std::endl;
685  }
686 
687  procFile.close();
688 }
689 
690 //==================================================================//
691 //========================= beginRun ===============================//
692 //==================================================================//
694 
695 //==================================================================//
696 //==================== analyse (takes each event) ==================//
697 //==================================================================//
698 void DQMStoreStats::analyze(const Event& iEvent, const EventSetup& iSetup) {
699  //now read virtual memory size from proc folder
700  memoryHistoryVector_.emplace_back(readMemoryEntry());
701 
702  if (runineventloop_) {
706  }
707 }
708 
709 //==================================================================//
710 //========================= endLuminosityBlock =====================//
711 //==================================================================//
713  if (runonendlumi_) {
717  }
718 }
719 
720 //==================================================================//
721 //============================= endRun =============================//
722 //==================================================================//
724  if (runonendrun_) {
728  }
729 }
730 
731 //==================================================================//
732 //============================= endJob =============================//
733 //==================================================================//
735  if (runonendjob_) {
739  }
740 }
std::string subfolderName_
Definition: DQMStoreStats.h:49
T getUntrackedParameter(std::string const &, T const &) const
DQMStore * dbe_
tuple array
Definition: mps_check.py:216
void AddBinsS(unsigned int nBins, unsigned int nEmptyBins)
Definition: DQMStoreStats.h:60
void endJob() override
void update(unsigned int bins, unsigned int empty, unsigned int memory)
void AddBinsD(unsigned int nBins, unsigned int nEmptyBins)
Definition: DQMStoreStats.h:66
std::vector< std::pair< time_t, unsigned int > > memoryHistoryVector_
void AddBinsI(unsigned int nBins, unsigned int nEmptyBins)
Definition: DQMStoreStats.h:72
std::string subsystemName_
Definition: DQMStoreStats.h:87
void beginJob() override
void mainrows_cumulative(std::string &sql_statement)
VIterator< Folder * > CreateIterator()
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
int ii
Definition: cuy.py:589
time_t startingTime_
virtual std::vector< dqm::harvesting::MonitorElement * > getAllContents(std::string const &path) const
Definition: DQMStore.cc:609
void summary(std::string &sql_statement)
tuple result
Definition: mps_fire.py:311
std::string subsystem_
void endRun(const edm::Run &r, const edm::EventSetup &c) override
void mainrows(std::string &sql_statement)
int calcstats(int)
int iEvent
Definition: GenABIO.cc:224
bool isOpenProcFileSuccessful_
void endLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &c) override
Item CurrentItem() const override
std::string pathnamematch_
bool isAvailable() const
Definition: Service.h:40
std::string maxbinsmesubsys_
DQMStoreStats(const edm::ParameterSet &)
void files(std::string &sql_statement)
void Next() override
void analyze(const edm::Event &e, const edm::EventSetup &c) override
void parents(std::string &sql_statement)
bool IsDone() const override
void First() override
std::string subfolder_
static unsigned int getEmptyMetric(T *array, int lenx, int leny, int lenz)
Folder * cd(const std::string &name)
edm::ParameterSet parameters_
void AddBinsF(unsigned int nBins, unsigned int nEmptyBins)
Definition: DQMStoreStats.h:54
void children(std::string &sql_statement)
void reportAnalysisFile(std::string const &fileName, std::map< std::string, std::string > const &fileData)
Definition: JobReport.cc:474
void calcIgProfDump(Folder &)
void beginRun(const edm::Run &r, const edm::EventSetup &c) override
std::pair< unsigned int, unsigned int > readMemoryEntry() const
tuple cout
Definition: gather_cfg.py:144
std::stringstream procFileName_
~DQMStoreStats() override
long double T
void dumpMemoryProfile()
void symbols(std::string &sql_statement)
Definition: Run.h:45