CMS 3D CMS Logo

List of all members | Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes
ProcessCallGraph Class Reference

#include <ProcessCallGraph.h>

Classes

struct  NodeType
 
struct  PathType
 
struct  ProcessType
 

Public Types

using GraphType = boost::subgraph< boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, NodeType, boost::property< boost::edge_index_t, int >, boost::property< boost::graph_name_t, std::string > >>
 

Public Member Functions

std::pair< std::vector< unsigned int >, std::vector< unsigned int > > dependencies (std::vector< unsigned int > const &path)
 
std::vector< unsigned int > depends (unsigned int module) const
 
edm::ModuleDescription const & module (unsigned int module) const
 
NodeType const & operator[] (unsigned int module) const
 
void preBeginJob (edm::PathsAndConsumesOfModulesBase const &, edm::ProcessContext const &)
 
void preSourceConstruction (edm::ModuleDescription const &)
 
 ProcessCallGraph ()
 
ProcessType const & processDescription (unsigned int) const
 
ProcessType const & processDescription (edm::ProcessContext const &) const
 
ProcessType const & processDescription (std::string const &) const
 
std::vector< ProcessType > const & processes () const
 
unsigned int processId (edm::ProcessContext const &) const
 
unsigned int processId (std::string const &) const
 
unsigned int size () const
 
edm::ModuleDescription const & source () const
 

Private Member Functions

unsigned int registerProcess (edm::ProcessContext const &)
 

Private Attributes

GraphType graph_
 
std::vector< ProcessTypeprocess_description_
 
std::unordered_map< std::string, unsigned int > process_id_
 
unsigned int source_
 

Detailed Description

Definition at line 27 of file ProcessCallGraph.h.

Member Typedef Documentation

using ProcessCallGraph::GraphType = boost::subgraph<boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, NodeType, boost::property<boost::edge_index_t, int>, boost::property<boost::graph_name_t, std::string> >>

Definition at line 49 of file ProcessCallGraph.h.

Constructor & Destructor Documentation

ProcessCallGraph::ProcessCallGraph ( )
default

Member Function Documentation

std::pair< std::vector< unsigned int >, std::vector< unsigned int > > ProcessCallGraph::dependencies ( std::vector< unsigned int > const &  path)

Definition at line 218 of file ProcessCallGraph.cc.

References create_public_lumi_plots::color, colors, symbols::dependencies, findQualityFiles::size, and electrons_cff::vertices.

Referenced by ProcessCallGraph::ProcessType::ProcessType().

219 {
220  std::vector<unsigned int> colors(boost::num_vertices(graph_));
221  auto colormap = boost::make_container_vertex_map(colors);
222 
223  // first, find and count all the path's modules' dependencies
224  boost::default_dfs_visitor visitor;
225  for (unsigned int module: path)
226  boost::depth_first_visit(graph_, module, visitor, colormap);
227 
228  unsigned int size = 0;
229  for (unsigned int color : colors)
230  if (color == 0)
231  ++size;
232 
233  // allocate the output vectors
234  std::vector<unsigned int> dependencies(size);
235  dependencies.resize(0);
236  std::vector<unsigned int> indices(path.size());
237  indices.resize(0);
238 
239  // reset the color map
240  for (unsigned int & color : colors)
241  color = 0;
242 
243  // find again all the dependencies, and record those associated to each module
244  struct record_vertices : boost::default_dfs_visitor {
245  record_vertices(std::vector<unsigned int> & vertices) :
246  vertices_(vertices) { }
247 
248  void discover_vertex(unsigned int vertex, GraphType const& graph) {
249  vertices_.push_back(vertex);
250  }
251 
252  std::vector<unsigned int> & vertices_;
253  };
254  record_vertices recorder(dependencies);
255 
256  for (unsigned int module: path) {
257  // skip modules that have already been added as dependencies
258  if (colors[module] != boost::black_color)
259  boost::depth_first_visit(graph_, module, recorder, colormap);
260  indices.push_back(dependencies.size());
261  }
262 
263  return std::make_pair(dependencies, indices);
264 
265 }
vector< Color_t > colors
boost::subgraph< boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, NodeType, boost::property< boost::edge_index_t, int >, boost::property< boost::graph_name_t, std::string > >> GraphType
Definition: colors.py:1
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > dependencies(std::vector< unsigned int > const &path)
unsigned int size() const
Definition: vlib.h:208
std::vector< unsigned int > ProcessCallGraph::depends ( unsigned int  module) const

Definition at line 187 of file ProcessCallGraph.cc.

References create_public_lumi_plots::color, colors, symbols::dependencies, mps_fire::i, and findQualityFiles::size.

Referenced by ProcessCallGraph::ProcessType::ProcessType().

188 {
189  std::vector<unsigned int> colors(boost::num_vertices(graph_));
190  auto colormap = boost::make_container_vertex_map(colors);
191 
192  // depht-first visit all vertices starting from the given module
193  boost::default_dfs_visitor visitor;
194  boost::depth_first_visit(graph_, module, visitor, colormap);
195 
196  // count the visited vertices (the `black' ones) in order to properly size the
197  // output vector; then fill the dependencies with the list of visited nodes
198  unsigned int size = 0;
199  for (unsigned int color : colors)
200  if (boost::black_color == color)
201  ++size;
202  std::vector<unsigned int> dependencies(size);
203  unsigned j = 0;
204  for (unsigned int i = 0; i < colors.size(); ++i)
205  if (boost::black_color == colors[i])
206  dependencies[j++] = i;
207  assert(size == j);
208 
209  return dependencies;
210 }
vector< Color_t > colors
Definition: colors.py:1
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > dependencies(std::vector< unsigned int > const &path)
unsigned int size() const
Definition: vlib.h:208
edm::ModuleDescription const & ProcessCallGraph::module ( unsigned int  module) const
ProcessCallGraph::NodeType const & ProcessCallGraph::operator[] ( unsigned int  module) const

Definition at line 179 of file ProcessCallGraph.cc.

References python.rootplot.argparse::module.

Referenced by ProcessCallGraph::ProcessType::ProcessType().

180 {
181  return graph_.m_graph[module];
182 }
edm::ModuleDescription const & module(unsigned int module) const
void ProcessCallGraph::preBeginJob ( edm::PathsAndConsumesOfModulesBase const &  pathsAndConsumes,
edm::ProcessContext const &  context 
)

Definition at line 73 of file ProcessCallGraph.cc.

References edm::PathsAndConsumesOfModulesBase::allModules(), symbols::dependencies, symbols::deps, edm::edmModuleTypeEnum(), edm::PathsAndConsumesOfModulesBase::endPaths(), mps_fire::i, edm::ProcessContext::isSubProcess(), python.rootplot.argparse::module, ErrorSummaryFilter_cfi::modules, edm::PathsAndConsumesOfModulesBase::modulesOnEndPath(), edm::PathsAndConsumesOfModulesBase::modulesOnPath(), edm::PathsAndConsumesOfModulesBase::modulesWhoseProductsAreConsumedBy(), edm::ProcessContext::parentProcessContext(), edm::PathsAndConsumesOfModulesBase::paths(), sysUtil::pid, edm::ProcessContext::processName(), and findQualityFiles::size.

Referenced by FastTimerService::preBeginJob(), and ProcessCallGraph::ProcessType::ProcessType().

74 {
75  unsigned int pid = registerProcess(context);
76 
77  // work on the full graph (for the main process) or a subgraph (for a subprocess)
78  GraphType & graph = context.isSubProcess() ? graph_.create_subgraph() : graph_.root();
79 
80  // set the graph name property to the process name
81  boost::get_property(graph, boost::graph_name) = context.processName();
82 
83  // create graph vertices associated to all modules in the process
84  auto size = pathsAndConsumes.allModules().size();
85  for (size_t i = 0; i < size; ++i)
86  boost::add_vertex(graph);
87 
88  // set the vertices properties (use the module id as the global index into the graph)
89  std::vector<unsigned int> modules;
90  modules.reserve(size);
91  for (edm::ModuleDescription const * module: pathsAndConsumes.allModules()) {
92  modules.push_back(module->id());
93  graph_.m_graph[module->id()] = { *module, edmModuleTypeEnum(*module), false };
94  }
95 
96  // add graph edges associated to module dependencies
97  for (edm::ModuleDescription const * consumer: pathsAndConsumes.allModules()) {
98  for (edm::ModuleDescription const * module: pathsAndConsumes.modulesWhoseProductsAreConsumedBy(consumer->id())) {
99  // module `consumer' depends on module `module'
100  boost::add_edge(consumer->id(), module->id(), graph_);
101  }
102  }
103 
104  // extract path names from the TriggerNamesService
106 
107  // extract the details of the paths and endpaths: name, modules on the path, and their dependencies
108  size = pathsAndConsumes.paths().size();
109  assert (tns.getTrigPaths().size() == size);
110  std::vector<PathType> paths;
111  paths.reserve(size);
112  for (unsigned int i = 0; i < size; ++i) {
113  std::vector<unsigned int> modules;
114  for (edm::ModuleDescription const * module: pathsAndConsumes.modulesOnPath(i)) {
115  modules.push_back(module->id());
116  // mark the modules in the Paths as scheduled
117  graph_.m_graph[module->id()].scheduled_ = true;
118  }
119  auto deps = dependencies(modules);
120  paths.emplace_back(tns.getTrigPath(i), modules, deps.first, deps.second);
121  }
122  size = pathsAndConsumes.endPaths().size();
123  std::vector<PathType> endPaths;
124  endPaths.reserve(size);
125  for (unsigned int i = 0; i < size; ++i) {
126  std::vector<unsigned int> modules;
127  for (edm::ModuleDescription const * module: pathsAndConsumes.modulesOnEndPath(i)) {
128  modules.push_back(module->id());
129  // mark the modules in the EndPaths as scheduled
130  graph_.m_graph[module->id()].scheduled_ = true;
131  }
132  auto deps = dependencies(modules);
133  endPaths.emplace_back(tns.getEndPath(i), modules, deps.first, deps.second);
134  }
135 
136  // store the description of process, modules and paths
137  process_description_.emplace_back(
138  context.processName(),
139  graph,
140  modules,
141  paths,
142  endPaths);
143  assert(process_description_.size() == pid+1);
144 
145  // attach a subprocess to its parent
146  if (context.isSubProcess()) {
147  unsigned int parent_pid = processId(context.parentProcessContext());
148  process_description_[parent_pid].subprocesses_.push_back(pid);
149  }
150 }
unsigned int registerProcess(edm::ProcessContext const &)
unsigned int processId(edm::ProcessContext const &) const
EDMModuleType edmModuleTypeEnum(edm::ModuleDescription const &module)
boost::subgraph< boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, NodeType, boost::property< boost::edge_index_t, int >, boost::property< boost::graph_name_t, std::string > >> GraphType
std::vector< ProcessType > process_description_
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > dependencies(std::vector< unsigned int > const &path)
unsigned int size() const
edm::ModuleDescription const & module(unsigned int module) const
Definition: vlib.h:208
void ProcessCallGraph::preSourceConstruction ( edm::ModuleDescription const &  module)

Definition at line 57 of file ProcessCallGraph.cc.

References edm::ModuleDescription::id(), edm::kSource, and python.rootplot.argparse::module.

Referenced by FastTimerService::preSourceConstruction(), and ProcessCallGraph::ProcessType::ProcessType().

58 {
59  // keep track of the Source module id
60  source_ = module.id();
61 
62  // create graph vertex for the source module
63  boost::add_vertex(graph_);
64  graph_.m_graph[module.id()] = { module, edm::EDMModuleType::kSource, true };
65 }
edm::ModuleDescription const & module(unsigned int module) const
unsigned int source_
Definition: vlib.h:208
ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( unsigned int  pid) const
ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( edm::ProcessContext const &  context) const

Definition at line 332 of file ProcessCallGraph.cc.

References sysUtil::pid.

333 {
334  unsigned int pid = processId(context);
335  return process_description_[pid];
336 }
unsigned int processId(edm::ProcessContext const &) const
std::vector< ProcessType > process_description_
ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( std::string const &  processName) const

Definition at line 340 of file ProcessCallGraph.cc.

References sysUtil::pid.

341 {
342  unsigned int pid = processId(processName);
343  return process_description_[pid];
344 }
unsigned int processId(edm::ProcessContext const &) const
std::vector< ProcessType > process_description_
std::vector< ProcessCallGraph::ProcessType > const & ProcessCallGraph::processes ( ) const
unsigned int ProcessCallGraph::processId ( edm::ProcessContext const &  context) const

Definition at line 295 of file ProcessCallGraph.cc.

References edm::ProcessContext::isSubProcess(), edm::errors::LogicError, and edm::ProcessContext::processName().

Referenced by FastTimerService::postEvent(), FastTimerService::postPathEvent(), FastTimerService::prePathEvent(), ProcessCallGraph::ProcessType::ProcessType(), and FastTimerService::querySourceTime().

296 {
297  auto id = process_id_.find(context.processName());
298  if (id == process_id_.end())
300  << "ProcessCallGraph::processId(): unexpected " << (context.isSubProcess() ? "subprocess" : "process") << " " << context.processName();
301  return id->second;
302 }
std::unordered_map< std::string, unsigned int > process_id_
unsigned int ProcessCallGraph::processId ( std::string const &  processName) const

Definition at line 307 of file ProcessCallGraph.cc.

References edm::errors::LogicError, and modifiedElectrons_cfi::processName.

308 {
309  auto id = process_id_.find(processName);
310  if (id == process_id_.end())
312  << "ProcessCallGraph::processId(): unexpected (sub)process " << processName;
313  return id->second;
314 }
std::unordered_map< std::string, unsigned int > process_id_
unsigned int ProcessCallGraph::registerProcess ( edm::ProcessContext const &  context)
private

Definition at line 269 of file ProcessCallGraph.cc.

References Exception, SequenceTypes::ignore(), edm::ProcessContext::isSubProcess(), edm::errors::LogicError, edm::ProcessContext::parentProcessContext(), edm::ProcessContext::processName(), and s_id.

Referenced by ProcessCallGraph::ProcessType::ProcessType().

270 {
271  static unsigned int s_id = 0;
272 
273  // registerProcess (called by preBeginJob) must be called for the parent process before its subprocess(es)
274  if (context.isSubProcess() and process_id_.find(context.parentProcessContext().processName()) == process_id_.end()) {
276  << "ProcessCallGraph::preBeginJob(): called for subprocess \"" << context.processName() << "\""
277  << " before being called for its parent process \"" << context.parentProcessContext().processName() << "\"";
278  }
279 
280  // registerProcess (called by preBeginJob) should be called once or each (sub)process
281  auto id = process_id_.find(context.processName());
282  if (id != process_id_.end()) {
284  << "ProcessCallGraph::preBeginJob(): called twice for the same "
285  << (context.isSubProcess() ? "subprocess" : "process") << " " << context.processName();
286  }
287 
288  std::tie(id, std::ignore) = process_id_.insert(std::make_pair(context.processName(), s_id++));
289  return id->second;
290 }
std::unordered_map< std::string, unsigned int > process_id_
static const edm::ProductID s_id
Definition: EventBase.cc:27
def ignore(seq)
unsigned int ProcessCallGraph::size ( void  ) const
edm::ModuleDescription const & ProcessCallGraph::source ( ) const

Member Data Documentation

GraphType ProcessCallGraph::graph_
private

Definition at line 180 of file ProcessCallGraph.h.

Referenced by ProcessCallGraph::ProcessType::ProcessType().

std::vector<ProcessType> ProcessCallGraph::process_description_
private

Definition at line 189 of file ProcessCallGraph.h.

std::unordered_map<std::string, unsigned int> ProcessCallGraph::process_id_
private

Definition at line 186 of file ProcessCallGraph.h.

unsigned int ProcessCallGraph::source_
private

Definition at line 183 of file ProcessCallGraph.h.

Referenced by Config.Process::dumpConfig(), and Config.Process::dumpPython().