Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-31 00:08:55

0001 #ifndef HLTrigger_Timer_interface_ProcessCallGraph_h
0002 #define HLTrigger_Timer_interface_ProcessCallGraph_h
0003 
0004 /*
0005  *
0006  */
0007 
0008 #include <iostream>
0009 #include <utility>
0010 #include <vector>
0011 #include <string>
0012 #include <type_traits>
0013 
0014 // boost optional (used by boost graph) results in some false positives with -Wmaybe-uninitialized
0015 #pragma GCC diagnostic push
0016 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0017 #include <boost/graph/adjacency_list.hpp>
0018 #include <boost/graph/lookup_edge.hpp>
0019 #include <boost/graph/subgraph.hpp>
0020 #pragma GCC diagnostic pop
0021 
0022 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0023 #include "FWCore/ServiceRegistry/interface/PathsAndConsumesOfModulesBase.h"
0024 #include "FWCore/ServiceRegistry/interface/ProcessContext.h"
0025 #include "HLTrigger/Timer/interface/EDMModuleType.h"
0026 
0027 class ProcessCallGraph {
0028 public:
0029   struct NodeType {
0030     edm::ModuleDescription module_;
0031     edm::EDMModuleType type_;
0032     bool scheduled_ = false;
0033   };
0034 
0035   // directed graph, with `NodeType` properties attached to each vertex
0036   using GraphType = boost::subgraph<boost::adjacency_list<
0037       // edge list
0038       boost::vecS,
0039       // vertex list
0040       boost::vecS,
0041       boost::directedS,
0042       // vertex properties
0043       NodeType,
0044       // edge propoerties, used internally by boost::subgraph
0045       boost::property<boost::edge_index_t, int>,
0046       // graph properties, used to name each boost::subgraph
0047       boost::property<boost::graph_name_t, std::string>>>;
0048 
0049   // store the details of each path: name, modules on the path, and their dependencies
0050   struct PathType {
0051     std::string name_;
0052     std::vector<unsigned int> modules_on_path_;
0053     std::vector<unsigned int> modules_and_dependencies_;
0054     std::vector<unsigned int>
0055         last_dependency_of_module_;  // one-after-the-last dependency of each module, as indices into modules_and_dependencies_
0056 
0057     PathType() = default;
0058 
0059     PathType(std::string name,
0060              std::vector<unsigned int> mop,
0061              std::vector<unsigned int> mad,
0062              std::vector<unsigned int> ldom)
0063         : name_(std::move(name)),
0064           modules_on_path_(std::move(mop)),
0065           modules_and_dependencies_(std::move(mad)),
0066           last_dependency_of_module_(std::move(ldom)) {}
0067 
0068     PathType(PathType const &other) = default;
0069 
0070     PathType(PathType &&other) = default;
0071 
0072     ~PathType() = default;
0073 
0074     PathType &operator=(PathType const &other) = default;
0075   };
0076 
0077   // store the details of each process: name, modules call subgraph, modules, paths and endpaths, subprocess pids
0078   struct ProcessType {
0079     std::string name_;
0080     GraphType const &graph_;
0081     std::vector<unsigned int> modules_;
0082     std::vector<PathType> paths_;
0083     std::vector<PathType> endPaths_;
0084     std::vector<unsigned int> subprocesses_;
0085 
0086     ProcessType() = delete;
0087 
0088     ProcessType(std::string name,
0089                 GraphType const &graph,
0090                 std::vector<unsigned int> modules,
0091                 std::vector<PathType> paths,
0092                 std::vector<PathType> endPaths,
0093                 std::vector<unsigned int> subprocesses = {})
0094         : name_(std::move(name)),
0095           graph_(graph),
0096           modules_(std::move(modules)),
0097           paths_(std::move(paths)),
0098           endPaths_(std::move(endPaths)),
0099           subprocesses_(std::move(subprocesses)) {}
0100 
0101     ProcessType(std::string &&name,
0102                 GraphType const &graph,
0103                 std::vector<unsigned int> &&modules,
0104                 std::vector<PathType> &&paths,
0105                 std::vector<PathType> &&endPaths,
0106                 std::vector<unsigned int> &&subprocesses = {})
0107         : name_(std::move(name)),
0108           graph_(graph),
0109           modules_(std::move(modules)),
0110           paths_(std::move(paths)),
0111           endPaths_(std::move(endPaths)),
0112           subprocesses_(std::move(subprocesses)) {}
0113 
0114     ProcessType(ProcessType const &other) = default;
0115     ProcessType(ProcessType &&other) = default;
0116 
0117     ProcessType &operator=(ProcessType const &other) = delete;
0118     ProcessType &operator=(ProcessType &&other) = delete;
0119   };
0120 
0121 public:
0122   // default c'tor
0123   ProcessCallGraph();
0124 
0125   // to be called from preSourceConstruction(...)
0126   void preSourceConstruction(edm::ModuleDescription const &);
0127 
0128   // to be called from preBeginJob(...)
0129   void preBeginJob(edm::PathsAndConsumesOfModulesBase const &, edm::ProcessContext const &);
0130 
0131   // number of modules stored in the call graph
0132   unsigned int size() const;
0133 
0134   // retrieve the ModuleDescription associated to the Source
0135   edm::ModuleDescription const &source() const;
0136 
0137   // retrieve the ModuleDescription associated to the given id
0138   edm::ModuleDescription const &module(unsigned int module) const;
0139 
0140   // retrieve the full information for a given module
0141   NodeType const &operator[](unsigned int module) const;
0142 
0143   // find the dependencies of the given module
0144   std::vector<unsigned int> depends(unsigned int module) const;
0145 
0146   // find the dependencies of all modules in the given path
0147   std::pair<std::vector<unsigned int>, std::vector<unsigned int>> dependencies(std::vector<unsigned int> const &path);
0148 
0149   // retrieve the "process id" of a process, given its ProcessContex
0150   unsigned int processId(edm::ProcessContext const &) const;
0151 
0152   // retrieve the "process id" of a process, given its name
0153   unsigned int processId(std::string const &) const;
0154 
0155   // retrieve the processes
0156   std::vector<ProcessType> const &processes() const;
0157 
0158   // retrieve information about a process, given its "process id"
0159   ProcessType const &processDescription(unsigned int) const;
0160 
0161   // retrieve information about a process, given its ProcessContex
0162   ProcessType const &processDescription(edm::ProcessContext const &) const;
0163 
0164   // retrieve information about a process, given its name
0165   ProcessType const &processDescription(std::string const &) const;
0166 
0167 private:
0168   // register a (sub)process and assigns it a "process id"
0169   unsigned int registerProcess(edm::ProcessContext const &);
0170 
0171 private:
0172   GraphType graph_;
0173 
0174   // module id of the Source
0175   unsigned int source_;
0176 
0177   // map each (sub)process name to a "process id"
0178   std::unordered_map<std::string, unsigned int> process_id_;
0179 
0180   // description of each process
0181   std::vector<ProcessType> process_description_;
0182 };
0183 
0184 #endif  // not defined HLTrigger_Timer_interface_ProcessCallGraph_h