CMS 3D CMS Logo

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 
18 #include <string>
19 #include <sstream>
20 #include <utility>
21 #include <vector>
22 #include <iostream>
23 #include <iomanip>
24 #include <utility>
25 #include <fstream>
26 #include <sstream>
27 
28 #include "TFile.h"
29 #include "TTree.h"
30 
36 
37 //
38 // class declarations
39 //
40 
43 
49 public:
51  totalHistos_ = 0;
52  totalBins_ = 0;
53  totalMemory_ = 0;
54  totalEmptyBins_ = 0;
55  }
57  unsigned int totalHistos_;
58  unsigned int totalBins_;
59  unsigned int totalEmptyBins_;
60  unsigned int totalMemory_;
61  void AddBinsF(unsigned int nBins, unsigned int nEmptyBins) {
62  ++totalHistos_;
63  totalBins_ += nBins;
64  totalEmptyBins_ += nEmptyBins;
65  totalMemory_ += (nBins *= sizeof(float));
66  }
67  void AddBinsS(unsigned int nBins, unsigned int nEmptyBins) {
68  ++totalHistos_;
69  totalBins_ += nBins;
70  totalEmptyBins_ += nEmptyBins;
71  totalMemory_ += (nBins *= sizeof(short));
72  }
73  void AddBinsD(unsigned int nBins, unsigned int nEmptyBins) {
74  ++totalHistos_;
75  totalBins_ += nBins;
76  totalEmptyBins_ += nEmptyBins;
77  totalMemory_ += (nBins *= sizeof(double));
78  }
79  void AddBinsI(unsigned int nBins, unsigned int nEmptyBins) {
80  ++totalHistos_;
81  totalBins_ += nBins;
82  totalEmptyBins_ += nEmptyBins;
83  totalMemory_ += (nBins *= sizeof(int));
84  }
85 };
86 
91 class DQMStoreStatsSubsystem : public std::vector<DQMStoreStatsSubfolder> {
92 public:
93  DQMStoreStatsSubsystem() = default;
95 };
96 
101 class DQMStoreStatsTopLevel : public std::vector<DQMStoreStatsSubsystem> {
102 public:
103  DQMStoreStatsTopLevel() = default;
104 };
105 
106 template <class Item>
107 class Iterator {
108 public:
109  virtual ~Iterator() = default;
110  virtual void First() = 0;
111  virtual void Next() = 0;
112  virtual bool IsDone() const = 0;
113  virtual Item CurrentItem() const = 0;
114 
115 protected:
116  Iterator() = default;
117 };
118 
119 template <class Item>
120 class VIterator : public Iterator<Item> {
121 public:
122  VIterator(const std::vector<Item>* aVector) : vector_(aVector), index(0) {}
123  ~VIterator() override = default;
124  void First() override { index = 0; }
125  void Next() override { ++index; }
126  virtual int size() { return vector_->size(); }
127  virtual int getIndex() { return (int)index; }
128 
129  bool IsDone() const override {
130  if (index < (unsigned int)vector_->size())
131  return false;
132  return true;
133  }
134 
135  Item CurrentItem() const override { return vector_->operator[](index); }
136 
137 private:
138  const std::vector<Item>* vector_;
139  unsigned int index;
140 };
141 
142 static unsigned int getId() {
143  static unsigned int id = 10;
144  return ++id;
145 }
146 
147 class Folder {
148 public:
150  : totalHistos_(0),
151  totalBins_(0),
152  totalEmptyBins_(0),
153  totalMemory_(0),
154  id_(10),
155  level_(0),
157  father_(nullptr) {}
158 
160  for (auto& subfolder : subfolders_)
161  delete subfolder;
162  }
163 
164  void setFather(Folder* e) { father_ = e; }
165  Folder* getFather() { return father_; }
166  const std::string& name() { return folderName_; }
167 
169  for (auto& subfolder : subfolders_)
170  if (subfolder->name() == name)
171  return subfolder;
172  auto* tmp = new Folder(name);
173  this->add(tmp);
174  return tmp;
175  }
176 
177  void setId(unsigned int id) { id_ = id; }
178  unsigned int id() { return id_; }
179  void setLevel(unsigned int value) { level_ = value; }
180  unsigned int level() { return level_; }
181 
182  void add(Folder* f) {
183  f->setFather(this);
184  subfolders_.push_back(f);
185  f->setLevel(level_ + 1);
186  f->setId(getId());
187  }
188 
189  unsigned int getHistos() {
190  unsigned int result = totalHistos_;
191  for (auto& subfolder : subfolders_)
192  result += subfolder->getHistos();
193  return result;
194  }
195  unsigned int getBins() {
196  unsigned int result = totalBins_;
197  for (auto& subfolder : subfolders_)
198  result += subfolder->getBins();
199  return result;
200  }
201  unsigned int getEmptyBins() {
202  unsigned int result = totalEmptyBins_;
203  for (auto& subfolder : subfolders_)
204  result += subfolder->getEmptyBins();
205  return result;
206  }
207  unsigned int getMemory() {
208  unsigned int result = totalMemory_;
209  for (auto& subfolder : subfolders_)
210  result += subfolder->getMemory();
211  return result;
212  }
213  void update(unsigned int bins, unsigned int empty, unsigned int memory) {
214  totalHistos_ += 1;
215  totalBins_ += bins;
217  totalMemory_ += memory;
218  }
220  indent.append(" ");
221  std::cout << indent << "I'm a " << name() << " whose father is " << getFather() << " with ID: " << id_
222  << " Histo: " << getHistos() << " Bins: " << getBins() << " EmptyBins: " << getEmptyBins()
223  << " Memory: " << getMemory() << " and my children are: " << std::endl;
224  for (auto& subfolder : subfolders_)
225  subfolder->dump(indent);
226  }
228 
229  void mainrows(std::string& sql_statement) {
230  std::stringstream s("");
231  s << "INSERT INTO mainrows(id, symbol_id, self_count, cumulative_count, kids, self_calls, total_calls, self_paths, "
232  "total_paths, pct)"
233  " VALUES("
234  << id_ << ", " << id_ << ", " << getMemory() << ", " << getMemory() << ", " << subfolders_.size() << ", "
235  << getBins() - getEmptyBins() << ", " << getBins() << ", " << getHistos() << ", " << getHistos() << ", 0.0);\n";
236  sql_statement.append(s.str());
237  for (auto& subfolder : subfolders_)
238  subfolder->mainrows(sql_statement);
239  }
240 
241  void symbols(std::string& sql_statement) {
242  unsigned int parentid = this->getFather() ? this->getFather()->id() : id_;
243  std::stringstream s("");
244  s << "INSERT INTO symbols(id, name, filename_id) VALUES (" << id_ << ",\"" << folderName_ << "\", " << parentid
245  << ");\n";
246  sql_statement.append(s.str());
247  for (auto& subfolder : subfolders_)
248  subfolder->symbols(sql_statement);
249  }
250 
251  void parents(std::string& sql_statement) {
252  unsigned int parentid = this->getFather() ? this->getFather()->id() : id_;
253  std::stringstream s("");
254  s << "INSERT INTO parents(self_id, child_id, to_child_count, to_child_calls, to_child_paths, pct) VALUES("
255  << parentid << "," << id_ << "," << totalMemory_ << "," << totalBins_ << "," << totalHistos_ << ",0"
256  << ");\n";
257  sql_statement.append(s.str());
258  for (auto& subfolder : subfolders_)
259  subfolder->parents(sql_statement);
260  }
261 
262  void children(std::string& sql_statement) {
263  unsigned int parentid = this->getFather() ? this->getFather()->id() : id_;
264  std::stringstream s("");
265  s << "INSERT INTO children(self_id, parent_id, from_parent_count, from_parent_calls, from_parent_paths, pct) "
266  "VALUES("
267  << id_ << "," << parentid << "," << getMemory() << "," << getBins() - getEmptyBins() << "," << totalHistos_
268  << ",0"
269  << ");\n";
270  sql_statement.append(s.str());
271  for (auto& subfolder : subfolders_)
272  subfolder->children(sql_statement);
273  }
274 
275  void mainrows_cumulative(std::string& sql_statement) {
276  std::stringstream s("");
277  s << "INSERT INTO mainrows(id, symbol_id, self_count, cumulative_count, kids, self_calls, total_calls, self_paths, "
278  "total_paths, pct)"
279  << " VALUES(" << id_ << "," << id_ << "," << 0 << "," << getMemory() << ", 0," << getBins() - getEmptyBins()
280  << "," << getBins() << ", 0, " << getHistos() << ", 0);\n";
281  sql_statement.append(s.str());
282  }
283 
284  void summary(std::string& sql_statement) {
285  std::stringstream s("");
286  s << "INSERT INTO summary(counter, total_count, total_freq, tick_period) VALUES (\"BINS_LIVE\"," << getMemory()
287  << "," << getBins() << ", 1);\n";
288  sql_statement.append(s.str());
289  }
290 
291  void files(std::string& sql_statement) {
292  std::stringstream s("");
293  s << "INSERT INTO files(id, name) VALUES(" << id_ << ",\"" << folderName_ << "\");\n";
294  sql_statement.append(s.str());
295  }
296 
297 private:
298  unsigned int totalHistos_;
299  unsigned int totalBins_;
300  unsigned int totalEmptyBins_;
301  unsigned int totalMemory_;
302  unsigned int id_;
303  unsigned int level_;
306  std::vector<Folder*> subfolders_;
307 };
308 
312 class DQMStoreStats : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
313 public:
315  ~DQMStoreStats() override = default;
316 
318 
319 protected:
320  // BeginJob
321  void beginJob() override;
322 
323  // BeginRun
324  void beginRun(const edm::Run& r, const edm::EventSetup& c) override;
325 
326  // Fake Analyze
327  void analyze(const edm::Event& e, const edm::EventSetup& c) override;
328 
329  // DQM Client Diagnostic
330  void beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& c) override;
331  void endLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& c) override;
332 
333  // EndRun
334  void endRun(const edm::Run& r, const edm::EventSetup& c) override;
335 
336  // Endjob
337  void endJob() override;
338 
339 private:
340  int calcstats(int);
341  void calcIgProfDump(Folder&);
342  void dumpMemoryProfile();
343  std::pair<unsigned int, unsigned int> readMemoryEntry() const;
344  void print();
345 
348 
359 
362  int verbose_;
363 
364  std::vector<std::pair<time_t, unsigned int> > memoryHistoryVector_;
367  std::stringstream procFileName_;
368 
375 
376  // ---------- member data ----------
377 };
378 
379 using namespace std;
380 using namespace edm;
381 
382 template <class T>
383 static unsigned int getEmptyMetric(T* array, int lenx, int leny, int lenz) {
384  // len{x,y,z} MUST include under/overflow bins.
385  unsigned int len = lenx + leny + lenz;
386  unsigned int result = 0;
387  // start from 1 to exclude underflow bin. The comparison is accurate
388  // since it takes properly into account under/overflow bins, for all
389  // kind of histograms.
390  for (unsigned int i = 1; i < len; ++i) {
391  // get rid of under/overflow bins for x,y,z axis, to have a correct statistics.
392  if (i % (lenx - 1) == 0)
393  continue;
394  if (i % lenx == 0)
395  continue;
396  if (i % (lenx + leny - 1) == 0)
397  continue;
398  if (i % (lenx + leny) == 0)
399  continue;
400  if (i % (lenx + leny + lenz - 1) == 0)
401  continue;
402 
403  if (array[i] == 0)
404  result += 1;
405  }
406 
407  return result;
408 }
409 
410 //==================================================================//
411 //================= Constructor and Destructor =====================//
412 //==================================================================//
414  : subsystem_(""),
415  subfolder_(""),
416  nbinsglobal_(0),
417  nbinssubsys_(0),
418  nmeglobal_(0),
419  nmesubsys_(0),
420  maxbinsglobal_(0),
421  maxbinssubsys_(0),
422  maxbinsmeglobal_(""),
423  maxbinsmesubsys_(""),
424  statsdepth_(1),
425  pathnamematch_(""),
426  verbose_(0) {
427  parameters_ = ps;
429  statsdepth_ = ps.getUntrackedParameter<int>("statsDepth", statsdepth_);
430  verbose_ = ps.getUntrackedParameter<int>("verbose", verbose_);
431  dumpMemHistory_ = ps.getUntrackedParameter<bool>("dumpMemoryHistory", false);
432  runonendrun_ = ps.getUntrackedParameter<bool>("runOnEndRun", true);
433  runonendjob_ = ps.getUntrackedParameter<bool>("runOnEndJob", false);
434  runonendlumi_ = ps.getUntrackedParameter<bool>("runOnEndLumi", false);
435  runineventloop_ = ps.getUntrackedParameter<bool>("runInEventLoop", false);
436  dumpToFWJR_ = ps.getUntrackedParameter<bool>("dumpToFWJR", false);
437 
438  startingTime_ = time(nullptr);
439 }
440 
442  std::ofstream stream("dqm-bin-stats.sql");
443  stream << ""
444  " PRAGMA journal_mode=OFF;"
445  " PRAGMA count_changes=OFF;"
446  " DROP TABLE IF EXISTS files;"
447  " DROP TABLE IF EXISTS symbols;"
448  " DROP TABLE IF EXISTS mainrows;"
449  " DROP TABLE IF EXISTS children;"
450  " DROP TABLE IF EXISTS parents;"
451  " DROP TABLE IF EXISTS summary;"
452  " CREATE TABLE children ("
453  " self_id INTEGER CONSTRAINT self_exists REFERENCES mainrows(id),"
454  " parent_id INTEGER CONSTRAINT parent_exists REFERENCES mainrows(id),"
455  " from_parent_count INTEGER,"
456  " from_parent_calls INTEGER,"
457  " from_parent_paths INTEGER,"
458  " pct REAL"
459  " );"
460  " CREATE TABLE files ("
461  " id,"
462  " name TEXT"
463  " );"
464  " CREATE TABLE mainrows ("
465  " id INTEGER PRIMARY KEY,"
466  " symbol_id INTEGER CONSTRAINT symbol_id_exists REFERENCES symbols(id),"
467  " self_count INTEGER,"
468  " cumulative_count INTEGER,"
469  " kids INTEGER,"
470  " self_calls INTEGER,"
471  " total_calls INTEGER,"
472  " self_paths INTEGER,"
473  " total_paths INTEGER,"
474  " pct REAL"
475  " );"
476  " CREATE TABLE parents ("
477  " self_id INTEGER CONSTRAINT self_exists REFERENCES mainrows(id),"
478  " child_id INTEGER CONSTRAINT child_exists REFERENCES mainrows(id),"
479  " to_child_count INTEGER,"
480  " to_child_calls INTEGER,"
481  " to_child_paths INTEGER,"
482  " pct REAL"
483  " );"
484  " CREATE TABLE summary ("
485  " counter TEXT,"
486  " total_count INTEGER,"
487  " total_freq INTEGER,"
488  " tick_period REAL"
489  " );"
490  " CREATE TABLE symbols ("
491  " id,"
492  " name TEXT,"
493  " filename_id INTEGER CONSTRAINT file_id_exists REFERENCES files(id)"
494  " );"
495  " CREATE UNIQUE INDEX fileIndex ON files (id);"
496  " CREATE INDEX selfCountIndex ON mainrows(self_count);"
497  " CREATE UNIQUE INDEX symbolsIndex ON symbols (id);"
498  " CREATE INDEX totalCountIndex ON mainrows(cumulative_count);"
499  << std::endl;
500 
501  std::string sql_statement("");
502 
503  root.files(sql_statement);
504  root.symbols(sql_statement);
505  root.mainrows_cumulative(sql_statement);
506  root.summary(sql_statement);
507  VIterator<Folder*> subsystems = root.CreateIterator();
508  size_t ii = 0;
509  for (subsystems.First(); !subsystems.IsDone(); subsystems.Next(), ++ii) {
510  subsystems.CurrentItem()->mainrows(sql_statement);
511  subsystems.CurrentItem()->parents(sql_statement);
512  subsystems.CurrentItem()->children(sql_statement);
513  }
514  stream << sql_statement << std::endl;
515 }
516 
525  nbinsglobal_ = 0;
526  nbinssubsys_ = 0;
527  maxbinsglobal_ = 0;
528  maxbinssubsys_ = 0;
529  std::string path = "";
530  std::string subsystemname = "";
531  std::string subfoldername = "";
532  size_t subsysStringEnd = 0, subfolderStringBegin = 0, subfolderStringEnd = 0;
533 
534  std::vector<MonitorElement*> melist;
536 
537  Folder dbeFolder("root");
538  DQMStoreStatsTopLevel dqmStoreStatsTopLevel;
539 
540  // loop all ME
541  for (auto& it : melist) {
542  // consider only ME with getLumiFlag() == true ?
543  if (mode == DQMStoreStats::considerOnlyLumiProductME && !(it->getLumiFlag()))
544  continue;
545 
546  // figure out subsystem/subfolder names
547  const std::string& path = it->getPathname();
548 
549  subfolderStringBegin = 0;
550  Folder* curr = &dbeFolder;
551  while (true) {
552  subfolderStringEnd = path.find('/', subfolderStringBegin);
553  if (std::string::npos == subfolderStringEnd) {
554  curr = curr->cd(path.substr(subfolderStringBegin, path.size() - subfolderStringBegin));
555  break;
556  }
557  curr = curr->cd(path.substr(subfolderStringBegin, subfolderStringEnd - subfolderStringBegin));
558  subfolderStringBegin = ++subfolderStringEnd < path.size() ? subfolderStringEnd : path.size();
559  }
560 
561  // protection against ghost ME with empty paths
562  if (path.empty())
563  continue;
564 
565  subsysStringEnd = path.find('/', 0);
566  if (std::string::npos == subsysStringEnd)
567  subsysStringEnd = path.size(); // no subfolder
568 
569  // new subsystem?
570  if (path.substr(0, subsysStringEnd) != subsystemname) {
571  DQMStoreStatsSubsystem aSubsystem;
572  subsystemname = path.substr(0, subsysStringEnd);
573  aSubsystem.subsystemName_ = subsystemname;
574  dqmStoreStatsTopLevel.push_back(aSubsystem);
575  subfoldername = "";
576  }
577 
578  // get subfolder name (if there is one..)
579  if (path.size() == subsysStringEnd) {
580  // no subfolders in subsystem, make dummy
581  DQMStoreStatsSubfolder aSubfolder;
582  aSubfolder.subfolderName_ = subsystemname; // <-- for tagging this case
583  dqmStoreStatsTopLevel.back().push_back(aSubfolder);
584  }
585 
586  else {
587  // there is a subfolder, get its name
588  subfolderStringEnd = path.find('/', subsysStringEnd + 1);
589  if (std::string::npos == subfolderStringEnd)
590  subfolderStringEnd = path.size();
591 
592  // new subfolder?
593  if (path.substr(subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1) != subfoldername) {
594  subfoldername = path.substr(subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1);
595  DQMStoreStatsSubfolder aSubfolder;
596  aSubfolder.subfolderName_ = subfoldername;
597  dqmStoreStatsTopLevel.back().push_back(aSubfolder);
598  }
599  }
600 
601  // shortcut
602  DQMStoreStatsSubfolder& currentSubfolder = dqmStoreStatsTopLevel.back().back();
603 
604  switch (it->kind()) {
605  // one-dim ME
607  currentSubfolder.AddBinsF(it->getNbinsX(), getEmptyMetric(it->getTH1F()->GetArray(), it->getTH1F()->fN, 0, 0));
608  curr->update(it->getNbinsX(),
609  getEmptyMetric(it->getTH1F()->GetArray(), it->getTH1F()->fN, 0, 0),
610  it->getNbinsX() * sizeof(float));
611  break;
613  currentSubfolder.AddBinsS(it->getNbinsX(), getEmptyMetric(it->getTH1S()->GetArray(), it->getTH1S()->fN, 0, 0));
614  curr->update(it->getNbinsX(),
615  getEmptyMetric(it->getTH1S()->GetArray(), it->getTH1S()->fN, 0, 0),
616  it->getNbinsX() * sizeof(short));
617  break;
619  currentSubfolder.AddBinsD(it->getNbinsX(), getEmptyMetric(it->getTH1D()->GetArray(), it->getTH1D()->fN, 0, 0));
620  curr->update(it->getNbinsX(),
621  getEmptyMetric(it->getTH1D()->GetArray(), it->getTH1D()->fN, 0, 0),
622  it->getNbinsX() * sizeof(double));
623  break;
625  currentSubfolder.AddBinsI(it->getNbinsX(), getEmptyMetric(it->getTH1I()->GetArray(), it->getTH1I()->fN, 0, 0));
626  curr->update(it->getNbinsX(),
627  getEmptyMetric(it->getTH1I()->GetArray(), it->getTH1I()->fN, 0, 0),
628  it->getNbinsX() * sizeof(int));
629  break;
631  currentSubfolder.AddBinsD(it->getNbinsX(),
632  getEmptyMetric(it->getTProfile()->GetArray(), it->getTProfile()->fN, 0, 0));
633  curr->update(it->getNbinsX(),
634  getEmptyMetric(it->getTProfile()->GetArray(), it->getTProfile()->fN, 0, 0),
635  it->getNbinsX() * sizeof(double));
636  break;
637 
638  // two-dim ME
640  currentSubfolder.AddBinsF(
641  it->getNbinsX() * it->getNbinsY(),
642  getEmptyMetric(it->getTH2F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
643  curr->update(it->getNbinsX() * it->getNbinsY(),
644  getEmptyMetric(it->getTH2F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
645  it->getNbinsX() * it->getNbinsY() * sizeof(float));
646  break;
648  currentSubfolder.AddBinsS(
649  it->getNbinsX() * it->getNbinsY(),
650  getEmptyMetric(it->getTH2S()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
651  curr->update(it->getNbinsX() * it->getNbinsY(),
652  getEmptyMetric(it->getTH2S()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
653  it->getNbinsX() * it->getNbinsY() * sizeof(short));
654  break;
656  currentSubfolder.AddBinsD(
657  it->getNbinsX() * it->getNbinsY(),
658  getEmptyMetric(it->getTH2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
659  curr->update(it->getNbinsX() * it->getNbinsY(),
660  getEmptyMetric(it->getTH2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
661  it->getNbinsX() * it->getNbinsY() * sizeof(double));
662  break;
664  currentSubfolder.AddBinsI(
665  it->getNbinsX() * it->getNbinsY(),
666  getEmptyMetric(it->getTH2I()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
667  curr->update(it->getNbinsX() * it->getNbinsY(),
668  getEmptyMetric(it->getTH2I()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
669  it->getNbinsX() * it->getNbinsY() * sizeof(int));
670  break;
672  currentSubfolder.AddBinsD(
673  it->getNbinsX() * it->getNbinsY(),
674  getEmptyMetric(it->getTProfile2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0));
675  curr->update(it->getNbinsX() * it->getNbinsY(),
676  getEmptyMetric(it->getTProfile2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0),
677  it->getNbinsX() * it->getNbinsY() * sizeof(double));
678  break;
679 
680  // three-dim ME
682  currentSubfolder.AddBinsF(
683  it->getNbinsX() * it->getNbinsY() * it->getNbinsZ(),
684  getEmptyMetric(it->getTH3F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, it->getNbinsZ() + 2));
685  curr->update(
686  it->getNbinsX() * it->getNbinsY() * it->getNbinsZ(),
687  getEmptyMetric(it->getTH3F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, it->getNbinsZ() + 2),
688  it->getNbinsX() * it->getNbinsY() * it->getNbinsZ() * sizeof(float));
689  break;
690 
691  default: {
692  }
693  // here we have a DQM_KIND_INVALID, DQM_KIND_INT, DQM_KIND_REAL or DQM_KIND_STRING
694  // which we don't care much about. Alternatively:
695 
696  // std::cerr << "[DQMStoreStats::calcstats] ** WARNING: monitor element of kind: "
697  // << (*it)->kind() << ", name: \"" << (*it)->getName() << "\"\n"
698  // << " in path: \"" << path << "\" not considered." << std::endl;
699  }
700  }
701 
703  calcIgProfDump(dbeFolder);
704 
705  // OUTPUT
706 
707  std::cout << endl;
708  std::cout << "==========================================================================================="
709  << std::endl;
710  std::cout << "[DQMStoreStats::calcstats] -- Dumping stats results ";
712  std::cout << "FOR ALL ME" << std::endl;
714  std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl;
715  std::cout << "==========================================================================================="
716  << std::endl;
717  std::cout << endl;
718 
719  std::cout << "------------------------------------------------------------------------------------------"
720  << std::endl;
721  std::cout << "Configuration:" << std::endl;
722  std::cout << "------------------------------------------------------------------------------------------"
723  << std::endl;
724  std::cout << " > running ";
725  if (runonendrun_)
726  std::cout << "on run end." << std::endl;
727  if (runonendlumi_)
728  std::cout << "on lumi end." << std::endl;
729  if (runonendjob_)
730  std::cout << "on job end." << std::endl;
731  if (runineventloop_)
732  std::cout << "in event loop." << std::endl;
733  std::cout << " > pathNameMatch = \"" << pathnamematch_ << "\"" << std::endl;
734  std::cout << std::endl;
735 
736  // dump folder structure
737  std::cout << "------------------------------------------------------------------------------------------"
738  << std::endl;
739  std::cout << "Top level folder tree:" << std::endl;
740  std::cout << "------------------------------------------------------------------------------------------"
741  << std::endl;
742  for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) {
743  std::cout << it0->subsystemName_ << " (subsystem)" << std::endl;
744 
745  for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) {
746  std::cout << " |--> " << it1->subfolderName_ << " (subfolder)" << std::endl;
747  }
748  }
749 
750  // dump mem/bin table
751 
752  unsigned int overallNHistograms = 0, overallNBins = 0, overallNEmptyBins = 0, overallNBytes = 0;
753 
754  std::cout << std::endl;
755  std::cout << "------------------------------------------------------------------------------------------"
756  << std::endl;
757  std::cout << "Detailed ressource usage information ";
759  std::cout << "FOR ALL ME" << std::endl;
761  std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl;
762  std::cout << "------------------------------------------------------------------------------------------"
763  << std::endl;
764  std::cout << "subsystem/folder histograms bins Empty bins Empty/Total "
765  "bins per MB kB per"
766  << std::endl;
767  std::cout << " (total) (total) (total) "
768  "histogram (total) histogram "
769  << std::endl;
770  std::cout << "------------------------------------------------------------------------------------------"
771  << std::endl;
772  for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) {
773  std::cout << it0->subsystemName_ << std::endl;
774 
775  unsigned int nHistograms = 0, nBins = 0, nEmptyBins = 0, nBytes = 0;
776 
777  for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) {
778  // fixed-size working copy
779  std::string thisSubfolderName(it1->subfolderName_);
780  if (thisSubfolderName.size() > 30) {
781  thisSubfolderName.resize(30);
782  thisSubfolderName.replace(thisSubfolderName.size() - 3, 3, 3, '.');
783  }
784 
785  std::cout << " -> " << std::setw(30) << std::left << thisSubfolderName;
786  std::cout << std::setw(14) << std::right << it1->totalHistos_;
787  std::cout << std::setw(14) << std::right << it1->totalBins_;
788  std::cout << std::setw(14) << std::right << it1->totalEmptyBins_;
789  std::cout << std::setw(14) << std::right << std::setprecision(3)
790  << (float)it1->totalEmptyBins_ / (float)it1->totalBins_;
791 
792  // bins/histogram, need to catch nan if histos=0
793  if (it1->totalHistos_) {
794  std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalBins_ / float(it1->totalHistos_);
795  } else
796  std::cout << std::setw(14) << std::right << "-";
797 
798  std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalMemory_ / 1024. / 1024.;
799 
800  // mem/histogram, need to catch nan if histos=0
801  if (it1->totalHistos_) {
802  std::cout << std::setw(14) << std::right << std::setprecision(3)
803  << it1->totalMemory_ / 1024. / it1->totalHistos_;
804  } else
805  std::cout << std::setw(14) << std::right << "-";
806 
807  std::cout << std::endl;
808 
809  // collect totals
810  nHistograms += it1->totalHistos_;
811  nBins += it1->totalBins_;
812  nEmptyBins += it1->totalEmptyBins_;
813  nBytes += it1->totalMemory_;
814  }
815 
816  overallNHistograms += nHistograms;
817  overallNBins += nBins;
818  overallNEmptyBins += nEmptyBins;
819  overallNBytes += nBytes;
820 
821  // display totals
822  std::cout << " " << std::setw(30) << std::left << "SUBSYSTEM TOTAL";
823  std::cout << std::setw(14) << std::right << nHistograms;
824  std::cout << std::setw(14) << std::right << nBins;
825  std::cout << std::setw(14) << std::right << nEmptyBins;
826  std::cout << std::setw(14) << std::right << (float)nEmptyBins / (float)nBins;
827  std::cout << std::setw(14) << std::right << std::setprecision(3) << nBins / float(nHistograms);
828  std::cout << std::setw(14) << std::right << std::setprecision(3) << nBytes / 1024. / 1000.;
829  std::cout << std::setw(14) << std::right << std::setprecision(3) << nBytes / 1024. / nHistograms;
830  std::cout << std::endl;
831 
832  std::cout << ".........................................................................................."
833  << std::endl;
834  }
835 
836  // dump total
837  std::cout << std::endl;
838  std::cout << "------------------------------------------------------------------------------------------"
839  << std::endl;
840  std::cout << "Grand total ";
842  std::cout << "FOR ALL ME:" << std::endl;
844  std::cout << "FOR LUMI PRODUCTS ONLY:" << std::endl;
845  std::cout << "------------------------------------------------------------------------------------------"
846  << std::endl;
847  std::cout << "Number of subsystems: " << dqmStoreStatsTopLevel.size() << std::endl;
848  std::cout << "Total number of histograms: " << overallNHistograms << " with: " << overallNBins << " bins alltogether"
849  << std::endl;
850  std::cout << "Total memory occupied by histograms (excl. overhead): " << overallNBytes / 1024. / 1000. << " MB"
851  << std::endl;
852 
853  std::cout << endl;
854  std::cout << "==========================================================================================="
855  << std::endl;
856  std::cout << "[DQMStoreStats::calcstats] -- End of output ";
858  std::cout << "FOR ALL ME." << std::endl;
860  std::cout << "FOR LUMI PRODUCTS ONLY." << std::endl;
861  std::cout << "==========================================================================================="
862  << std::endl;
863  std::cout << endl;
864 
865  // Put together a simplified version of the complete dump that is
866  // sent to std::cout. Just dump the very basic information,
867  // i.e. summary for each folder, both for run and LS products.
868  if (dumpToFWJR_) {
870  // Do not even try if the FWJR service is not available.
871  if (!jr.isAvailable())
872  return 0;
873  // Prepare appropriate map to store FWJR output.
874  std::map<std::string, std::string> jrInfo;
875  unsigned int overallNHistograms = 0, overallNBins = 0, overallNBytes = 0;
876 
877  jrInfo["Source"] = "DQMServices/Components";
878  jrInfo["FileClass"] = "DQMStoreStats";
879  if (runonendrun_)
880  jrInfo["DumpType"] = "EndRun";
881  if (runonendlumi_)
882  jrInfo["DumpType"] = "EndLumi";
883  if (runonendjob_)
884  jrInfo["DumpType"] = "EndJob";
885  if (runineventloop_)
886  jrInfo["DumpType"] = "EventLoop";
888  jrInfo["Type"] = "RunProduct";
890  jrInfo["Type"] = "LumiProduct";
891 
892  jrInfo["pathNameMatch"] = pathnamematch_;
893 
894  for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) {
895  unsigned int nHistograms = 0, nBins = 0, nEmptyBins = 0, nBytes = 0;
896  for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) {
897  // collect totals
898  nHistograms += it1->totalHistos_;
899  nBins += it1->totalBins_;
900  nEmptyBins += it1->totalEmptyBins_;
901  nBytes += it1->totalMemory_;
902  }
903  overallNHistograms += nHistograms;
904  overallNBins += nBins;
905  overallNBytes += nBytes;
906  std::stringstream iss("");
907  iss << nHistograms;
908  jrInfo[it0->subsystemName_ + std::string("_h")] = iss.str();
909  iss.str("");
910  iss << nBins;
911  jrInfo[it0->subsystemName_ + std::string("_b")] = iss.str();
912  iss.str("");
913  iss << nEmptyBins;
914  jrInfo[it0->subsystemName_ + std::string("_be")] = iss.str();
915  iss.str("");
916  iss << ((float)nEmptyBins / (float)nBins);
917  jrInfo[it0->subsystemName_ + std::string("_fbe")] = iss.str();
918  iss.str("");
919  iss << ((float)nBins / (float)nHistograms);
920  jrInfo[it0->subsystemName_ + std::string("_b_h")] = iss.str();
921  iss.str("");
922  iss << nBytes / 1024. / 1024.;
923  jrInfo[it0->subsystemName_ + std::string("_MB")] = iss.str();
924  iss.str("");
925  iss << nBytes / 1024. / nHistograms;
926  jrInfo[it0->subsystemName_ + std::string("_Kb_h")] = iss.str();
927  }
928  jr->reportAnalysisFile("DQMStatsReport", jrInfo);
929  }
930 
931  return 0;
932 }
933 
938  std::cout << std::endl;
939  std::cout << "------------------------------------------------------------------------------------------"
940  << std::endl;
941  std::cout << "Memory profile:" << std::endl;
942  std::cout << "------------------------------------------------------------------------------------------"
943  << std::endl;
944 
945  // determine virtual memory maximum
946  std::pair<time_t, unsigned int> maxItem(0, 0);
947  for (auto it = memoryHistoryVector_.begin(); it < memoryHistoryVector_.end(); ++it) {
948  if (it->second > maxItem.second) {
949  maxItem = *it;
950  }
951  }
952 
953  std::stringstream rootOutputFileName;
954  rootOutputFileName << "dqmStoreStats_memProfile_" << getpid() << ".root";
955 
956  // dump memory history to root file
958  TFile outputFile(rootOutputFileName.str().c_str(), "RECREATE");
959 
960  int aTime;
961  float aMb;
962 
963  TTree memHistoryTree("dqmstorestats_memhistory", "memory history");
964  memHistoryTree.Branch("seconds", &aTime, "seconds/I");
965  memHistoryTree.Branch("megabytes", &aMb, "megabytes/F");
966  for (auto it = memoryHistoryVector_.begin(); it < memoryHistoryVector_.end(); ++it) {
967  aTime = it->first - startingTime_;
968  aMb = it->second / 1000.;
969  memHistoryTree.Fill();
970  }
971 
972  outputFile.Write();
973  outputFile.Close();
974  }
975 
976  std::cout << "Approx. maximum total virtual memory size of job: ";
978  std::cout << maxItem.second / 1000. << " MB (reached " << maxItem.first - startingTime_
979  << " sec. after constructor called)," << std::endl;
980  std::cout << " memory history written to: " << rootOutputFileName.str() << " (" << memoryHistoryVector_.size()
981  << " samples)" << std::endl;
982  } else {
983  std::cout << "(could not be determined)" << std::endl;
984  }
985 
986  std::cout << std::endl << std::endl;
987 }
988 
993  // subsystem info printout
994  std::cout << " ---------- " << subsystem_ << " ---------- " << std::endl;
995  std::cout << " " << subfolder_ << ": ";
996  std::cout << nmesubsys_ << " histograms with " << nbinssubsys_ << " bins. ";
997  if (nmesubsys_ > 0)
998  std::cout << nbinssubsys_ / nmesubsys_ << " bins/histogram ";
999  std::cout << std::endl;
1000  std::cout << " Largest histogram: " << maxbinsmesubsys_ << " with " << maxbinssubsys_ << " bins." << std::endl;
1001 }
1002 
1006 std::pair<unsigned int, unsigned int> DQMStoreStats::readMemoryEntry() const {
1007  // see if initial test reading was successful
1009  std::ifstream procFile(procFileName_.str().c_str(), ios::in);
1010 
1011  std::string readBuffer("");
1012  unsigned int memSize = 0;
1013 
1014  // scan procfile
1015  while (!procFile.eof()) {
1016  procFile >> readBuffer;
1017  if (std::string("VmSize:") == readBuffer) {
1018  procFile >> memSize;
1019  break;
1020  }
1021  }
1022 
1023  procFile.close();
1024  return std::pair<time_t, unsigned int>(time(nullptr), memSize);
1025  }
1026 
1027  return std::pair<time_t, unsigned int>(0, 0);
1028 }
1029 
1030 //==================================================================//
1031 //========================= beginJob ===============================//
1032 //==================================================================//
1036 
1037  // access the proc/ folder for memory information
1038  procFileName_ << "/proc/" << getpid() << "/status";
1039 
1040  // open for a test
1041  std::ifstream procFile(procFileName_.str().c_str(), ios::in);
1042 
1043  if (procFile.good()) {
1045  } else {
1046  std::cerr << " [DQMStoreStats::beginJob] ** WARNING: could not open file: " << procFileName_.str() << std::endl;
1047  std::cerr << " Total memory profile will not be available." << std::endl;
1048  isOpenProcFileSuccessful_ = false;
1049  }
1050 
1051  procFile.close();
1052 }
1053 
1054 //==================================================================//
1055 //========================= beginRun ===============================//
1056 //==================================================================//
1058 
1059 //==================================================================//
1060 //==================== analyse (takes each event) ==================//
1061 //==================================================================//
1062 void DQMStoreStats::analyze(const Event& iEvent, const EventSetup& iSetup) {
1063  //now read virtual memory size from proc folder
1064  memoryHistoryVector_.emplace_back(readMemoryEntry());
1065 
1066  if (runineventloop_) {
1070  }
1071 }
1072 
1073 //==================================================================//
1074 //========================= endLuminosityBlock =====================//
1075 //==================================================================//
1077  if (runonendlumi_) {
1081  }
1082 }
1083 
1084 //==================================================================//
1085 //======================= beginLuminosityBlock =====================//
1086 //==================================================================//
1088 
1089 //==================================================================//
1090 //============================= endRun =============================//
1091 //==================================================================//
1093  if (runonendrun_) {
1097  }
1098 }
1099 
1100 //==================================================================//
1101 //============================= endJob =============================//
1102 //==================================================================//
1104  if (runonendjob_) {
1108  }
1109 }
1110 
std::string subfolderName_
std::pair< unsigned int, unsigned int > readMemoryEntry() const
virtual void Next()=0
virtual bool IsDone() const =0
DQMStore * dbe_
unsigned int getHistos()
void AddBinsS(unsigned int nBins, unsigned int nEmptyBins)
void endJob() override
~VIterator() override=default
DQMStoreStatsSubsystem()=default
void update(unsigned int bins, unsigned int empty, unsigned int memory)
virtual Item CurrentItem() const =0
virtual ~Iterator()=default
unsigned int level()
void AddBinsD(unsigned int nBins, unsigned int nEmptyBins)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual void First()=0
VIterator(const std::vector< Item > *aVector)
std::vector< std::pair< time_t, unsigned int > > memoryHistoryVector_
void AddBinsI(unsigned int nBins, unsigned int nEmptyBins)
std::string subsystemName_
void add(Folder *f)
Folder(std::string name)
void beginJob() override
unsigned int totalBins_
void mainrows_cumulative(std::string &sql_statement)
unsigned int getEmptyBins()
VIterator< Folder * > CreateIterator()
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
time_t startingTime_
void beginLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &c) override
~DQMStoreStats() override=default
virtual int getIndex()
unsigned int totalMemory_
void summary(std::string &sql_statement)
T getUntrackedParameter(std::string const &, T const &) const
dqm::reco::DQMStore DQMStore
std::string subsystem_
std::string maxbinsmeglobal_
void endRun(const edm::Run &r, const edm::EventSetup &c) override
void mainrows(std::string &sql_statement)
DQMStoreStatsTopLevel()=default
std::vector< Folder * > subfolders_
int calcstats(int)
int iEvent
Definition: GenABIO.cc:224
const std::string & name()
unsigned int getBins()
bool isOpenProcFileSuccessful_
unsigned int totalEmptyBins_
void setLevel(unsigned int value)
unsigned int totalEmptyBins_
Folder * getFather()
virtual std::vector< dqm::harvesting::MonitorElement * > getAllContents(std::string const &path) const
Definition: DQMStore.cc:609
void endLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &c) override
Item CurrentItem() const override
std::string pathnamematch_
std::string maxbinsmesubsys_
double f[11][100]
DQMStoreStats(const edm::ParameterSet &)
void files(std::string &sql_statement)
unsigned int id()
Definition: value.py:1
void Next() override
void setFather(Folder *e)
void dump(std::string indent)
unsigned int index
Folder * father_
ii
Definition: cuy.py:589
virtual int size()
unsigned int totalHistos_
void analyze(const edm::Event &e, const edm::EventSetup &c) override
unsigned int level_
void parents(std::string &sql_statement)
bool IsDone() const override
dqm::legacy::MonitorElement MonitorElement
static unsigned int getId()
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_
unsigned int totalMemory_
void AddBinsF(unsigned int nBins, unsigned int nEmptyBins)
void children(std::string &sql_statement)
HLT enums.
void reportAnalysisFile(std::string const &fileName, std::map< std::string, std::string > const &fileData)
Definition: JobReport.cc:473
void calcIgProfDump(Folder &)
void beginRun(const edm::Run &r, const edm::EventSetup &c) override
unsigned int totalHistos_
bool isAvailable() const
Definition: Service.h:40
const std::vector< Item > * vector_
unsigned int getMemory()
std::stringstream procFileName_
tmp
align.sh
Definition: createJobs.py:716
long double T
void dumpMemoryProfile()
void symbols(std::string &sql_statement)
unsigned int id_
Iterator()=default
def move(src, dest)
Definition: eostools.py:511
std::string folderName_
Definition: Run.h:45
void setId(unsigned int id)