CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 47 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 184 of file ProcessCallGraph.cc.

References colors, graph_, dqmdumpme::indices, module(), size(), and beam_dqm_sourceclient-live_cfg::vertices.

Referenced by depends(), and preBeginJob().

185  {
186  std::vector<unsigned int> colors(boost::num_vertices(graph_));
187  auto colormap = boost::make_container_vertex_map(colors);
188 
189  // first, find and count all the path's modules' dependencies
190  boost::default_dfs_visitor visitor;
191  for (unsigned int module : path)
192  boost::depth_first_visit(graph_, module, visitor, colormap);
193 
194  unsigned int size = 0;
195  for (unsigned int color : colors)
196  if (color == 0)
197  ++size;
198 
199  // allocate the output vectors
200  std::vector<unsigned int> dependencies(size);
201  dependencies.resize(0);
202  std::vector<unsigned int> indices(path.size());
203  indices.resize(0);
204 
205  // reset the color map
206  for (unsigned int& color : colors)
207  color = 0;
208 
209  // find again all the dependencies, and record those associated to each module
210  struct record_vertices : boost::default_dfs_visitor {
211  record_vertices(std::vector<unsigned int>& vertices) : vertices_(vertices) {}
212 
213  void discover_vertex(unsigned int vertex, GraphType const& graph) { vertices_.push_back(vertex); }
214 
215  std::vector<unsigned int>& vertices_;
216  };
217  record_vertices recorder(dependencies);
218 
219  for (unsigned int module : path) {
220  // skip modules that have already been added as dependencies
221  if (colors[module] != boost::black_color)
222  boost::depth_first_visit(graph_, module, recorder, colormap);
223  indices.push_back(dependencies.size());
224  }
225 
226  return std::make_pair(dependencies, indices);
227 }
vector< Color_t > colors
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
list indices
Definition: dqmdumpme.py:50
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< unsigned int > ProcessCallGraph::depends ( unsigned int  module) const

Definition at line 155 of file ProcessCallGraph.cc.

References cms::cuda::assert(), colors, dependencies(), graph_, mps_fire::i, dqmiolumiharvest::j, and size().

155  {
156  std::vector<unsigned int> colors(boost::num_vertices(graph_));
157  auto colormap = boost::make_container_vertex_map(colors);
158 
159  // depht-first visit all vertices starting from the given module
160  boost::default_dfs_visitor visitor;
161  boost::depth_first_visit(graph_, module, visitor, colormap);
162 
163  // count the visited vertices (the `black' ones) in order to properly size the
164  // output vector; then fill the dependencies with the list of visited nodes
165  unsigned int size = 0;
166  for (unsigned int color : colors)
167  if (boost::black_color == color)
168  ++size;
169  std::vector<unsigned int> dependencies(size);
170  unsigned j = 0;
171  for (unsigned int i = 0; i < colors.size(); ++i)
172  if (boost::black_color == colors[i])
173  dependencies[j++] = i;
174  assert(size == j);
175 
176  return dependencies;
177 }
assert(be >=bs)
vector< Color_t > colors
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
edm::ModuleDescription const & ProcessCallGraph::module ( unsigned int  module) const

Definition at line 145 of file ProcessCallGraph.cc.

References graph_.

Referenced by FastTimerService::PlotsPerJob::book(), dependencies(), operator[](), preBeginJob(), and preSourceConstruction().

145  {
146  return graph_.m_graph[module].module_;
147 }
edm::ModuleDescription const & module(unsigned int module) const
ProcessCallGraph::NodeType const & ProcessCallGraph::operator[] ( unsigned int  module) const

Definition at line 150 of file ProcessCallGraph.cc.

References graph_, and module().

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

Definition at line 64 of file ProcessCallGraph.cc.

References edm::PathsAndConsumesOfModulesBase::allModules(), cms::cuda::assert(), OfflineOutput_cfi::consumer, dependencies(), symbols::deps, edm::edmModuleTypeEnum(), edm::PathsAndConsumesOfModulesBase::endPaths(), edm::service::TriggerNamesService::getEndPath(), edm::service::TriggerNamesService::getTrigPath(), edm::service::TriggerNamesService::getTrigPaths(), graph_, mps_fire::i, edm::ModuleDescription::id(), edm::ProcessContext::isSubProcess(), edm::PathsAndConsumesOfModulesBase::largestModuleID(), module(), TrackingSourceConfig_Tier0_Cosmic_cff::modules, edm::PathsAndConsumesOfModulesBase::modulesOnEndPath(), edm::PathsAndConsumesOfModulesBase::modulesOnPath(), edm::PathsAndConsumesOfModulesBase::modulesWhoseProductsAreConsumedBy(), edm::ProcessContext::parentProcessContext(), edm::PathsAndConsumesOfModulesBase::paths(), mergeAndRegister::paths, process_description_, processId(), edm::ProcessContext::processName(), registerProcess(), size(), and edm::tns().

65  {
66  unsigned int pid = registerProcess(context);
67 
68  // work on the full graph (for the main process) or a subgraph (for a subprocess)
69  GraphType& graph = context.isSubProcess() ? graph_.create_subgraph() : graph_.root();
70 
71  // set the graph name property to the process name
72  boost::get_property(graph, boost::graph_name) = context.processName();
73 
74  // create graph vertices associated to all modules in the process
75  unsigned int size = pathsAndConsumes.largestModuleID() - boost::num_vertices(graph) + 1;
76  for (size_t i = 0; i < size; ++i)
77  boost::add_vertex(graph);
78 
79  // set the vertices properties (use the module id as the global index into the graph)
80  std::vector<unsigned int> modules;
81  modules.reserve(size);
82  for (edm::ModuleDescription const* module : pathsAndConsumes.allModules()) {
83  modules.push_back(module->id());
84  graph_.m_graph[module->id()] = {*module, edmModuleTypeEnum(*module), false};
85  }
86 
87  // add graph edges associated to module dependencies
88  for (edm::ModuleDescription const* consumer : pathsAndConsumes.allModules()) {
89  for (edm::ModuleDescription const* module : pathsAndConsumes.modulesWhoseProductsAreConsumedBy(consumer->id())) {
90  // module `consumer' depends on module `module'
91  boost::add_edge(consumer->id(), module->id(), graph_);
92  }
93  }
94 
95  // extract path names from the TriggerNamesService
97 
98  // extract the details of the paths and endpaths: name, modules on the path, and their dependencies
99  size = pathsAndConsumes.paths().size();
100  assert(tns.getTrigPaths().size() == size);
101  std::vector<PathType> paths;
102  paths.reserve(size);
103  for (unsigned int i = 0; i < size; ++i) {
104  std::vector<unsigned int> modules;
105  for (edm::ModuleDescription const* module : pathsAndConsumes.modulesOnPath(i)) {
106  modules.push_back(module->id());
107  // mark the modules in the Paths as scheduled
108  graph_.m_graph[module->id()].scheduled_ = true;
109  }
110  auto deps = dependencies(modules);
111  paths.emplace_back(tns.getTrigPath(i), modules, deps.first, deps.second);
112  }
113  size = pathsAndConsumes.endPaths().size();
114  std::vector<PathType> endPaths;
115  endPaths.reserve(size);
116  for (unsigned int i = 0; i < size; ++i) {
117  std::vector<unsigned int> modules;
118  for (edm::ModuleDescription const* module : pathsAndConsumes.modulesOnEndPath(i)) {
119  modules.push_back(module->id());
120  // mark the modules in the EndPaths as scheduled
121  graph_.m_graph[module->id()].scheduled_ = true;
122  }
123  auto deps = dependencies(modules);
124  endPaths.emplace_back(tns.getEndPath(i), modules, deps.first, deps.second);
125  }
126 
127  // store the description of process, modules and paths
128  process_description_.emplace_back(context.processName(), graph, modules, paths, endPaths);
129  assert(process_description_.size() == pid + 1);
130 
131  // attach a subprocess to its parent
132  if (context.isSubProcess()) {
133  unsigned int parent_pid = processId(context.parentProcessContext());
134  process_description_[parent_pid].subprocesses_.push_back(pid);
135  }
136 }
pathNames_ & tns()), endPathNames_(&tns.getEndPaths()), wantSummary_(tns.wantSummary()
Definition: Schedule.cc:691
unsigned int registerProcess(edm::ProcessContext const &)
std::string const & getTrigPath(size_type const i) const
unsigned int processId(edm::ProcessContext const &) const
assert(be >=bs)
EDMModuleType edmModuleTypeEnum(edm::ModuleDescription const &module)
std::vector< ProcessType > process_description_
tuple deps
Definition: symbols.py:61
std::string const & getEndPath(size_type const i) const
Strings const & getTrigPaths() const
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
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
unsigned int id() const
void ProcessCallGraph::preSourceConstruction ( edm::ModuleDescription const &  module)

Definition at line 51 of file ProcessCallGraph.cc.

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

51  {
52  // keep track of the Source module id
53  source_ = module.id();
54 
55  // create graph vertex for the source module
56  boost::add_vertex(graph_);
57  graph_.m_graph[module.id()] = {module, edm::EDMModuleType::kSource, true};
58 }
edm::ModuleDescription const & module(unsigned int module) const
unsigned int source_
unsigned int id() const
ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( unsigned int  pid) const

Definition at line 278 of file ProcessCallGraph.cc.

References process_description_.

Referenced by FastTimerService::PlotsPerJob::book(), and FastTimerService::PlotsPerJob::fill().

278  {
279  return process_description_.at(pid);
280 }
std::vector< ProcessType > process_description_
ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( edm::ProcessContext const &  context) const

Definition at line 283 of file ProcessCallGraph.cc.

References process_description_, and processId().

283  {
284  unsigned int pid = processId(context);
285  return process_description_[pid];
286 }
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 289 of file ProcessCallGraph.cc.

References process_description_, and processId().

289  {
290  unsigned int pid = processId(processName);
291  return process_description_[pid];
292 }
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 255 of file ProcessCallGraph.cc.

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

Referenced by preBeginJob(), and processDescription().

255  {
256  auto id = process_id_.find(context.processName());
257  if (id == process_id_.end())
259  << "ProcessCallGraph::processId(): unexpected " << (context.isSubProcess() ? "subprocess" : "process") << " "
260  << context.processName();
261  return id->second;
262 }
std::unordered_map< std::string, unsigned int > process_id_
unsigned int ProcessCallGraph::processId ( std::string const &  processName) const

Definition at line 266 of file ProcessCallGraph.cc.

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

266  {
267  auto id = process_id_.find(processName);
268  if (id == process_id_.end())
270  << "ProcessCallGraph::processId(): unexpected (sub)process " << processName;
271  return id->second;
272 }
std::unordered_map< std::string, unsigned int > process_id_
unsigned int ProcessCallGraph::registerProcess ( edm::ProcessContext const &  context)
private

Definition at line 231 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().

231  {
232  static unsigned int s_id = 0;
233 
234  // registerProcess (called by preBeginJob) must be called for the parent process before its subprocess(es)
235  if (context.isSubProcess() and process_id_.find(context.parentProcessContext().processName()) == process_id_.end()) {
237  << "ProcessCallGraph::preBeginJob(): called for subprocess \"" << context.processName() << "\""
238  << " before being called for its parent process \"" << context.parentProcessContext().processName() << "\"";
239  }
240 
241  // registerProcess (called by preBeginJob) should be called once or each (sub)process
242  auto id = process_id_.find(context.processName());
243  if (id != process_id_.end()) {
245  << "ProcessCallGraph::preBeginJob(): called twice for the same "
246  << (context.isSubProcess() ? "subprocess" : "process") << " " << context.processName();
247  }
248 
249  std::tie(id, std::ignore) = process_id_.insert(std::make_pair(context.processName(), s_id++));
250  return id->second;
251 }
std::unordered_map< std::string, unsigned int > process_id_
static const edm::ProductID s_id
Definition: EventBase.cc:27
unsigned int ProcessCallGraph::size ( void  ) const

Definition at line 139 of file ProcessCallGraph.cc.

References graph_.

Referenced by ntupleDataFormat._Collection::__iter__(), ntupleDataFormat._Collection::__len__(), dependencies(), depends(), and preBeginJob().

139 { return boost::num_vertices(graph_); }
edm::ModuleDescription const & ProcessCallGraph::source ( ) const

Definition at line 142 of file ProcessCallGraph.cc.

References graph_, and source_.

Referenced by FastTimerService::PlotsPerJob::book().

142 { return graph_.m_graph[source_].module_; }
unsigned int source_

Member Data Documentation

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

Definition at line 181 of file ProcessCallGraph.h.

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

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

Definition at line 178 of file ProcessCallGraph.h.

Referenced by processId(), and registerProcess().

unsigned int ProcessCallGraph::source_
private