25 #include "art/Framework/Services/Optional/detail/LinuxMallInfo.h" 31 #include "art/Utilities/LinuxProcData.h" 32 #include "art/Utilities/LinuxProcMgr.h" 36 #include "cetlib/HorizontalRule.h" 37 #include "cetlib/container_algorithms.h" 38 #include "cetlib/sqlite/Connection.h" 39 #include "cetlib/sqlite/Ntuple.h" 40 #include "cetlib/sqlite/select.h" 90 cet::sqlite::Connection
db_;
95 std::string pathName{};
98 std::vector<PerScheduleData>
data_;
100 template <
unsigned N>
105 {
"Step",
"ModuleLabel",
"ModuleType",
"Vsize",
"RSS"}};
107 {
"Step",
"Run",
"SubRun",
"Event",
"Vsize",
"RSS"}};
143 using peakUsage_t = cet::sqlite::Ntuple<std::string, double, std::string>;
145 Ntuple<std::string, std::string, std::string, double, double>;
147 Ntuple<std::string, uint32_t, uint32_t, uint32_t, double, double>;
148 using memModule_t = cet::sqlite::Ntuple<std::string,
201 unsigned const nSchedules{1u};
205 using art::detail::LinuxMallInfo;
212 ,
fileName_{config().dbOutput().filename()}
217 config().includeMallocInfo())}
225 std::make_unique<memEventHeap_t>(
db_,
230 std::make_unique<memModuleHeap_t>(
db_,
235 data_.resize(nSchedules);
240 iReg.sPreModuleConstruction.watch([
this](
auto const& md) {
243 iReg.sPostModuleConstruction.watch([
this](
auto const& md) {
246 iReg.sPreModuleBeginJob.watch(
248 iReg.sPostModuleBeginJob.watch(
249 [
this](
auto const& md) { this->
recordOtherData(md,
"PostBeginJob"); });
250 iReg.sPreModuleBeginRun.watch(
252 iReg.sPostModuleBeginRun.watch(
253 [
this](
auto const& md) { this->
recordOtherData(md,
"PostBeginRun"); });
254 iReg.sPreModuleBeginSubRun.watch(
255 [
this](
auto const& md) { this->
recordOtherData(md,
"PreBeginSubRun"); });
256 iReg.sPostModuleBeginSubRun.watch(
257 [
this](
auto const& md) { this->
recordOtherData(md,
"PostBeginSubRun"); });
259 iReg.sPreProcessEvent.watch(
261 iReg.sPostProcessEvent.watch(
263 iReg.sPreModule.watch([
this](
auto const& md) {
266 iReg.sPostModule.watch([
this](
auto const& md) {
269 iReg.sPreWriteEvent.watch(
271 iReg.sPostWriteEvent.watch(
273 iReg.sPreModuleEndSubRun.watch(
274 [
this](
auto const& md) { this->
recordOtherData(md,
"PreEndSubRun"); });
275 iReg.sPreModuleEndRun.watch(
277 iReg.sPreModuleEndJob.watch(
279 iReg.sPostModuleEndSubRun.watch(
280 [
this](
auto const& md) { this->
recordOtherData(md,
"PostEndSubRun"); });
281 iReg.sPostModuleEndRun.watch(
283 iReg.sPostModuleEndJob.watch(
294 data_[sid].pathName = pathname;
300 std::string
const& step)
304 auto const data =
procInfo_.getCurrentData(sid);
308 LinuxProcData::getValueInMB<vsize_t>(data),
309 LinuxProcData::getValueInMB<rss_t>(data));
321 auto const currentMemory =
procInfo_.getCurrentData(sid);
327 LinuxProcData::getValueInMB<vsize_t>(currentMemory),
328 LinuxProcData::getValueInMB<rss_t>(currentMemory));
331 auto minfo = LinuxMallInfo{}.get();
349 std::string
const& step)
355 auto const currentMemory =
procInfo_.getCurrentData(sid);
364 LinuxProcData::getValueInMB<vsize_t>(currentMemory),
365 LinuxProcData::getValueInMB<rss_t>(currentMemory));
368 auto minfo = LinuxMallInfo{}.get();
400 if (include && dbfilename.empty()) {
401 std::string
const errmsg =
402 "\n'includeMallocInfo : true' is valid only if a nonempty db filename is specified:\n\n"s +
403 " MemoryTracker: {\n" 404 " includeMallocInfo: true\n" 406 " filename: \"your_filename.db\"\n" 419 "VmPeak",
procInfo_.getVmPeak(),
"Peak virtual memory (MB)");
421 "VmHWM",
procInfo_.getVmHWM(),
"Peak resident set size (MB)");
444 query_result<double> rVMax;
445 query_result<double> rRMax;
452 HorizontalRule
const rule{100};
453 log <<
'\n' << rule(
'=') <<
'\n';
454 log <<
std::left <<
"MemoryTracker summary (base-10 MB units used)\n\n";
455 log <<
" Peak virtual memory usage (VmPeak) : " << unique_value(rVMax)
457 <<
" Peak resident set size usage (VmHWM): " << unique_value(rRMax)
460 log <<
" Details saved in: '" <<
fileName_ <<
"'\n";
fhicl::Atom< std::string > filename
MemoryTracker(fhicl::ParameterSet const &)
void recordOtherData(ModuleDescription const &md, std::string const &step)
name_array< 11u > eventHeapColumns_
#define DEFINE_ART_SERVICE(svc)
art::LinuxProcData::rss_t rss_t
name_array< 9u > moduleColumns_
cet::sqlite::Ntuple< std::string, uint32_t, uint32_t, uint32_t, std::string, std::string, std::string, int, int, int, int, int, int, int > memModuleHeap_t
fhicl::Atom< bool > includeMallocInfo
cet::sqlite::name_array< N > name_array
constexpr id_type id() const
void prePathProcessing(std::string const &)
std::vector< PerScheduleData > data_
static ScheduleID first()
peakUsage_t peakUsageTable_
#define DECLARE_ART_SERVICE(svc, scope)
std::unique_ptr< memEventHeap_t > eventHeapTable_
bool checkMallocConfig_(std::string const &, bool)
cet::sqlite::Ntuple< std::string, uint32_t, uint32_t, uint32_t, int, int, int, int, int, int, int > memEventHeap_t
void recordModuleData(ModuleDescription const &md, std::string const &step)
fhicl::Table< DBoutput > dbOutput
std::string const & moduleName() const
cet::sqlite::Ntuple< std::string, std::string, std::string, double, double > otherInfo_t
std::unique_ptr< memModuleHeap_t > moduleHeapTable_
name_array< 3u > peakUsageColumns_
cet::sqlite::Ntuple< std::string, uint32_t, uint32_t, uint32_t, double, double > memEvent_t
name_array< 5u > otherInfoColumns_
std::string const & moduleLabel() const
name_array< 6u > eventColumns_
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
cet::sqlite::Ntuple< std::string, double, std::string > peakUsage_t
void recordEventData(Event const &e, std::string const &step)
art::LinuxProcData::vsize_t vsize_t
fhicl::Atom< bool > overwrite
name_array< 14u > moduleHeapColumns_
cet::sqlite::Ntuple< std::string, uint32_t, uint32_t, uint32_t, std::string, std::string, std::string, double, double > memModule_t
otherInfo_t otherInfoTable_
cet::sqlite::Connection db_