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 26 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 48 of file ProcessCallGraph.h.

Constructor & Destructor Documentation

ProcessCallGraph::ProcessCallGraph ( )

Definition at line 33 of file ProcessCallGraph.cc.

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

34 {
35 }

Member Function Documentation

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

Definition at line 220 of file ProcessCallGraph.cc.

References colors, graph_, mps_fire::i, size(), and primaryVertexAssociation_cfi::vertices.

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

221 {
222  std::vector<unsigned int> colors(boost::num_vertices(graph_));
223  auto colormap = boost::make_container_vertex_map(colors);
224 
225  // first, find and count all the path's modules' dependencies
226  boost::default_dfs_visitor visitor;
227  for (unsigned int module: path)
228  boost::depth_first_visit(graph_, module, visitor, colormap);
229 
230  unsigned int size = 0;
231  for (unsigned int i = 0; i < colors.size(); ++i)
232  if (colors[i] == 0)
233  ++size;
234 
235  // allocate the output vectors
236  std::vector<unsigned int> dependencies(size);
237  dependencies.resize(0);
238  std::vector<unsigned int> indices(path.size());
239  indices.resize(0);
240 
241  // reset the color map
242  for (unsigned int i = 0; i < colors.size(); ++i)
243  colors[i] = 0;
244 
245  // find again all the dependencies, and record those associated to each module
246  struct record_vertices : boost::default_dfs_visitor {
247  record_vertices(std::vector<unsigned int> & vertices) :
248  vertices_(vertices) { }
249 
250  void discover_vertex(unsigned int vertex, GraphType const& graph) {
251  vertices_.push_back(vertex);
252  }
253 
254  std::vector<unsigned int> & vertices_;
255  };
256  record_vertices recorder(dependencies);
257 
258  for (unsigned int module: path) {
259  // skip modules that have already been added as dependencies
260  if (colors[module] != boost::black_color)
261  boost::depth_first_visit(graph_, module, recorder, colormap);
262  indices.push_back(dependencies.size());
263  }
264 
265  return std::make_pair(dependencies, indices);
266 
267 }
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: adjgraph.h:12
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 189 of file ProcessCallGraph.cc.

References colors, dependencies(), graph_, mps_fire::i, and size().

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

190 {
191  std::vector<unsigned int> colors(boost::num_vertices(graph_));
192  auto colormap = boost::make_container_vertex_map(colors);
193 
194  // depht-first visit all vertices starting from the given module
195  boost::default_dfs_visitor visitor;
196  boost::depth_first_visit(graph_, module, visitor, colormap);
197 
198  // count the visited vertices (the `black' ones) in order to properly size the
199  // output vector; then fill the dependencies with the list of visited nodes
200  unsigned int size = 0;
201  for (unsigned int i = 0; i < colors.size(); ++i)
202  if (boost::black_color == colors[i])
203  ++size;
204  std::vector<unsigned int> dependencies(size);
205  unsigned j = 0;
206  for (unsigned int i = 0; i < colors.size(); ++i)
207  if (boost::black_color == colors[i])
208  dependencies[j++] = i;
209  assert(size == j);
210 
211  return dependencies;
212 }
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 181 of file ProcessCallGraph.cc.

References graph_, and module().

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

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

Definition at line 75 of file ProcessCallGraph.cc.

References edm::PathsAndConsumesOfModulesBase::allModules(), dependencies(), symbols::deps, edm::edmModuleTypeEnum(), edm::PathsAndConsumesOfModulesBase::endPaths(), graph_, mps_fire::i, edm::ProcessContext::isSubProcess(), module(), ErrorSummaryFilter_cfi::modules, edm::PathsAndConsumesOfModulesBase::modulesOnEndPath(), edm::PathsAndConsumesOfModulesBase::modulesOnPath(), edm::PathsAndConsumesOfModulesBase::modulesWhoseProductsAreConsumedBy(), edm::ProcessContext::parentProcessContext(), edm::PathsAndConsumesOfModulesBase::paths(), sysUtil::pid, process_description_, processId(), edm::ProcessContext::processName(), registerProcess(), and size().

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

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

References graph_, edm::ModuleDescription::id(), edm::kSource, module(), and source_.

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

60 {
61  // keep track of the Source module id
62  source_ = module.id();
63 
64  // create graph vertex for the source module
65  boost::add_vertex(graph_);
66  graph_.m_graph[module.id()] = { module, edm::EDMModuleType::kSource, true };
67 }
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 334 of file ProcessCallGraph.cc.

References sysUtil::pid, process_description_, and processId().

335 {
336  unsigned int pid = processId(context);
337  return process_description_[pid];
338 }
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 342 of file ProcessCallGraph.cc.

References sysUtil::pid, process_description_, and processId().

343 {
344  unsigned int pid = processId(processName);
345  return process_description_[pid];
346 }
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 297 of file ProcessCallGraph.cc.

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

Referenced by FastTimerService::postEvent(), FastTimerService::postPathEvent(), preBeginJob(), FastTimerService::prePathEvent(), processDescription(), ProcessCallGraph::ProcessType::ProcessType(), FastTimerService::queryEventTime(), and FastTimerService::queryPathTime().

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

Definition at line 309 of file ProcessCallGraph.cc.

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

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

Definition at line 271 of file ProcessCallGraph.cc.

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

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

272 {
273  static unsigned int s_id = 0;
274 
275  // registerProcess (called by preBeginJob) must be called for the parent process before its subprocess(es)
276  if (context.isSubProcess() and process_id_.find(context.parentProcessContext().processName()) == process_id_.end()) {
278  << "ProcessCallGraph::preBeginJob(): called for subprocess \"" << context.processName() << "\""
279  << " before being called for its parent process \"" << context.parentProcessContext().processName() << "\"";
280  }
281 
282  // registerProcess (called by preBeginJob) should be called once or each (sub)process
283  auto id = process_id_.find(context.processName());
284  if (id != process_id_.end()) {
286  << "ProcessCallGraph::preBeginJob(): called twice for the same "
287  << (context.isSubProcess() ? "subprocess" : "process") << " " << context.processName();
288  }
289 
290  std::tie(id, std::ignore) = process_id_.insert(std::make_pair(context.processName(), s_id++));
291  return id->second;
292 }
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
std::vector<ProcessType> ProcessCallGraph::process_description_
private

Definition at line 195 of file ProcessCallGraph.h.

Referenced by preBeginJob(), processDescription(), and processes().

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

Definition at line 192 of file ProcessCallGraph.h.

Referenced by processId(), and registerProcess().

unsigned int ProcessCallGraph::source_
private