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