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 ()=default
 
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_ = edm::ModuleDescription::invalidID()
 

Detailed Description

Definition at line 27 of file ProcessCallGraph.h.

Member Typedef Documentation

◆ GraphType

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::ProcessCallGraph ( )
default

Member Function Documentation

◆ dependencies()

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

Definition at line 185 of file ProcessCallGraph.cc.

References colors, graph_, dqmdumpme::indices, module(), castor_dqm_sourceclient_file_cfg::path, size(), bphysicsOniaDQM_cfi::vertex, and AlignmentTracksFromVertexSelector_cfi::vertices.

Referenced by depends(), and preBeginJob().

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

◆ depends()

std::vector< unsigned int > ProcessCallGraph::depends ( unsigned int  module) const

Definition at line 156 of file ProcessCallGraph.cc.

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

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

◆ module()

edm::ModuleDescription const & ProcessCallGraph::module ( unsigned int  module) const

Definition at line 146 of file ProcessCallGraph.cc.

References graph_.

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

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

◆ operator[]()

ProcessCallGraph::NodeType const & ProcessCallGraph::operator[] ( unsigned int  module) const

Definition at line 151 of file ProcessCallGraph.cc.

References graph_, and module().

151  {
152  return graph_.m_graph[module];
153 }
edm::ModuleDescription const & module(unsigned int module) const

◆ preBeginJob()

void ProcessCallGraph::preBeginJob ( edm::PathsAndConsumesOfModulesBase const &  pathsAndConsumes,
edm::ProcessContext const &  context 
)

Definition at line 62 of file ProcessCallGraph.cc.

References edm::PathsAndConsumesOfModulesBase::allModules(), cms::cuda::assert(), OfflineOutput_cfi::consumer, visDQMUpload::context, 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::ModuleDescription::invalidID(), edm::PathsAndConsumesOfModulesBase::largestModuleID(), module(), LogMessageMonitor_cff::modules, edm::PathsAndConsumesOfModulesBase::modulesOnEndPath(), edm::PathsAndConsumesOfModulesBase::modulesOnPath(), edm::PathsAndConsumesOfModulesBase::modulesWhoseProductsAreConsumedBy(), Skims_PA_cff::paths, edm::PathsAndConsumesOfModulesBase::paths(), process_description_, processId(), registerProcess(), size(), and source_.

Referenced by NVProfilerService::preBeginJob().

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

◆ preSourceConstruction()

void ProcessCallGraph::preSourceConstruction ( edm::ModuleDescription const &  module)

Definition at line 47 of file ProcessCallGraph.cc.

References cms::cuda::assert(), graph_, edm::ModuleDescription::id(), edm::ModuleDescription::invalidID(), edm::kSource, module(), and source_.

Referenced by NVProfilerService::preSourceConstruction().

47  {
48  // check that the Source has not already been added
50 
51  // keep track of the Source module id
52  source_ = module.id();
53 
54  // create graph vertex for the source module
55  boost::add_vertex(graph_);
56  graph_.m_graph[module.id()] = {module, edm::EDMModuleType::kSource, true};
57 }
assert(be >=bs)
edm::ModuleDescription const & module(unsigned int module) const
unsigned int id() const
static constexpr unsigned int invalidID()
Returns a value identifying an invalid id (the max unsigned int value)
unsigned int source_

◆ processDescription() [1/3]

ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( unsigned int  pid) const

Definition at line 279 of file ProcessCallGraph.cc.

References process_description_.

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

279  {
280  return process_description_.at(pid);
281 }
std::vector< ProcessType > process_description_

◆ processDescription() [2/3]

ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( edm::ProcessContext const &  context) const

Definition at line 284 of file ProcessCallGraph.cc.

References visDQMUpload::context, process_description_, and processId().

284  {
285  unsigned int pid = processId(context);
286  return process_description_[pid];
287 }
unsigned int processId(edm::ProcessContext const &) const
std::vector< ProcessType > process_description_

◆ processDescription() [3/3]

ProcessCallGraph::ProcessType const & ProcessCallGraph::processDescription ( std::string const &  processName) const

Definition at line 290 of file ProcessCallGraph.cc.

References process_description_, processId(), and SimL1EmulatorRepack_CalouGT_cff::processName.

290  {
291  unsigned int pid = processId(processName);
292  return process_description_[pid];
293 }
unsigned int processId(edm::ProcessContext const &) const
std::vector< ProcessType > process_description_

◆ processes()

std::vector< ProcessCallGraph::ProcessType > const & ProcessCallGraph::processes ( ) const

◆ processId() [1/2]

unsigned int ProcessCallGraph::processId ( edm::ProcessContext const &  context) const

Definition at line 256 of file ProcessCallGraph.cc.

References visDQMUpload::context, edm::errors::LogicError, and process_id_.

Referenced by preBeginJob(), and processDescription().

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

◆ processId() [2/2]

unsigned int ProcessCallGraph::processId ( std::string const &  processName) const

Definition at line 267 of file ProcessCallGraph.cc.

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

267  {
268  auto id = process_id_.find(processName);
269  if (id == process_id_.end())
271  << "ProcessCallGraph::processId(): unexpected (sub)process " << processName;
272  return id->second;
273 }
std::unordered_map< std::string, unsigned int > process_id_

◆ registerProcess()

unsigned int ProcessCallGraph::registerProcess ( edm::ProcessContext const &  context)
private

Definition at line 232 of file ProcessCallGraph.cc.

References visDQMUpload::context, Exception, SequenceTypes::ignore(), edm::errors::LogicError, and process_id_.

Referenced by preBeginJob().

232  {
233  // registerProcess (called by preBeginJob) must be called for the parent process before its subprocess(es)
234  if (context.isSubProcess() and process_id_.find(context.parentProcessContext().processName()) == process_id_.end()) {
236  << "ProcessCallGraph::preBeginJob(): called for subprocess \"" << context.processName() << "\""
237  << " before being called for its parent process \"" << context.parentProcessContext().processName() << "\"";
238  }
239 
240  // registerProcess (called by preBeginJob) should be called once or each (sub)process
241  auto id = process_id_.find(context.processName());
242  if (id != process_id_.end()) {
244  << "ProcessCallGraph::preBeginJob(): called twice for the same "
245  << (context.isSubProcess() ? "subprocess" : "process") << " " << context.processName();
246  }
247 
248  // this assumes that registerProcess (called by preBeginJob) is not called concurrently from different threads
249  // otherwise, process_id_.size() should be replaces with an atomic counter
250  std::tie(id, std::ignore) = process_id_.insert(std::make_pair(context.processName(), process_id_.size()));
251  return id->second;
252 }
std::unordered_map< std::string, unsigned int > process_id_
def ignore(seq)

◆ size()

unsigned int ProcessCallGraph::size ( void  ) const

◆ source()

edm::ModuleDescription const & ProcessCallGraph::source ( ) const

Definition at line 143 of file ProcessCallGraph.cc.

References graph_, and source_.

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

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

Member Data Documentation

◆ graph_

GraphType ProcessCallGraph::graph_
private

◆ process_description_

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

Definition at line 181 of file ProcessCallGraph.h.

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

◆ process_id_

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

Definition at line 178 of file ProcessCallGraph.h.

Referenced by processId(), and registerProcess().

◆ source_

unsigned int ProcessCallGraph::source_ = edm::ModuleDescription::invalidID()
private