File indexing completed on 2024-12-17 02:43:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <atomic>
0015
0016
0017 #include "PerfTools/AllocMonitor/interface/AllocMonitorBase.h"
0018 #include "PerfTools/AllocMonitor/interface/AllocMonitorRegistry.h"
0019 #include "FWCore/Framework/interface/ComponentDescription.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0022 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
0023 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0024 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0025
0026 #if defined(ALLOC_USE_PTHREADS)
0027 #include <pthread.h>
0028 #else
0029 #include <unistd.h>
0030 #include <sys/syscall.h>
0031 #endif
0032
0033 #include "moduleAlloc_setupFile.h"
0034 #include "ThreadAllocInfo.h"
0035 #include "ThreadTracker.h"
0036
0037 namespace {
0038 using namespace cms::perftools::allocMon;
0039 using namespace edm::service::moduleAlloc;
0040 class MonitorAdaptor : public cms::perftools::AllocMonitorBase {
0041 public:
0042 static void startOnThread() { threadAllocInfo().reset(); }
0043 static ThreadAllocInfo const& stopOnThread() {
0044 auto& t = threadAllocInfo();
0045 if (not t.active_) {
0046 t.reset();
0047 } else {
0048 t.deactivate();
0049 }
0050 return t;
0051 }
0052
0053 private:
0054 static ThreadAllocInfo& threadAllocInfo() {
0055 static ThreadAllocInfo s_info[ThreadTracker::kTotalEntries];
0056 return s_info[ThreadTracker::instance().thread_index()];
0057 }
0058 void allocCalled(size_t iRequested, size_t iActual, void const*) final {
0059 auto& allocInfo = threadAllocInfo();
0060 if (not allocInfo.active_) {
0061 return;
0062 }
0063 allocInfo.nAllocations_ += 1;
0064 allocInfo.requested_ += iRequested;
0065
0066 if (allocInfo.maxSingleAlloc_ < iRequested) {
0067 allocInfo.maxSingleAlloc_ = iRequested;
0068 }
0069
0070 allocInfo.presentActual_ += iActual;
0071 if (allocInfo.presentActual_ > static_cast<long long>(allocInfo.maxActual_)) {
0072 allocInfo.maxActual_ = allocInfo.presentActual_;
0073 }
0074 }
0075 void deallocCalled(size_t iActual, void const*) final {
0076 auto& allocInfo = threadAllocInfo();
0077 if (not allocInfo.active_) {
0078 return;
0079 }
0080
0081 allocInfo.nDeallocations_ += 1;
0082 allocInfo.presentActual_ -= iActual;
0083 if (allocInfo.presentActual_ < 0) {
0084 if (allocInfo.minActual_ == 0 or allocInfo.minActual_ > allocInfo.presentActual_) {
0085 allocInfo.minActual_ = allocInfo.presentActual_;
0086 }
0087 }
0088 }
0089 };
0090
0091 }
0092
0093 namespace edm::service::moduleAlloc {
0094 Filter::Filter(std::vector<int> const* moduleIDs) : moduleIDs_{moduleIDs} {}
0095
0096 bool Filter::startOnThread(int moduleID) const {
0097 if (not globalKeep_.load()) {
0098 return false;
0099 }
0100 if (keepModuleInfo(moduleID)) {
0101 MonitorAdaptor::startOnThread();
0102 return true;
0103 }
0104 return false;
0105 }
0106
0107 const ThreadAllocInfo* Filter::stopOnThread(int moduleID) const {
0108 if (not globalKeep_.load()) {
0109 return nullptr;
0110 }
0111
0112 if (keepModuleInfo(moduleID)) {
0113 return &MonitorAdaptor::stopOnThread();
0114 }
0115 return nullptr;
0116 }
0117
0118 bool Filter::startOnThread() const {
0119 if (not globalKeep_.load()) {
0120 return false;
0121 }
0122 MonitorAdaptor::startOnThread();
0123 return true;
0124 }
0125
0126 const ThreadAllocInfo* Filter::stopOnThread() const {
0127 if (not globalKeep_.load()) {
0128 return nullptr;
0129 }
0130 return &MonitorAdaptor::stopOnThread();
0131 }
0132
0133 void Filter::setGlobalKeep(bool iShouldKeep) { globalKeep_.store(iShouldKeep); }
0134
0135 bool Filter::keepModuleInfo(int moduleID) const {
0136 if ((nullptr == moduleIDs_) or (moduleIDs_->empty()) or
0137 (std::binary_search(moduleIDs_->begin(), moduleIDs_->end(), moduleID))) {
0138 return true;
0139 }
0140 return false;
0141 }
0142 }
0143
0144 class ModuleAllocMonitor {
0145 public:
0146 ModuleAllocMonitor(edm::ParameterSet const& iPS, edm::ActivityRegistry& iAR)
0147 : moduleNames_(iPS.getUntrackedParameter<std::vector<std::string>>("moduleNames")),
0148 nEventsToSkip_(iPS.getUntrackedParameter<unsigned int>("nEventsToSkip")),
0149 filter_(&moduleIDs_) {
0150 (void)cms::perftools::AllocMonitorRegistry::instance().createAndRegisterMonitor<MonitorAdaptor>();
0151
0152 if (nEventsToSkip_ > 0) {
0153 filter_.setGlobalKeep(false);
0154 }
0155 if (not moduleNames_.empty()) {
0156 iAR.watchPreModuleConstruction([this](auto const& description) {
0157 auto found = std::find(moduleNames_.begin(), moduleNames_.end(), description.moduleLabel());
0158 if (found != moduleNames_.end()) {
0159 moduleIDs_.push_back(description.id());
0160 std::sort(moduleIDs_.begin(), moduleIDs_.end());
0161 }
0162 });
0163
0164 iAR.watchPostESModuleRegistration([this](auto const& iDescription) {
0165 auto label = iDescription.label_;
0166 if (label.empty()) {
0167 label = iDescription.type_;
0168 }
0169 auto found = std::find(moduleNames_.begin(), moduleNames_.end(), label);
0170 if (found != moduleNames_.end()) {
0171
0172 moduleIDs_.push_back(-1 * (iDescription.id_ + 1));
0173 std::sort(moduleIDs_.begin(), moduleIDs_.end());
0174 }
0175 });
0176 }
0177 if (nEventsToSkip_ > 0) {
0178 iAR.watchPreSourceEvent([this](auto) {
0179 ++nEventsStarted_;
0180 if (nEventsStarted_ > nEventsToSkip_) {
0181 filter_.setGlobalKeep(true);
0182 }
0183 });
0184 }
0185 edm::service::moduleAlloc::setupFile(iPS.getUntrackedParameter<std::string>("fileName"), iAR, &filter_);
0186 }
0187
0188 static void fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
0189 edm::ParameterSetDescription ps;
0190 ps.addUntracked<std::string>("fileName");
0191 ps.addUntracked<std::vector<std::string>>("moduleNames", std::vector<std::string>());
0192 ps.addUntracked<unsigned int>("nEventsToSkip", 0);
0193 iDesc.addDefault(ps);
0194 }
0195
0196 private:
0197 bool forThisModule(unsigned int iID) {
0198 return (moduleNames_.empty() or std::binary_search(moduleIDs_.begin(), moduleIDs_.end(), iID));
0199 }
0200 std::vector<std::string> moduleNames_;
0201 std::vector<int> moduleIDs_;
0202 unsigned int nEventsToSkip_ = 0;
0203 std::atomic<unsigned int> nEventsStarted_{0};
0204 edm::service::moduleAlloc::Filter filter_;
0205 };
0206
0207 DEFINE_FWK_SERVICE(ModuleAllocMonitor);