00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "DQMServices/Components/src/DQMStoreStats.h"
00013 #include "FWCore/ServiceRegistry/interface/Service.h"
00014
00015 using namespace std;
00016 using namespace edm;
00017
00018
00019
00020
00021 DQMStoreStats::DQMStoreStats( const edm::ParameterSet& ps )
00022 : subsystem_ (""),
00023 subfolder_ (""),
00024 nbinsglobal_ (0),
00025 nbinssubsys_ (0),
00026 nmeglobal_ (0),
00027 nmesubsys_ (0),
00028 maxbinsglobal_ (0),
00029 maxbinssubsys_ (0),
00030 maxbinsmeglobal_ (""),
00031 maxbinsmesubsys_ (""),
00032 statsdepth_ (1),
00033 pathnamematch_ ("*"),
00034 verbose_ (0)
00035 {
00036 parameters_ = ps;
00037 pathnamematch_ = ps.getUntrackedParameter<std::string>( "pathNameMatch", pathnamematch_ );
00038 statsdepth_ = ps.getUntrackedParameter<int>( "statsDepth", statsdepth_ );
00039 verbose_ = ps.getUntrackedParameter<int>( "verbose", verbose_ );
00040 dumpMemHistory_ = ps.getUntrackedParameter<bool>( "dumpMemoryHistory", false );
00041 runonendrun_ = ps.getUntrackedParameter<bool>( "runOnEndRun", true );
00042 runonendjob_ = ps.getUntrackedParameter<bool>( "runOnEndJob", false );
00043 runonendlumi_ = ps.getUntrackedParameter<bool>( "runOnEndLumi", false );
00044 runineventloop_ = ps.getUntrackedParameter<bool>( "runInEventLoop", false );
00045
00046 startingTime_ = time( 0 );
00047
00048 }
00049
00050 DQMStoreStats::~DQMStoreStats(){
00051 }
00052
00053
00060 int DQMStoreStats::calcstats( int mode = DQMStoreStats::considerAllME ) {
00061
00063 nbinsglobal_ = 0;
00064 nbinssubsys_ = 0;
00065 maxbinsglobal_ = 0;
00066 maxbinssubsys_ = 0;
00067 std::string path = "";
00068 std::string subsystemname = "";
00069 std::string subfoldername = "";
00070 size_t subsysStringEnd = 0, subfolderStringEnd = 0;
00071
00072
00073 std::vector<MonitorElement*> melist;
00074 melist = dbe_->getMatchingContents( pathnamematch_ );
00075
00076 DQMStoreStatsTopLevel dqmStoreStatsTopLevel;
00077
00078
00079 typedef std::vector <MonitorElement*>::iterator meIt;
00080 for(meIt it = melist.begin(); it != melist.end(); ++it) {
00081
00082
00083 if( mode == DQMStoreStats::considerOnlyLumiProductME &&
00084 !( (*it)->getLumiFlag() ) ) continue;
00085
00086
00087 std::string path = (*it)->getPathname();
00088
00089
00090 if( 0 == path.size() ) continue;
00091
00092 subsysStringEnd = path.find( '/', 0 );
00093 if( std::string::npos == subsysStringEnd ) subsysStringEnd = path.size();
00094
00095
00096 if( path.substr( 0, subsysStringEnd ) != subsystemname ) {
00097 DQMStoreStatsSubsystem aSubsystem;
00098 subsystemname = path.substr( 0, subsysStringEnd );
00099 aSubsystem.subsystemName_ = subsystemname;
00100 dqmStoreStatsTopLevel.push_back( aSubsystem );
00101 }
00102
00103
00104 if( path.size() == subsysStringEnd ) {
00105
00106 DQMStoreStatsSubfolder aSubfolder;
00107 aSubfolder.subfolderName_ = subsystemname;
00108 dqmStoreStatsTopLevel.back().push_back( aSubfolder );
00109 }
00110
00111 else {
00112
00113
00114 subfolderStringEnd = path.find( '/', subsysStringEnd + 1 );
00115 if( std::string::npos == subfolderStringEnd ) subfolderStringEnd = path.size();
00116
00117
00118 if( path.substr( subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1 ) != subfoldername ) {
00119 subfoldername = path.substr( subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1 );
00120 DQMStoreStatsSubfolder aSubfolder;
00121 aSubfolder.subfolderName_ = subfoldername;
00122 dqmStoreStatsTopLevel.back().push_back( aSubfolder );
00123 }
00124
00125 }
00126
00127
00128 DQMStoreStatsSubfolder& currentSubfolder = dqmStoreStatsTopLevel.back().back();
00129
00130 switch( (*it)->kind() ) {
00131
00132
00133 case MonitorElement::DQM_KIND_TH1F: currentSubfolder.AddBinsF( (*it)->getNbinsX() ); break;
00134 case MonitorElement::DQM_KIND_TH1S: currentSubfolder.AddBinsS( (*it)->getNbinsX() ); break;
00135 case MonitorElement::DQM_KIND_TH1D: currentSubfolder.AddBinsD( (*it)->getNbinsX() ); break;
00136 case MonitorElement::DQM_KIND_TPROFILE: currentSubfolder.AddBinsD( (*it)->getNbinsX() ); break;
00137
00138
00139 case MonitorElement::DQM_KIND_TH2F: currentSubfolder.AddBinsF( (*it)->getNbinsX() * (*it)->getNbinsY() ); break;
00140 case MonitorElement::DQM_KIND_TH2S: currentSubfolder.AddBinsS( (*it)->getNbinsX() * (*it)->getNbinsY() ); break;
00141 case MonitorElement::DQM_KIND_TH2D: currentSubfolder.AddBinsD( (*it)->getNbinsX() * (*it)->getNbinsY() ); break;
00142 case MonitorElement::DQM_KIND_TPROFILE2D: currentSubfolder.AddBinsD( (*it)->getNbinsX() * (*it)->getNbinsY() ); break;
00143
00144
00145 case MonitorElement::DQM_KIND_TH3F:
00146 currentSubfolder.AddBinsF( (*it)->getNbinsX() * (*it)->getNbinsY() * (*it)->getNbinsZ() ); break;
00147
00148 default: {}
00149
00150
00151
00152
00153
00154
00155 }
00156
00157 }
00158
00159
00160
00161
00162
00163 std::cout << endl;
00164 std::cout << "===========================================================================================" << std::endl;
00165 std::cout << "[DQMStoreStats::calcstats] -- Dumping stats results ";
00166 if( mode == DQMStoreStats::considerAllME ) std::cout << "FOR ALL ME" << std::endl;
00167 else if( mode == DQMStoreStats::considerOnlyLumiProductME ) std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl;
00168 std::cout << "===========================================================================================" << std::endl;
00169 std::cout << endl;
00170
00171 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00172 std::cout << "Configuration:" << std::endl;
00173 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00174 std::cout << " > running ";
00175 if (runonendrun_) std::cout << "on run end." << std::endl;
00176 if (runonendlumi_) std::cout << "on lumi end." << std::endl;
00177 if (runonendjob_) std::cout << "on job end." << std::endl;
00178 if (runineventloop_) std::cout << "in event loop." << std::endl;
00179 std::cout << " > pathNameMatch = \"" << pathnamematch_ << "\"" << std::endl;
00180 std::cout << std::endl;
00181
00182
00183 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00184 std::cout << "Top level folder tree:" << std::endl;
00185 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00186 for( DQMStoreStatsTopLevel::const_iterator it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0 ) {
00187 std::cout << it0->subsystemName_ << " (subsystem)" << std::endl;
00188
00189 for( DQMStoreStatsSubsystem::const_iterator it1 = it0->begin(); it1 < it0->end(); ++it1 ) {
00190 std::cout << " |--> " << it1->subfolderName_ << " (subfolder)" << std::endl;
00191 }
00192
00193 }
00194
00195
00196
00197 unsigned int overallNHistograms = 0, overallNBins = 0, overallNBytes = 0;
00198
00199 std::cout << std::endl;
00200 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00201 std::cout << "Detailed ressource usage information ";
00202 if( mode == DQMStoreStats::considerAllME ) std::cout << "FOR ALL ME" << std::endl;
00203 else if( mode == DQMStoreStats::considerOnlyLumiProductME ) std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl;
00204 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00205 std::cout << "subsystem/folder histograms bins bins per MB kB per" << std::endl;
00206 std::cout << " (total) (total) histogram (total) histogram " << std::endl;
00207 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00208 for( DQMStoreStatsTopLevel::const_iterator it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0 ) {
00209 std::cout << it0->subsystemName_ << std::endl;
00210
00211 unsigned int nHistograms = 0, nBins = 0, nBytes = 0;
00212
00213 for( DQMStoreStatsSubsystem::const_iterator it1 = it0->begin(); it1 < it0->end(); ++it1 ) {
00214
00215
00216 std::string thisSubfolderName( it1->subfolderName_ );
00217 if( thisSubfolderName.size() > 30 ) {
00218 thisSubfolderName.resize( 30 );
00219 thisSubfolderName.replace( thisSubfolderName.size() - 3, 3, 3, '.' );
00220 }
00221
00222 std::cout << " -> " << std::setw( 30 ) << std::left << thisSubfolderName;
00223 std::cout << std::setw( 7 ) << std::right << it1->totalHistos_;
00224 std::cout << std::setw( 12 ) << std::right << it1->totalBins_;
00225
00226
00227 if( it1->totalHistos_ ) {
00228 std::cout << std::setw( 12 ) << std::right << std::setprecision( 3 ) << it1->totalBins_ / float( it1->totalHistos_ );
00229 }
00230 else std::cout << std::setw( 12 ) << std::right << "-";
00231
00232 std::cout << std::setw( 12 ) << std::right << std::setprecision( 3 ) << it1->totalMemory_ / 1024. / 1000.;
00233
00234
00235 if( it1->totalHistos_ ) {
00236 std::cout << std::setw( 12 ) << std::right << std::setprecision( 3 ) << it1->totalMemory_ / 1024. / it1->totalHistos_;
00237 }
00238 else std::cout << std::setw( 12 ) << std::right << "-";
00239
00240 std::cout << std::endl;
00241
00242
00243 nHistograms += it1->totalHistos_;
00244 nBins += it1->totalBins_;
00245 nBytes += it1->totalMemory_;
00246
00247 }
00248
00249
00250
00251
00252 overallNHistograms += nHistograms;
00253 overallNBins += nBins;
00254 overallNBytes += nBytes;
00255
00256
00257 std::cout << " " << std::setw( 30 ) << std::left << "SUBSYSTEM TOTAL";
00258 std::cout << std::setw( 7 ) << std::right << nHistograms;
00259 std::cout << std::setw( 12 ) << std::right << nBins;
00260 std::cout << std::setw( 12 ) << std::right << std::setprecision( 3 ) << nBins / float( nHistograms );
00261 std::cout << std::setw( 12 ) << std::right << std::setprecision( 3 ) << nBytes / 1024. / 1000.;
00262 std::cout << std::setw( 12 ) << std::right << std::setprecision( 3 ) << nBytes / 1024. / nHistograms;
00263 std::cout << std::endl;
00264
00265 std::cout << ".........................................................................................." << std::endl;
00266
00267 }
00268
00269
00270
00271 std::cout << std::endl;
00272 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00273 std::cout << "Grand total ";
00274 if( mode == DQMStoreStats::considerAllME ) std::cout << "FOR ALL ME:" << std::endl;
00275 else if( mode == DQMStoreStats::considerOnlyLumiProductME ) std::cout << "FOR LUMI PRODUCTS ONLY:" << std::endl;
00276 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00277 std::cout << "Number of subsystems: " << dqmStoreStatsTopLevel.size() << std::endl;
00278 std::cout << "Total number of histograms: " << overallNHistograms << " with: " << overallNBins << " bins alltogether" << std::endl;
00279 std::cout << "Total memory occupied by histograms (excl. overhead): " << overallNBytes / 1024. / 1000. << " MB" << std::endl;
00280
00281
00282
00283 std::cout << endl;
00284 std::cout << "===========================================================================================" << std::endl;
00285 std::cout << "[DQMStoreStats::calcstats] -- End of output ";
00286 if( mode == DQMStoreStats::considerAllME ) std::cout << "FOR ALL ME." << std::endl;
00287 else if( mode == DQMStoreStats::considerOnlyLumiProductME ) std::cout << "FOR LUMI PRODUCTS ONLY." << std::endl;
00288 std::cout << "===========================================================================================" << std::endl;
00289 std::cout << endl;
00290
00291 return 0;
00292
00293 }
00294
00295
00296
00300 void DQMStoreStats::dumpMemoryProfile( void ) {
00301
00302 std::cout << std::endl;
00303 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00304 std::cout << "Memory profile:" << std::endl;
00305 std::cout << "------------------------------------------------------------------------------------------" << std::endl;
00306
00307
00308 std::pair<time_t, unsigned int> maxItem( 0, 0 );
00309 for( std::vector<std::pair<time_t, unsigned int> >::const_iterator it = memoryHistoryVector_.begin();
00310 it < memoryHistoryVector_.end(); ++it ) {
00311 if( it->second > maxItem.second ) {
00312 maxItem = *it;
00313 }
00314 }
00315
00316 std::stringstream rootOutputFileName;
00317 rootOutputFileName << "dqmStoreStats_memProfile_" << getpid() << ".root";
00318
00319
00320 if( dumpMemHistory_ && isOpenProcFileSuccessful_ ) {
00321
00322 TFile outputFile( rootOutputFileName.str().c_str(), "RECREATE" );
00323
00324 int aTime;
00325 float aMb;
00326
00327 TTree memHistoryTree( "dqmstorestats_memhistory", "memory history" );
00328 memHistoryTree.Branch( "seconds", &aTime, "seconds/I" );
00329 memHistoryTree.Branch( "megabytes", &aMb, "megabytes/F" );
00330 for( std::vector<std::pair<time_t, unsigned int> >::const_iterator it = memoryHistoryVector_.begin();
00331 it < memoryHistoryVector_.end(); ++it ) {
00332 aTime = it->first - startingTime_;
00333 aMb = it->second / 1000.;
00334 memHistoryTree.Fill();
00335 }
00336
00337 outputFile.Write();
00338 outputFile.Close();
00339
00340 }
00341
00342 std::cout << "Approx. maximum total virtual memory size of job: ";
00343 if( isOpenProcFileSuccessful_ && memoryHistoryVector_.size() ) {
00344 std::cout << maxItem.second / 1000.
00345 << " MB (reached " << maxItem.first - startingTime_ << " sec. after constructor called)," << std::endl;
00346 std::cout << " memory history written to: " << rootOutputFileName.str() << " (" << memoryHistoryVector_.size() << " samples)" << std::endl;
00347 } else {
00348 std::cout << "(could not be determined)" << std::endl;
00349 }
00350
00351 std::cout << std::endl << std::endl;
00352
00353 }
00354
00355
00356
00360 void DQMStoreStats::print(){
00361
00362 std::cout << " ---------- " << subsystem_ << " ---------- " << std::endl;
00363 std::cout << " " << subfolder_ << ": " ;
00364 std::cout << nmesubsys_ << " histograms with "
00365 << nbinssubsys_ << " bins. " ;
00366 if (nmesubsys_ > 0) std::cout << nbinssubsys_/nmesubsys_ << " bins/histogram " ;
00367 std::cout << std::endl;
00368 std::cout << " Largest histogram: " << maxbinsmesubsys_ << " with " <<
00369 maxbinssubsys_ << " bins." << std::endl;
00370 }
00371
00372
00373
00374
00378 std::pair<unsigned int, unsigned int> DQMStoreStats::readMemoryEntry( void ) const {
00379
00380
00381 if( isOpenProcFileSuccessful_ ) {
00382
00383 std::ifstream procFile( procFileName_.str().c_str(), ios::in );
00384
00385 std::string readBuffer( "" );
00386 unsigned int memSize = 0;
00387
00388
00389 while( !procFile.eof() ) {
00390 procFile >> readBuffer;
00391 if( std::string( "VmSize:" ) == readBuffer ) {
00392 procFile >> memSize;
00393 break;
00394 }
00395 }
00396
00397 procFile.close();
00398 return std::pair<time_t, unsigned int>( time( 0 ), memSize );
00399 }
00400
00401 return std::pair<time_t, unsigned int>( 0, 0 );
00402
00403 }
00404
00405
00406
00407
00408
00409
00410 void DQMStoreStats::beginJob() {
00411
00413 dbe_ = Service<DQMStore>().operator->();
00414
00415
00416 procFileName_ << "/proc/" << getpid() << "/status";
00417
00418
00419 std::ifstream procFile( procFileName_.str().c_str(), ios::in );
00420
00421 if( procFile.good() ) {
00422 isOpenProcFileSuccessful_ = true;
00423 }
00424 else {
00425 std::cerr << " [DQMStoreStats::beginJob] ** WARNING: could not open file: " << procFileName_.str() << std::endl;
00426 std::cerr << " Total memory profile will not be available." << std::endl;
00427 isOpenProcFileSuccessful_ = false;
00428 }
00429
00430 procFile.close();
00431
00432 }
00433
00434
00435
00436
00437 void DQMStoreStats::beginRun(const edm::Run& r, const EventSetup& context) {
00438 }
00439
00440
00441
00442
00443
00444 void DQMStoreStats::beginLuminosityBlock(const LuminosityBlock& lumiSeg,
00445 const EventSetup& context) {
00446 }
00447
00448
00449
00450
00451
00452 void DQMStoreStats::analyze(const Event& iEvent, const EventSetup& iSetup) {
00453
00454
00455 memoryHistoryVector_.push_back( readMemoryEntry() );
00456
00457 if (runineventloop_) {
00458 calcstats( DQMStoreStats::considerAllME );
00459 calcstats( DQMStoreStats::considerOnlyLumiProductME );
00460 dumpMemoryProfile();
00461 }
00462
00463 }
00464
00465
00466
00467
00468
00469 void DQMStoreStats::endLuminosityBlock(const LuminosityBlock& lumiSeg,
00470 const EventSetup& context) {
00471 if (runonendlumi_) {
00472 calcstats( DQMStoreStats::considerAllME );
00473 calcstats( DQMStoreStats::considerOnlyLumiProductME );
00474 dumpMemoryProfile();
00475 }
00476
00477 }
00478
00479
00480
00481
00482 void DQMStoreStats::endRun(const Run& r, const EventSetup& context) {
00483
00484 if (runonendrun_) {
00485 calcstats( DQMStoreStats::considerAllME );
00486 calcstats( DQMStoreStats::considerOnlyLumiProductME );
00487 dumpMemoryProfile();
00488 }
00489
00490 }
00491
00492
00493
00494
00495 void DQMStoreStats::endJob() {
00496
00497 if (runonendjob_) {
00498 calcstats( DQMStoreStats::considerAllME );
00499 calcstats( DQMStoreStats::considerOnlyLumiProductME );
00500 dumpMemoryProfile();
00501 }
00502
00503 }