CMS 3D CMS Logo

JeProfService.cc
Go to the documentation of this file.
1 
2 //
3 // Description: FWK service to implement hook for jemalloc heap profile
4 // dump functionality
5 //
6 
15 #include <string>
16 #include <dlfcn.h>
17 #include <cstdio>
18 #include <cstring>
19 
20 extern "C" {
21 typedef int (*mallctl_t)(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
22 }
23 
24 namespace {
25  bool initialize_prof();
26 
27  mallctl_t mallctl = nullptr;
28  const bool have_jemalloc_and_prof = initialize_prof();
29 
30  bool initialize_prof() {
31  // check if mallctl and friends are available, if we are using jemalloc
32  mallctl = (mallctl_t)::dlsym(RTLD_DEFAULT, "mallctl");
33  if (mallctl == nullptr)
34  return false;
35  // check if heap profiling available, if --enable-prof was specified at build time
36  bool enable_prof = false;
37  size_t bool_s = sizeof(bool);
38  mallctl("prof.active", &enable_prof, &bool_s, nullptr, 0);
39  return enable_prof;
40  }
41 
42 } // namespace
43 
44 namespace edm {
45  class GlobalContext;
46  class StreamContext;
47 
48  namespace service {
49  class JeProfService {
50  public:
52 
53  void postBeginJob();
54 
55  void postBeginRun(GlobalContext const &gc);
56 
57  void postBeginLumi(GlobalContext const &gc);
58 
59  void preEvent(StreamContext const &sc);
60  void postEvent(StreamContext const &sc);
61 
62  void preModuleEvent(StreamContext const &sc, ModuleCallingContext const &mcc);
63  void postModuleEvent(StreamContext const &sc, ModuleCallingContext const &mcc);
64 
65  void postEndLumi(GlobalContext const &gc);
66 
67  void preEndRun(GlobalContext const &gc);
68  void postEndRun(GlobalContext const &gc);
69 
70  void preEndProcessBlock(GlobalContext const &gc);
71  void postEndProcessBlock(GlobalContext const &gc);
72 
73  void preEndJob();
74  void postEndJob();
75 
76  void postOpenFile(std::string const &);
77 
78  void postCloseFile(std::string const &);
79 
80  private:
81  void makeDump(const std::string &format, std::string_view moduleLabel = "");
82  static std::string replace(const std::string &s, const char *pat, int val);
83  static std::string replaceU64(const std::string &s, const char *pat, unsigned long long val);
84  static std::string replace(const std::string &s, const char *pat, std::string_view val);
85 
89 
92 
93  std::vector<std::string> modules_;
94  std::vector<std::string> moduleTypes_;
97 
105 
108 
111  int nrecord_; // counter
115  int nfileopened_; // counter of files opened thus far
116  int nfileclosed_; // counter of files closed thus far
117  };
118  inline bool isProcessWideService(JeProfService const *) { return true; }
119  } // namespace service
120 } // namespace edm
121 
122 using namespace edm::service;
123 
125  : mineventrecord_(1), prescale_(1), nrecord_(0), nevent_(0), nrun_(0), nlumi_(0), nfileopened_(0), nfileclosed_(0) {
126  if (!have_jemalloc_and_prof) {
127  edm::LogWarning("JeProfModule") << "JeProfModule requested but application is not"
128  << " currently being profiled with jemalloc profiling\n";
129  }
130  // Get the configuration
131  prescale_ = ps.getUntrackedParameter<int>("reportEventInterval", prescale_);
132  mineventrecord_ = ps.getUntrackedParameter<int>("reportFirstEvent", mineventrecord_);
133 
134  atPostBeginJob_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostBeginJob", atPostBeginJob_);
135  atPostBeginRun_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostBeginRun", atPostBeginRun_);
136  atPostBeginLumi_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostBeginLumi", atPostBeginLumi_);
137 
138  atPreEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreEvent", atPreEvent_);
139  atPostEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEvent", atPostEvent_);
140 
141  modules_ = ps.getUntrackedParameter<std::vector<std::string>>("reportModules", modules_);
142  moduleTypes_ = ps.getUntrackedParameter<std::vector<std::string>>("reportModuleTypes", moduleTypes_);
143  std::sort(modules_.begin(), modules_.end());
144  std::sort(moduleTypes_.begin(), moduleTypes_.end());
145  atPreModuleEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreModuleEvent", atPreModuleEvent_);
146  atPostModuleEvent_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostModuleEvent", atPostModuleEvent_);
147 
148  atPostEndLumi_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEndLumi", atPostEndLumi_);
149  atPreEndRun_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreEndRun", atPreEndRun_);
150  atPostEndRun_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEndRun", atPostEndRun_);
152  ps.getUntrackedParameter<std::string>("reportToFileAtPreEndProcessBlock", atPreEndProcessBlock_);
154  ps.getUntrackedParameter<std::string>("reportToFileAtPostEndProcessBlock", atPostEndProcessBlock_);
155  atPreEndJob_ = ps.getUntrackedParameter<std::string>("reportToFileAtPreEndJob", atPreEndJob_);
156  atPostEndJob_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostEndJob", atPostEndJob_);
157 
158  atPostOpenFile_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostOpenFile", atPostOpenFile_);
159  atPostCloseFile_ = ps.getUntrackedParameter<std::string>("reportToFileAtPostCloseFile", atPostCloseFile_);
160 
161  // Register for the framework signals
165 
166  iRegistry.watchPreEvent(this, &JeProfService::preEvent);
167  iRegistry.watchPostEvent(this, &JeProfService::postEvent);
168 
169  if (not modules_.empty() or not moduleTypes_.empty()) {
172  }
173 
179  iRegistry.watchPreEndJob(this, &JeProfService::preEndJob);
180  iRegistry.watchPostEndJob(this, &JeProfService::postEndJob);
181 
184 }
185 
187 
189  nrun_ = gc.luminosityBlockID().run();
191 }
192 
196 }
197 
199  ++nrecord_; // count before events
200  nevent_ = iStream.eventID().event();
201  if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0))
203 }
204 
206  nevent_ = iStream.eventID().event();
207  if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0))
209 }
210 
212  nevent_ = iStream.eventID().event();
213  if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0)) {
214  auto const &moduleLabel = mcc.moduleDescription()->moduleLabel();
215  auto const &moduleType = mcc.moduleDescription()->moduleName();
216  if (std::binary_search(modules_.begin(), modules_.end(), moduleLabel) or
217  std::binary_search(moduleTypes_.begin(), moduleTypes_.end(), moduleType)) {
219  }
220  }
221 }
222 
224  nevent_ = iStream.eventID().event();
225  if ((prescale_ > 0) && (nrecord_ >= mineventrecord_) && (((nrecord_ - mineventrecord_) % prescale_) == 0)) {
226  auto const &moduleLabel = mcc.moduleDescription()->moduleLabel();
227  auto const &moduleType = mcc.moduleDescription()->moduleName();
228  if (std::binary_search(modules_.begin(), modules_.end(), moduleLabel) or
229  std::binary_search(moduleTypes_.begin(), moduleTypes_.end(), moduleType)) {
231  }
232  }
233 }
234 
238 }
239 
241  nrun_ = gc.luminosityBlockID().run();
243 }
244 
246  nrun_ = gc.luminosityBlockID().run();
248 }
249 
251 
253 
255 
257 
259  ++nfileopened_;
261 }
262 
264  ++nfileclosed_;
266 }
267 
268 void JeProfService::makeDump(const std::string &format, std::string_view moduleLabel) {
269  if (!have_jemalloc_and_prof || format.empty())
270  return;
271 
272  std::string final(format);
273  final = replace(final, "%I", nrecord_);
274  final = replaceU64(final, "%E", nevent_);
275  final = replaceU64(final, "%R", nrun_);
276  final = replaceU64(final, "%L", nlumi_);
277  final = replace(final, "%F", nfileopened_);
278  final = replace(final, "%C", nfileclosed_);
279  final = replace(final, "%M", moduleLabel);
280  const char *fileName = final.c_str();
281  mallctl("prof.dump", nullptr, nullptr, &fileName, sizeof(const char *));
282 }
283 
285  size_t pos = 0;
286  size_t patlen = strlen(pat);
287  std::string result = s;
288  while ((pos = result.find(pat, pos)) != std::string::npos) {
289  char buf[64];
290  int n = sprintf(buf, "%d", val);
291  result.replace(pos, patlen, buf);
292  pos = pos - patlen + n;
293  }
294 
295  return result;
296 }
297 
298 std::string JeProfService::replaceU64(const std::string &s, const char *pat, unsigned long long val) {
299  size_t pos = 0;
300  size_t patlen = strlen(pat);
301  std::string result = s;
302  while ((pos = result.find(pat, pos)) != std::string::npos) {
303  char buf[64];
304  int n = sprintf(buf, "%llu", val);
305  result.replace(pos, patlen, buf);
306  pos = pos - patlen + n;
307  }
308 
309  return result;
310 }
311 
312 std::string JeProfService::replace(const std::string &s, const char *pat, std::string_view val) {
313  size_t pos = 0;
314  size_t patlen = strlen(pat);
315  std::string result = s;
316  while ((pos = result.find(pat, pos)) != std::string::npos) {
317  result.replace(pos, patlen, val.data());
318  pos = pos - patlen + val.size();
319  }
320 
321  return result;
322 }
323 
void preEndProcessBlock(GlobalContext const &gc)
void watchPreEvent(PreEvent::slot_type const &iSlot)
ModuleDescription const * moduleDescription() const
LuminosityBlockNumber_t luminosityBlock() const
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
void postModuleEvent(StreamContext const &sc, ModuleCallingContext const &mcc)
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
void watchPostEvent(PostEvent::slot_type const &iSlot)
void preEndRun(GlobalContext const &gc)
bool isProcessWideService(TFileService const *)
Definition: TFileService.h:98
unsigned long long EventNumber_t
void watchPostEndProcessBlock(PostEndProcessBlock::slot_type const &iSlot)
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
void watchPostGlobalBeginLumi(PostGlobalBeginLumi::slot_type const &iSlot)
std::string const & moduleName() const
void watchPreEndProcessBlock(PreEndProcessBlock::slot_type const &iSlot)
unsigned int LuminosityBlockNumber_t
Definition: HeavyIon.h:7
T getUntrackedParameter(std::string const &, T const &) const
void watchPostGlobalBeginRun(PostGlobalBeginRun::slot_type const &iSlot)
void watchPostCloseFile(PostCloseFile::slot_type const &iSlot)
void watchPreGlobalEndRun(PreGlobalEndRun::slot_type const &iSlot)
void postBeginRun(GlobalContext const &gc)
static std::string replace(const std::string &s, const char *pat, int val)
int(* mallctl_t)(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
void preEvent(StreamContext const &sc)
edm::LuminosityBlockNumber_t nlumi_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void postBeginLumi(GlobalContext const &gc)
void watchPostGlobalEndLumi(PostGlobalEndLumi::slot_type const &iSlot)
void preModuleEvent(StreamContext const &sc, ModuleCallingContext const &mcc)
std::vector< std::string > modules_
void postEndLumi(GlobalContext const &gc)
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:62
edm::EventNumber_t nevent_
RunNumber_t run() const
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:97
void watchPostGlobalEndRun(PostGlobalEndRun::slot_type const &iSlot)
void watchPostOpenFile(PostOpenFile::slot_type const &iSlot)
static std::string replaceU64(const std::string &s, const char *pat, unsigned long long val)
void watchPreEndJob(PreEndJob::slot_type const &iSlot)
void postEndRun(GlobalContext const &gc)
std::vector< std::string > moduleTypes_
HLT enums.
EventID const & eventID() const
Definition: StreamContext.h:60
void postEvent(StreamContext const &sc)
void postCloseFile(std::string const &)
void makeDump(const std::string &format, std::string_view moduleLabel="")
JeProfService(const ParameterSet &, ActivityRegistry &)
unsigned int RunNumber_t
void postEndProcessBlock(GlobalContext const &gc)
Log< level::Warning, false > LogWarning
std::string const & moduleLabel() const
void postOpenFile(std::string const &)
EventNumber_t event() const
Definition: EventID.h:40
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal