File indexing completed on 2023-07-12 01:18:42
0001 #ifndef FastTimerService_h
0002 #define FastTimerService_h
0003
0004
0005 #include <unistd.h>
0006 #include <pthread.h>
0007
0008
0009 #include <chrono>
0010 #include <cmath>
0011 #include <map>
0012 #include <mutex>
0013 #include <string>
0014 #include <unordered_map>
0015
0016
0017 #include <boost/chrono.hpp>
0018
0019
0020 #include <oneapi/tbb/concurrent_unordered_set.h>
0021 #include <oneapi/tbb/enumerable_thread_specific.h>
0022 #include <oneapi/tbb/task_scheduler_observer.h>
0023
0024
0025 #include <nlohmann/json_fwd.hpp>
0026 using json = nlohmann::json;
0027
0028
0029 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0030 #include "FWCore/ServiceRegistry/interface/Service.h"
0031 #include "FWCore/ServiceRegistry/interface/SystemBounds.h"
0032 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0033 #include "FWCore/ServiceRegistry/interface/PathContext.h"
0034 #include "FWCore/ServiceRegistry/interface/StreamContext.h"
0035 #include "FWCore/ServiceRegistry/interface/ProcessContext.h"
0036 #include "FWCore/ServiceRegistry/interface/GlobalContext.h"
0037 #include "FWCore/ServiceRegistry/interface/ESModuleCallingContext.h"
0038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0039 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0040 #include "FWCore/Framework/interface/TriggerNamesService.h"
0041 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0042 #include "DataFormats/Common/interface/HLTPathStatus.h"
0043 #include "DataFormats/Provenance/interface/EventID.h"
0044 #include "DataFormats/Provenance/interface/Timestamp.h"
0045 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0046 #include "DQMServices/Core/interface/DQMStore.h"
0047 #include "HLTrigger/Timer/interface/ProcessCallGraph.h"
0048
0049
0050
0051
0052
0053
0054
0055 class FastTimerService : public tbb::task_scheduler_observer {
0056 public:
0057 FastTimerService(const edm::ParameterSet&, edm::ActivityRegistry&);
0058 ~FastTimerService() override = default;
0059
0060 private:
0061 void ignoredSignal(const std::string& signal) const;
0062 void unsupportedSignal(const std::string& signal) const;
0063
0064
0065
0066 void preallocate(edm::service::SystemBounds const&);
0067
0068 void preBeginJob(edm::PathsAndConsumesOfModulesBase const&, edm::ProcessContext const&);
0069 void postBeginJob();
0070
0071 void postEndJob();
0072
0073 void preGlobalBeginRun(edm::GlobalContext const&);
0074 void postGlobalBeginRun(edm::GlobalContext const&);
0075
0076 void preGlobalEndRun(edm::GlobalContext const&);
0077 void postGlobalEndRun(edm::GlobalContext const&);
0078
0079 void preStreamBeginRun(edm::StreamContext const&);
0080 void postStreamBeginRun(edm::StreamContext const&);
0081
0082 void preStreamEndRun(edm::StreamContext const&);
0083 void postStreamEndRun(edm::StreamContext const&);
0084
0085 void preGlobalBeginLumi(edm::GlobalContext const&);
0086 void postGlobalBeginLumi(edm::GlobalContext const&);
0087
0088 void preGlobalEndLumi(edm::GlobalContext const&);
0089 void postGlobalEndLumi(edm::GlobalContext const&);
0090
0091 void preStreamBeginLumi(edm::StreamContext const&);
0092 void postStreamBeginLumi(edm::StreamContext const&);
0093
0094 void preStreamEndLumi(edm::StreamContext const&);
0095 void postStreamEndLumi(edm::StreamContext const&);
0096
0097 void preEvent(edm::StreamContext const&);
0098 void postEvent(edm::StreamContext const&);
0099
0100 void prePathEvent(edm::StreamContext const&, edm::PathContext const&);
0101 void postPathEvent(edm::StreamContext const&, edm::PathContext const&, edm::HLTPathStatus const&);
0102
0103 void preModuleEventPrefetching(edm::StreamContext const&, edm::ModuleCallingContext const&);
0104 void postModuleEventPrefetching(edm::StreamContext const&, edm::ModuleCallingContext const&);
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 void preSourceConstruction(edm::ModuleDescription const&);
0115
0116
0117 void preSourceRun(edm::RunIndex);
0118 void postSourceRun(edm::RunIndex);
0119
0120 void preSourceLumi(edm::LuminosityBlockIndex);
0121 void postSourceLumi(edm::LuminosityBlockIndex);
0122
0123 void preSourceEvent(edm::StreamID);
0124 void postSourceEvent(edm::StreamID);
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 void preModuleGlobalBeginRun(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0142 void postModuleGlobalBeginRun(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0143
0144 void preModuleGlobalEndRun(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0145 void postModuleGlobalEndRun(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0146
0147 void preModuleGlobalBeginLumi(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0148 void postModuleGlobalBeginLumi(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0149
0150 void preModuleGlobalEndLumi(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0151 void postModuleGlobalEndLumi(edm::GlobalContext const&, edm::ModuleCallingContext const&);
0152
0153 void preModuleStreamBeginRun(edm::StreamContext const&, edm::ModuleCallingContext const&);
0154 void postModuleStreamBeginRun(edm::StreamContext const&, edm::ModuleCallingContext const&);
0155
0156 void preModuleStreamEndRun(edm::StreamContext const&, edm::ModuleCallingContext const&);
0157 void postModuleStreamEndRun(edm::StreamContext const&, edm::ModuleCallingContext const&);
0158
0159 void preModuleStreamBeginLumi(edm::StreamContext const&, edm::ModuleCallingContext const&);
0160 void postModuleStreamBeginLumi(edm::StreamContext const&, edm::ModuleCallingContext const&);
0161
0162 void preModuleStreamEndLumi(edm::StreamContext const&, edm::ModuleCallingContext const&);
0163 void postModuleStreamEndLumi(edm::StreamContext const&, edm::ModuleCallingContext const&);
0164
0165 void preModuleEventAcquire(edm::StreamContext const&, edm::ModuleCallingContext const&);
0166 void postModuleEventAcquire(edm::StreamContext const&, edm::ModuleCallingContext const&);
0167
0168 void preModuleEvent(edm::StreamContext const&, edm::ModuleCallingContext const&);
0169 void postModuleEvent(edm::StreamContext const&, edm::ModuleCallingContext const&);
0170
0171 void preModuleEventDelayedGet(edm::StreamContext const&, edm::ModuleCallingContext const&);
0172 void postModuleEventDelayedGet(edm::StreamContext const&, edm::ModuleCallingContext const&);
0173
0174 void preEventReadFromSource(edm::StreamContext const&, edm::ModuleCallingContext const&);
0175 void postEventReadFromSource(edm::StreamContext const&, edm::ModuleCallingContext const&);
0176
0177 void preESModule(edm::eventsetup::EventSetupRecordKey const&, edm::ESModuleCallingContext const&);
0178 void postESModule(edm::eventsetup::EventSetupRecordKey const&, edm::ESModuleCallingContext const&);
0179
0180
0181 void on_scheduler_entry(bool worker) final;
0182 void on_scheduler_exit(bool worker) final;
0183
0184 public:
0185 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0186 static void fixForDQM(std::string& label);
0187
0188 private:
0189
0190 struct Resources;
0191 struct AtomicResources;
0192
0193
0194 struct Measurement {
0195 public:
0196 Measurement() noexcept;
0197
0198 void measure() noexcept;
0199
0200 void measure_and_store(Resources& store) noexcept;
0201
0202 void measure_and_accumulate(Resources& store) noexcept;
0203 void measure_and_accumulate(AtomicResources& store) noexcept;
0204
0205 public:
0206 #ifdef DEBUG_THREAD_CONCURRENCY
0207 std::thread::id id;
0208 #endif
0209 boost::chrono::thread_clock::time_point time_thread;
0210 boost::chrono::high_resolution_clock::time_point time_real;
0211 uint64_t allocated;
0212 uint64_t deallocated;
0213 };
0214
0215
0216 struct GroupOfModules {
0217 public:
0218 std::string label;
0219 std::vector<unsigned int> modules;
0220 };
0221
0222
0223 struct Resources {
0224 public:
0225 Resources();
0226 void reset();
0227
0228 Resources& operator+=(Resources const& other);
0229 Resources& operator+=(struct AtomicResources const& other);
0230 Resources operator+(Resources const& other) const;
0231 Resources operator+(struct AtomicResources const& other) const;
0232
0233 public:
0234 boost::chrono::nanoseconds time_thread;
0235 boost::chrono::nanoseconds time_real;
0236 uint64_t allocated;
0237 uint64_t deallocated;
0238 };
0239
0240
0241
0242 struct AtomicResources {
0243 public:
0244 AtomicResources();
0245 AtomicResources(AtomicResources const& other);
0246 void reset();
0247
0248 AtomicResources& operator=(AtomicResources const& other);
0249 AtomicResources& operator+=(AtomicResources const& other);
0250 AtomicResources& operator+=(Resources const& other);
0251 AtomicResources operator+(AtomicResources const& other) const;
0252 Resources operator+(Resources const& other) const;
0253
0254 public:
0255 std::atomic<boost::chrono::nanoseconds::rep> time_thread;
0256 std::atomic<boost::chrono::nanoseconds::rep> time_real;
0257 std::atomic<uint64_t> allocated;
0258 std::atomic<uint64_t> deallocated;
0259 };
0260
0261
0262
0263 struct ResourcesPerModule {
0264 public:
0265 ResourcesPerModule() noexcept;
0266 void reset() noexcept;
0267
0268 ResourcesPerModule& operator+=(ResourcesPerModule const& other);
0269 ResourcesPerModule operator+(ResourcesPerModule const& other) const;
0270
0271 public:
0272 Resources total;
0273 unsigned events;
0274 bool has_acquire;
0275 };
0276
0277 struct ResourcesPerPath {
0278 public:
0279 void reset();
0280 ResourcesPerPath& operator+=(ResourcesPerPath const& other);
0281 ResourcesPerPath operator+(ResourcesPerPath const& other) const;
0282
0283 public:
0284 Resources active;
0285 Resources total;
0286 unsigned last;
0287 bool status;
0288 };
0289
0290 struct ResourcesPerProcess {
0291 public:
0292 ResourcesPerProcess(ProcessCallGraph::ProcessType const& process);
0293 void reset();
0294 ResourcesPerProcess& operator+=(ResourcesPerProcess const& other);
0295 ResourcesPerProcess operator+(ResourcesPerProcess const& other) const;
0296
0297 public:
0298 Resources total;
0299 std::vector<ResourcesPerPath> paths;
0300 std::vector<ResourcesPerPath> endpaths;
0301 };
0302
0303 struct ResourcesPerJob {
0304 public:
0305 ResourcesPerJob() = default;
0306 ResourcesPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups);
0307 void reset();
0308 ResourcesPerJob& operator+=(ResourcesPerJob const& other);
0309 ResourcesPerJob operator+(ResourcesPerJob const& other) const;
0310
0311 public:
0312 Resources total;
0313 AtomicResources overhead;
0314 AtomicResources eventsetup;
0315 AtomicResources idle;
0316 Resources event;
0317 Measurement event_measurement;
0318 std::vector<Resources> highlight;
0319 std::vector<ResourcesPerModule> modules;
0320 std::vector<ResourcesPerProcess> processes;
0321 unsigned events;
0322 };
0323
0324
0325 struct PlotRanges {
0326 double time_range;
0327 double time_resolution;
0328 double memory_range;
0329 double memory_resolution;
0330 };
0331
0332
0333 class PlotsPerElement {
0334 public:
0335 PlotsPerElement() = default;
0336 void book(dqm::reco::DQMStore::IBooker&,
0337 std::string const& name,
0338 std::string const& title,
0339 PlotRanges const& ranges,
0340 unsigned int lumisections,
0341 bool byls);
0342 void fill(Resources const&, unsigned int lumisection);
0343 void fill(AtomicResources const&, unsigned int lumisection);
0344 void fill_fraction(Resources const&, Resources const&, unsigned int lumisection);
0345
0346 private:
0347
0348 dqm::reco::MonitorElement* time_thread_ = nullptr;
0349 dqm::reco::MonitorElement* time_thread_byls_ = nullptr;
0350 dqm::reco::MonitorElement* time_real_ = nullptr;
0351 dqm::reco::MonitorElement* time_real_byls_ = nullptr;
0352 dqm::reco::MonitorElement* allocated_ = nullptr;
0353 dqm::reco::MonitorElement* allocated_byls_ = nullptr;
0354 dqm::reco::MonitorElement* deallocated_ = nullptr;
0355 dqm::reco::MonitorElement* deallocated_byls_ = nullptr;
0356 };
0357
0358
0359 class PlotsPerPath {
0360 public:
0361 PlotsPerPath() = default;
0362 void book(dqm::reco::DQMStore::IBooker&,
0363 std::string const&,
0364 ProcessCallGraph const&,
0365 ProcessCallGraph::PathType const&,
0366 PlotRanges const& ranges,
0367 unsigned int lumisections,
0368 bool byls);
0369 void fill(ProcessCallGraph::PathType const&,
0370 ResourcesPerJob const&,
0371 ResourcesPerPath const&,
0372 unsigned int lumisection);
0373
0374 private:
0375
0376 PlotsPerElement total_;
0377
0378
0379
0380
0381
0382
0383
0384 dqm::reco::MonitorElement* module_counter_ = nullptr;
0385
0386 dqm::reco::MonitorElement* module_time_thread_total_ = nullptr;
0387 dqm::reco::MonitorElement* module_time_real_total_ = nullptr;
0388 dqm::reco::MonitorElement* module_allocated_total_ = nullptr;
0389 dqm::reco::MonitorElement* module_deallocated_total_ = nullptr;
0390 };
0391
0392 class PlotsPerProcess {
0393 public:
0394 PlotsPerProcess(ProcessCallGraph::ProcessType const&);
0395 void book(dqm::reco::DQMStore::IBooker&,
0396 ProcessCallGraph const&,
0397 ProcessCallGraph::ProcessType const&,
0398 PlotRanges const& event_ranges,
0399 PlotRanges const& path_ranges,
0400 unsigned int lumisections,
0401 bool bypath,
0402 bool byls);
0403 void fill(ProcessCallGraph::ProcessType const&, ResourcesPerJob const&, ResourcesPerProcess const&, unsigned int ls);
0404
0405 private:
0406
0407 PlotsPerElement event_;
0408
0409 std::vector<PlotsPerPath> paths_;
0410 std::vector<PlotsPerPath> endpaths_;
0411 };
0412
0413 class PlotsPerJob {
0414 public:
0415 PlotsPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups);
0416 void book(dqm::reco::DQMStore::IBooker&,
0417 ProcessCallGraph const&,
0418 std::vector<GroupOfModules> const&,
0419 PlotRanges const& event_ranges,
0420 PlotRanges const& path_ranges,
0421 PlotRanges const& module_ranges,
0422 unsigned int lumisections,
0423 bool bymodule,
0424 bool bypath,
0425 bool byls,
0426 bool transitions);
0427 void fill(ProcessCallGraph const&, ResourcesPerJob const&, unsigned int ls);
0428 void fill_run(AtomicResources const&);
0429 void fill_lumi(AtomicResources const&, unsigned int lumisection);
0430
0431 private:
0432
0433 PlotsPerElement event_;
0434 PlotsPerElement event_ex_;
0435 PlotsPerElement overhead_;
0436 PlotsPerElement idle_;
0437
0438 PlotsPerElement lumi_;
0439 PlotsPerElement run_;
0440
0441 std::vector<PlotsPerElement> highlight_;
0442
0443 std::vector<PlotsPerElement> modules_;
0444
0445 std::vector<PlotsPerProcess> processes_;
0446 };
0447
0448
0449 ProcessCallGraph callgraph_;
0450
0451
0452 std::vector<ResourcesPerJob> streams_;
0453
0454
0455 std::unique_ptr<PlotsPerJob> plots_;
0456
0457
0458 std::vector<AtomicResources> lumi_transition_;
0459 std::vector<AtomicResources> run_transition_;
0460
0461
0462 ResourcesPerJob job_summary_;
0463 std::vector<ResourcesPerJob> run_summary_;
0464 std::mutex summary_mutex_;
0465
0466
0467 struct ThreadGuard {
0468 struct specific_t {
0469 specific_t(AtomicResources& r) : resource_(r), live_(true) {}
0470 ~specific_t() = default;
0471
0472 Measurement measurement_;
0473 AtomicResources& resource_;
0474 std::atomic<bool> live_;
0475 };
0476
0477 ThreadGuard();
0478 ~ThreadGuard() = default;
0479
0480 static void retire_thread(void* t);
0481 static std::shared_ptr<specific_t>* ptr(void* p);
0482
0483 bool register_thread(FastTimerService::AtomicResources& r);
0484 Measurement& thread();
0485 void finalize();
0486
0487 tbb::concurrent_vector<std::shared_ptr<specific_t>> thread_resources_;
0488 pthread_key_t key_;
0489 };
0490
0491
0492 ThreadGuard guard_;
0493
0494
0495 std::unique_ptr<std::atomic<unsigned int>[]> subprocess_event_check_;
0496 std::unique_ptr<std::atomic<unsigned int>[]> subprocess_global_lumi_check_;
0497 std::unique_ptr<std::atomic<unsigned int>[]> subprocess_global_run_check_;
0498
0499
0500 Measurement& thread();
0501
0502
0503 unsigned int concurrent_lumis_;
0504 unsigned int concurrent_runs_;
0505 unsigned int concurrent_streams_;
0506 unsigned int concurrent_threads_;
0507
0508
0509 const bool print_event_summary_;
0510 const bool print_run_summary_;
0511 const bool print_job_summary_;
0512
0513
0514
0515
0516
0517 const bool write_json_summary_;
0518 const std::string json_filename_;
0519
0520
0521 bool enable_dqm_;
0522 const bool enable_dqm_bymodule_;
0523 const bool enable_dqm_bypath_;
0524 const bool enable_dqm_byls_;
0525 const bool enable_dqm_bynproc_;
0526 const bool enable_dqm_transitions_;
0527
0528 const PlotRanges dqm_event_ranges_;
0529 const PlotRanges dqm_path_ranges_;
0530 const PlotRanges dqm_module_ranges_;
0531 const unsigned int dqm_lumisections_range_;
0532 std::string dqm_path_;
0533
0534 std::vector<edm::ParameterSet> highlight_module_psets_;
0535 std::vector<GroupOfModules> highlight_modules_;
0536
0537
0538 mutable tbb::concurrent_unordered_set<std::string> unsupported_signals_;
0539
0540
0541 template <typename T>
0542 void printHeader(T& out, std::string const& label) const;
0543
0544 template <typename T>
0545 void printEventHeader(T& out, std::string const& label) const;
0546
0547 template <typename T>
0548 void printEventLine(T& out, Resources const& data, std::string const& label) const;
0549
0550 template <typename T>
0551 void printEventLine(T& out, AtomicResources const& data, std::string const& label) const;
0552
0553 template <typename T>
0554 void printEvent(T& out, ResourcesPerJob const&) const;
0555
0556 template <typename T>
0557 void printSummaryHeader(T& out, std::string const& label, bool detailed) const;
0558
0559 template <typename T>
0560 void printPathSummaryHeader(T& out, std::string const& label) const;
0561
0562 template <typename T>
0563 void printSummaryLine(T& out, Resources const& data, uint64_t events, std::string const& label) const;
0564
0565 template <typename T>
0566 void printSummaryLine(T& out, Resources const& data, uint64_t events, uint64_t active, std::string const& label) const;
0567
0568 template <typename T>
0569 void printSummaryLine(T& out, AtomicResources const& data, uint64_t events, std::string const& label) const;
0570
0571 template <typename T>
0572 void printSummaryLine(
0573 T& out, AtomicResources const& data, uint64_t events, uint64_t active, std::string const& label) const;
0574
0575 template <typename T>
0576 void printPathSummaryLine(
0577 T& out, Resources const& data, Resources const& total, uint64_t events, std::string const& label) const;
0578
0579 template <typename T>
0580 void printSummary(T& out, ResourcesPerJob const& data, std::string const& label) const;
0581
0582 template <typename T>
0583 void printTransition(T& out, AtomicResources const& data, std::string const& label) const;
0584
0585 template <typename T>
0586 json encodeToJSON(std::string const& type, std::string const& label, unsigned int events, T const& data) const;
0587
0588 json encodeToJSON(edm::ModuleDescription const& module, ResourcesPerModule const& data) const;
0589
0590 void writeSummaryJSON(ResourcesPerJob const& data, std::string const& filename) const;
0591
0592
0593 bool isFirstSubprocess(edm::StreamContext const&);
0594 bool isFirstSubprocess(edm::GlobalContext const&);
0595
0596
0597 bool isLastSubprocess(std::atomic<unsigned int>& check);
0598 };
0599
0600 #endif