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