Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:00

0001 
0002 //
0003 //  Description: FWK service to implement hook for igprof memory profile
0004 //               dump functionality
0005 //
0006 //  Peter Elmer, Princeton University                        18 Nov, 2008
0007 //
0008 
0009 #include "IgTools/IgProf/plugins/IgProfService.h"
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/Framework/interface/LuminosityBlock.h"
0015 #include "FWCore/Framework/interface/FileBlock.h"
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/Framework/interface/Run.h"
0018 #include <string>
0019 #include <dlfcn.h>
0020 #include <cstdio>
0021 #include <cstring>
0022 
0023 using namespace edm::service;
0024 
0025 IgProfService::IgProfService(ParameterSet const &ps, ActivityRegistry &iRegistry)
0026     : dump_(nullptr),
0027       mineventrecord_(1),
0028       prescale_(1),
0029       nrecord_(0),
0030       nevent_(0),
0031       nrun_(0),
0032       nlumi_(0),
0033       nfileopened_(0),
0034       nfileclosed_(0) {
0035   // Removing the __extension__ gives a warning which
0036   // is acknowledged as a language problem in the C++ Standard Core
0037   // Language Defect Report
0038   //
0039   // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
0040   //
0041   // since the suggested decision seems to be that the syntax should
0042   // actually be "Conditionally-Supported Behavior" in some
0043   // future C++ standard I simply silence the warning.
0044   if (void *sym = dlsym(nullptr, "igprof_dump_now")) {
0045     dump_ = __extension__(void (*)(const char *)) sym;
0046   } else
0047     edm::LogWarning("IgProfModule") << "IgProfModule requested but application is not"
0048                                     << " currently being profiled with igprof\n";
0049 
0050   // Get the configuration
0051   prescale_ = ps.getUntrackedParameter<int>("reportEventInterval", prescale_);
0052   mineventrecord_ = ps.getUntrackedParameter<int>("reportFirstEvent", mineventrecord_);
0053 
0054   atPostBeginJob_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostBeginJob", atPostBeginJob_);
0055   atPostBeginRun_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostBeginRun", atPostBeginRun_);
0056   atPostBeginLumi_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostBeginLumi", atPostBeginLumi_);
0057 
0058   atPreEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreEvent", atPreEvent_);
0059   atPostEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEvent", atPostEvent_);
0060 
0061   modules_ = ps.getUntrackedParameter<std::vector<std::string>>("reportModules", modules_);
0062   moduleTypes_ = ps.getUntrackedParameter<std::vector<std::string>>("reportModuleTypes", moduleTypes_);
0063   std::sort(modules_.begin(), modules_.end());
0064   std::sort(moduleTypes_.begin(), moduleTypes_.end());
0065   atPreModuleEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreModuleEvent", atPreModuleEvent_);
0066   atPostModuleEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostModuleEvent", atPostModuleEvent_);
0067 
0068   atPostEndLumi_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEndLumi", atPostEndLumi_);
0069   atPreEndRun_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreEndRun", atPreEndRun_);
0070   atPostEndRun_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEndRun", atPostEndRun_);
0071   atPreEndProcessBlock_ =
0072       ps.getUntrackedParameter<std::string>("reportToFileAtPreEndProcessBlock", atPreEndProcessBlock_);
0073   atPostEndProcessBlock_ =
0074       ps.getUntrackedParameter<std::string>("reportToFileAtPostEndProcessBlock", atPostEndProcessBlock_);
0075   atPreEndJob_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreEndJob", atPreEndJob_);
0076   atPostEndJob_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEndJob", atPostEndJob_);
0077 
0078   atPostOpenFile_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostOpenFile", atPostOpenFile_);
0079   atPostCloseFile_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostCloseFile", atPostCloseFile_);
0080 
0081   // Register for the framework signals
0082   iRegistry.watchPostBeginJob(this, &IgProfService::postBeginJob);
0083   iRegistry.watchPostGlobalBeginRun(this, &IgProfService::postBeginRun);
0084   iRegistry.watchPostGlobalBeginLumi(this, &IgProfService::postBeginLumi);
0085 
0086   iRegistry.watchPreEvent(this, &IgProfService::preEvent);
0087   iRegistry.watchPostEvent(this, &IgProfService::postEvent);
0088 
0089   if (not modules_.empty() or not moduleTypes_.empty()) {
0090     iRegistry.watchPreModuleEvent(this, &IgProfService::preModuleEvent);
0091     iRegistry.watchPostModuleEvent(this, &IgProfService::postModuleEvent);
0092   }
0093 
0094   iRegistry.watchPostGlobalEndLumi(this, &IgProfService::postEndLumi);
0095   iRegistry.watchPreGlobalEndRun(this, &IgProfService::preEndRun);
0096   iRegistry.watchPostGlobalEndRun(this, &IgProfService::postEndRun);
0097   iRegistry.watchPreEndProcessBlock(this, &IgProfService::preEndProcessBlock);
0098   iRegistry.watchPostEndProcessBlock(this, &IgProfService::postEndProcessBlock);
0099   iRegistry.watchPreEndJob(this, &IgProfService::preEndJob);
0100   iRegistry.watchPostEndJob(this, &IgProfService::postEndJob);
0101 
0102   iRegistry.watchPostOpenFile(this, &IgProfService::postOpenFile);
0103   iRegistry.watchPostCloseFile(this, &IgProfService::postCloseFile);
0104 }
0105 
0106 void IgProfService::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0107   edm::ParameterSetDescription desc;
0108 
0109   desc.setComment(
0110       "All file parameters allow the following replaceable tokens:\n"
0111       "  %I : record number\n"
0112       "  %E : event number\n"
0113       "  %R : run number\n"
0114       "  %L : lumi number\n"
0115       "  %F : file open count\n"
0116       "  %C : file close count\n"
0117       "  %M : module label");
0118   desc.addUntracked<int>("reportEventInterval", 1)->setComment("write a new file every n events");
0119   desc.addUntracked<int>("reportFirstEvent", 1)->setComment("first event count to start writing files");
0120   ;
0121 
0122   desc.addUntracked<std::string>("reportToFileAtPostBeginJob", "");
0123   desc.addUntracked<std::string>("reportToFileAtPostBeginRun", "");
0124   desc.addUntracked<std::string>("reportToFileAtPostBeginLumi", "");
0125 
0126   desc.addUntracked<std::string>("reportToFileAtPreEvent", "");
0127   desc.addUntracked<std::string>("reportToFileAtPostEvent", "");
0128 
0129   desc.addUntracked<std::vector<std::string>>("reportModules", {});
0130   desc.addUntracked<std::vector<std::string>>("reportModuleTypes", {});
0131 
0132   desc.addUntracked<std::string>("reportToFileAtPreModuleEvent", "");
0133   desc.addUntracked<std::string>("reportToFileAtPostModuleEvent", "");
0134 
0135   desc.addUntracked<std::string>("reportToFileAtPostEndLumi", "");
0136   desc.addUntracked<std::string>("reportToFileAtPreEndRun", "");
0137   desc.addUntracked<std::string>("reportToFileAtPostEndRun", "");
0138   desc.addUntracked<std::string>("reportToFileAtPreEndProcessBlock", "");
0139   desc.addUntracked<std::string>("reportToFileAtPostEndProcessBlock", "");
0140   desc.addUntracked<std::string>("reportToFileAtPreEndJob", "");
0141   desc.addUntracked<std::string>("reportToFileAtPostEndJob", "");
0142 
0143   desc.addUntracked<std::string>("reportToFileAtPostOpenFile", "");
0144   desc.addUntracked<std::string>("reportToFileAtPostCloseFile", "");
0145 
0146   descriptions.addDefault(desc);
0147 }
0148 
0149 void IgProfService::postBeginJob() { makeDump(atPostBeginJob_); }
0150 
0151 void IgProfService::postBeginRun(GlobalContext const &gc) {
0152   nrun_ = gc.luminosityBlockID().run();
0153   makeDump(atPostBeginRun_);
0154 }
0155 
0156 void IgProfService::postBeginLumi(GlobalContext const &gc) {
0157   nlumi_ = gc.luminosityBlockID().luminosityBlock();
0158   makeDump(atPostBeginLumi_);
0159 }
0160 
0161 void IgProfService::preEvent(StreamContext const &iStream) {
0162   ++nrecord_;  // count before events
0163   nevent_ = iStream.eventID().event();
0164   if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0))
0165     makeDump(atPreEvent_);
0166 }
0167 
0168 void IgProfService::postEvent(StreamContext const &iStream) {
0169   nevent_ = iStream.eventID().event();
0170   if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0))
0171     makeDump(atPostEvent_);
0172 }
0173 
0174 void IgProfService::preModuleEvent(StreamContext const &iStream, ModuleCallingContext const &mcc) {
0175   nevent_ = iStream.eventID().event();
0176   if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0)) {
0177     auto const &moduleLabel = mcc.moduleDescription()->moduleLabel();
0178     auto const &moduleType = mcc.moduleDescription()->moduleName();
0179     if (std::binary_search(modules_.begin(), modules_.end(), moduleLabel) or
0180         std::binary_search(moduleTypes_.begin(), moduleTypes_.end(), moduleType)) {
0181       makeDump(atPreModuleEvent_, moduleLabel);
0182     }
0183   }
0184 }
0185 
0186 void IgProfService::postModuleEvent(StreamContext const &iStream, ModuleCallingContext const &mcc) {
0187   nevent_ = iStream.eventID().event();
0188   if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0)) {
0189     auto const &moduleLabel = mcc.moduleDescription()->moduleLabel();
0190     auto const &moduleType = mcc.moduleDescription()->moduleName();
0191     if (std::binary_search(modules_.begin(), modules_.end(), moduleLabel) or
0192         std::binary_search(moduleTypes_.begin(), moduleTypes_.end(), moduleType)) {
0193       makeDump(atPostModuleEvent_, moduleLabel);
0194     }
0195   }
0196 }
0197 
0198 void IgProfService::postEndLumi(GlobalContext const &gc) {
0199   nlumi_ = gc.luminosityBlockID().luminosityBlock();
0200   makeDump(atPostEndLumi_);
0201 }
0202 
0203 void IgProfService::preEndRun(GlobalContext const &gc) {
0204   nrun_ = gc.luminosityBlockID().run();
0205   makeDump(atPreEndRun_);
0206 }
0207 
0208 void IgProfService::postEndRun(GlobalContext const &gc) {
0209   nrun_ = gc.luminosityBlockID().run();
0210   makeDump(atPostEndRun_);
0211 }
0212 
0213 void IgProfService::preEndProcessBlock(GlobalContext const &gc) { makeDump(atPreEndProcessBlock_); }
0214 
0215 void IgProfService::postEndProcessBlock(GlobalContext const &gc) { makeDump(atPostEndProcessBlock_); }
0216 
0217 void IgProfService::preEndJob() { makeDump(atPreEndJob_); }
0218 
0219 void IgProfService::postEndJob() { makeDump(atPostEndJob_); }
0220 
0221 void IgProfService::postOpenFile(std::string const &) {
0222   ++nfileopened_;
0223   makeDump(atPostOpenFile_);
0224 }
0225 
0226 void IgProfService::postCloseFile(std::string const &) {
0227   ++nfileclosed_;
0228   makeDump(atPostCloseFile_);
0229 }
0230 
0231 void IgProfService::makeDump(const std::string &format, std::string_view moduleLabel) {
0232   if (!dump_ || format.empty())
0233     return;
0234 
0235   std::string final(format);
0236   final = replace(final, "%I", nrecord_);
0237   final = replaceU64(final, "%E", nevent_);
0238   final = replaceU64(final, "%R", nrun_);
0239   final = replaceU64(final, "%L", nlumi_);
0240   final = replace(final, "%F", nfileopened_);
0241   final = replace(final, "%C", nfileclosed_);
0242   final = replace(final, "%M", moduleLabel);
0243   dump_(final.c_str());
0244 }
0245 
0246 std::string IgProfService::replace(const std::string &s, const char *pat, int val) {
0247   size_t pos = 0;
0248   size_t patlen = strlen(pat);
0249   std::string result = s;
0250   while ((pos = result.find(pat, pos)) != std::string::npos) {
0251     char buf[64];
0252     int n = sprintf(buf, "%d", val);
0253     result.replace(pos, patlen, buf);
0254     pos = pos - patlen + n;
0255   }
0256 
0257   return result;
0258 }
0259 
0260 std::string IgProfService::replaceU64(const std::string &s, const char *pat, unsigned long long val) {
0261   size_t pos = 0;
0262   size_t patlen = strlen(pat);
0263   std::string result = s;
0264   while ((pos = result.find(pat, pos)) != std::string::npos) {
0265     char buf[64];
0266     int n = sprintf(buf, "%llu", val);
0267     result.replace(pos, patlen, buf);
0268     pos = pos - patlen + n;
0269   }
0270 
0271   return result;
0272 }
0273 
0274 std::string IgProfService::replace(const std::string &s, const char *pat, std::string_view val) {
0275   size_t pos = 0;
0276   size_t patlen = strlen(pat);
0277   std::string result = s;
0278   while ((pos = result.find(pat, pos)) != std::string::npos) {
0279     result.replace(pos, patlen, val.data());
0280     pos = pos - patlen + val.size();
0281   }
0282 
0283   return result;
0284 }
0285 
0286 DEFINE_FWK_SERVICE(IgProfService);