Skip to content

Commit 0002c77

Browse files
committed
Added ModuleAllocMonitor Service
This uses the AllocMonitor system to monitor the memory usage done by each module as well as the source and memory released at end of event.
1 parent f1dac78 commit 0002c77

21 files changed

+3304
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<use name="FWCore/MessageLogger"/>
22
<use name="FWCore/ServiceRegistry"/>
33
<use name="PerfTools/AllocMonitor"/>
4+
<use name="FWCore/Concurrency"/>
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// -*- C++ -*-
2+
//
3+
// Package: PerfTools/AllocMonitor
4+
// Class : EventProcessingAllocMonitor
5+
//
6+
// Implementation:
7+
// [Notes on implementation]
8+
//
9+
// Original Author: Christopher Jones
10+
// Created: Mon, 21 Aug 2023 20:31:57 GMT
11+
//
12+
13+
// system include files
14+
#include <atomic>
15+
16+
// user include files
17+
#include "PerfTools/AllocMonitor/interface/AllocMonitorBase.h"
18+
#include "PerfTools/AllocMonitor/interface/AllocMonitorRegistry.h"
19+
#include "FWCore/Framework/interface/ComponentDescription.h"
20+
#include "FWCore/MessageLogger/interface/MessageLogger.h"
21+
#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
22+
#include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
23+
#include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
24+
#include "DataFormats/Provenance/interface/ModuleDescription.h"
25+
26+
#include "moduleAlloc_setupFile.h"
27+
#include "ThreadAllocInfo.h"
28+
29+
namespace {
30+
using namespace edm::service::moduleAlloc;
31+
class MonitorAdaptor : public cms::perftools::AllocMonitorBase {
32+
public:
33+
static void startOnThread() { threadAllocInfo().reset(); }
34+
static ThreadAllocInfo const& stopOnThread() {
35+
auto& t = threadAllocInfo();
36+
if (not t.active_) {
37+
t.reset();
38+
} else {
39+
t.deactivate();
40+
}
41+
return t;
42+
}
43+
44+
private:
45+
static ThreadAllocInfo& threadAllocInfo() {
46+
thread_local ThreadAllocInfo s_info;
47+
return s_info;
48+
}
49+
void allocCalled(size_t iRequested, size_t iActual) final {
50+
auto& allocInfo = threadAllocInfo();
51+
if (not allocInfo.active_) {
52+
return;
53+
}
54+
allocInfo.nAllocations_ += 1;
55+
allocInfo.requested_ += iRequested;
56+
57+
if (allocInfo.maxSingleAlloc_ < iRequested) {
58+
allocInfo.maxSingleAlloc_ = iRequested;
59+
}
60+
61+
allocInfo.presentActual_ += iActual;
62+
if (allocInfo.presentActual_ > static_cast<long long>(allocInfo.maxActual_)) {
63+
allocInfo.maxActual_ = allocInfo.presentActual_;
64+
}
65+
}
66+
void deallocCalled(size_t iActual) final {
67+
auto& allocInfo = threadAllocInfo();
68+
if (not allocInfo.active_) {
69+
return;
70+
}
71+
72+
allocInfo.nDeallocations_ += 1;
73+
allocInfo.presentActual_ -= iActual;
74+
if (allocInfo.presentActual_ < 0) {
75+
if (allocInfo.minActual_ == 0 or allocInfo.minActual_ > allocInfo.presentActual_) {
76+
allocInfo.minActual_ = allocInfo.presentActual_;
77+
}
78+
}
79+
}
80+
};
81+
82+
} // namespace
83+
84+
namespace edm::service::moduleAlloc {
85+
Filter::Filter(std::vector<int> const* moduleIDs) : moduleIDs_{moduleIDs} {}
86+
87+
bool Filter::startOnThread(int moduleID) const {
88+
if (not globalKeep_.load()) {
89+
return false;
90+
}
91+
if (keepModuleInfo(moduleID)) {
92+
MonitorAdaptor::startOnThread();
93+
return true;
94+
}
95+
return false;
96+
}
97+
98+
const ThreadAllocInfo* Filter::stopOnThread(int moduleID) const {
99+
if (not globalKeep_.load()) {
100+
return nullptr;
101+
}
102+
103+
if (keepModuleInfo(moduleID)) {
104+
return &MonitorAdaptor::stopOnThread();
105+
}
106+
return nullptr;
107+
}
108+
109+
bool Filter::startOnThread() const {
110+
if (not globalKeep_.load()) {
111+
return false;
112+
}
113+
MonitorAdaptor::startOnThread();
114+
return true;
115+
}
116+
117+
const ThreadAllocInfo* Filter::stopOnThread() const {
118+
if (not globalKeep_.load()) {
119+
return nullptr;
120+
}
121+
return &MonitorAdaptor::stopOnThread();
122+
}
123+
124+
void Filter::setGlobalKeep(bool iShouldKeep) { globalKeep_.store(iShouldKeep); }
125+
126+
bool Filter::keepModuleInfo(int moduleID) const {
127+
if ((nullptr == moduleIDs_) or (moduleIDs_->empty()) or
128+
(std::binary_search(moduleIDs_->begin(), moduleIDs_->end(), moduleID))) {
129+
return true;
130+
}
131+
return false;
132+
}
133+
} // namespace edm::service::moduleAlloc
134+
135+
class ModuleAllocMonitor {
136+
public:
137+
ModuleAllocMonitor(edm::ParameterSet const& iPS, edm::ActivityRegistry& iAR)
138+
: moduleNames_(iPS.getUntrackedParameter<std::vector<std::string>>("moduleNames")),
139+
nEventsToSkip_(iPS.getUntrackedParameter<unsigned int>("nEventsToSkip")),
140+
filter_(&moduleIDs_) {
141+
(void)cms::perftools::AllocMonitorRegistry::instance().createAndRegisterMonitor<MonitorAdaptor>();
142+
143+
if (nEventsToSkip_ > 0) {
144+
filter_.setGlobalKeep(false);
145+
}
146+
if (not moduleNames_.empty()) {
147+
iAR.watchPreModuleConstruction([this](auto const& description) {
148+
auto found = std::find(moduleNames_.begin(), moduleNames_.end(), description.moduleLabel());
149+
if (found != moduleNames_.end()) {
150+
moduleIDs_.push_back(description.id());
151+
std::sort(moduleIDs_.begin(), moduleIDs_.end());
152+
}
153+
});
154+
155+
iAR.watchPostESModuleRegistration([this](auto const& iDescription) {
156+
auto label = iDescription.label_;
157+
if (label.empty()) {
158+
label = iDescription.type_;
159+
}
160+
auto found = std::find(moduleNames_.begin(), moduleNames_.end(), label);
161+
if (found != moduleNames_.end()) {
162+
//NOTE: we want the id to start at 1 not 0
163+
moduleIDs_.push_back(-1 * (iDescription.id_ + 1));
164+
std::sort(moduleIDs_.begin(), moduleIDs_.end());
165+
}
166+
});
167+
}
168+
if (nEventsToSkip_ > 0) {
169+
iAR.watchPreSourceEvent([this](auto) {
170+
++nEventsStarted_;
171+
if (nEventsStarted_ > nEventsToSkip_) {
172+
filter_.setGlobalKeep(true);
173+
}
174+
});
175+
}
176+
edm::service::moduleAlloc::setupFile(iPS.getUntrackedParameter<std::string>("fileName"), iAR, &filter_);
177+
}
178+
179+
static void fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
180+
edm::ParameterSetDescription ps;
181+
ps.addUntracked<std::string>("fileName");
182+
ps.addUntracked<std::vector<std::string>>("moduleNames", std::vector<std::string>());
183+
ps.addUntracked<unsigned int>("nEventsToSkip", 0);
184+
iDesc.addDefault(ps);
185+
}
186+
187+
private:
188+
bool forThisModule(unsigned int iID) {
189+
return (moduleNames_.empty() or std::binary_search(moduleIDs_.begin(), moduleIDs_.end(), iID));
190+
}
191+
std::vector<std::string> moduleNames_;
192+
std::vector<int> moduleIDs_;
193+
unsigned int nEventsToSkip_ = 0;
194+
std::atomic<unsigned int> nEventsStarted_{0};
195+
edm::service::moduleAlloc::Filter filter_;
196+
};
197+
198+
DEFINE_FWK_SERVICE(ModuleAllocMonitor);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#ifndef PerfTools_AllocMonitor_ThreadAllocInfo_h
2+
#define PerfTools_AllocMonitor_ThreadAllocInfo_h
3+
// -*- C++ -*-
4+
//
5+
// Package: PerfTools/AllocMonitor
6+
// Class : ThreadAllocInfo
7+
//
8+
/**\class ThreadAllocInfo ThreadAllocInfo.h "ThreadAllocInfo.h"
9+
10+
Description: information about per module allocations
11+
12+
Usage:
13+
<usage>
14+
15+
*/
16+
//
17+
// Original Author: Christopher Jones
18+
// Created: Fri, 10 May 2024 14:48:59 GMT
19+
//
20+
21+
// system include files
22+
23+
// user include files
24+
25+
// forward declarations
26+
27+
namespace edm::service::moduleAlloc {
28+
struct ThreadAllocInfo {
29+
size_t requested_ = 0;
30+
long long presentActual_ = 0;
31+
size_t maxActual_ = 0;
32+
long long minActual_ = 0;
33+
size_t maxSingleAlloc_ = 0;
34+
size_t nAllocations_ = 0;
35+
size_t nDeallocations_ = 0;
36+
bool active_ = false;
37+
38+
void reset() {
39+
requested_ = 0;
40+
presentActual_ = 0;
41+
maxActual_ = 0;
42+
minActual_ = 0;
43+
maxSingleAlloc_ = 0;
44+
nAllocations_ = 0;
45+
nDeallocations_ = 0;
46+
active_ = true;
47+
}
48+
49+
void deactivate() { active_ = false; }
50+
};
51+
} // namespace edm::service::moduleAlloc
52+
#endif

0 commit comments

Comments
 (0)