16 #include <type_traits> 19 #pragma GCC diagnostic push 20 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 21 #include <boost/graph/adjacency_list.hpp> 22 #include <boost/graph/graphviz.hpp> 23 #include <boost/graph/lookup_edge.hpp> 24 #pragma GCC diagnostic pop 45 std::unordered_set<T> make_unordered_set(std::vector<T> && entries) {
46 std::unordered_set<T> u;
68 return (m_highlightModules.find(module) != m_highlightModules.end());
83 const char * module_type_desc[] {
95 const char * shapes[] {
123 boost::subgraph<boost::adjacency_list<
133 boost::property<boost::edge_index_t,
int,
134 boost::property<boost::edge_attribute_t, GraphvizAttributes>>,
137 boost::property<boost::graph_graph_attribute_t, GraphvizAttributes,
138 boost::property<boost::graph_vertex_attribute_t, GraphvizAttributes,
139 boost::property<boost::graph_edge_attribute_t, GraphvizAttributes>>>>
167 EDMModuleType::ESSource,
169 EDMModuleType::EDAnalyzer,
170 EDMModuleType::EDProducer,
171 EDMModuleType::EDFilter,
172 EDMModuleType::OutputModule
174 if (t == module_type_desc[
static_cast<std::underlying_type_t<EDMModuleType>
>(
v)])
183 return module_type_desc[
static_cast<std::underlying_type_t<EDMModuleType>
>(edmModuleTypeEnum(module))];
192 desc.
addUntracked<std::vector<std::string>>(
"highlightModules", {});
194 descriptions.
add(
"DependencyGraph", desc);
199 m_filename( config.getUntrackedParameter<
std::
string>(
"fileName") ),
200 m_highlightModules( make_unordered_set(config.getUntrackedParameter<
std::vector<
std::
string>>(
"highlightModules")) ),
201 m_showPathDependencies( config.getUntrackedParameter<bool>(
"showPathDependencies") ),
202 m_initialized(
false )
211 template <
typename I>
215 using std::pair<I, I>::pair;
221 template <
typename I>
237 attributes[
"style"] =
"filled";
238 attributes[
"color"] =
"black";
249 <<
"You have requested an instance of the DependencyGraph Service in the \"" << context.
processName()
250 <<
"\" SubProcess, which is not supported.\nPlease move it to the main process.";
257 boost::get_property(
m_graph, boost::graph_graph_attribute)[
"label"] =
"process " + context.
processName();
258 boost::get_property(
m_graph, boost::graph_graph_attribute)[
"labelloc"] =
"top";
262 for (
size_t i = 0;
i <
size; ++
i)
271 boost::get_property(
graph, boost::graph_name) =
"cluster" + context.
processName();
272 boost::get_property(
graph, boost::graph_graph_attribute)[
"label"] =
"subprocess " + context.
processName();
273 boost::get_property(
graph, boost::graph_graph_attribute)[
"labelloc"] =
"top";
277 for (
size_t i = 0;
i <
size; ++
i)
278 boost::add_vertex(
graph);
286 attributes[
"label"] =
module->moduleLabel();
287 attributes[
"tooltip"] =
module->moduleName();
289 attributes[
"style"] =
"filled";
290 attributes[
"color"] =
"black";
291 attributes[
"fillcolor"] =
highlighted(
module->moduleLabel()) ?
"green" :
"lightgrey";
295 auto const & paths = pathsAndConsumes.
paths();
296 auto const & endps = pathsAndConsumes.
endPaths();
301 edm::LogInfo(
"DependencyGraph") <<
"module " << consumer->moduleLabel() <<
" depends on module " <<
module->moduleLabel();
302 auto edge_status = boost::add_edge(consumer->id(),
module->id(),
m_graph);
305 auto const & edge = edge_status.first;
307 attributes[
"color"] =
"darkgreen";
314 for (
unsigned int i = 0;
i < paths.size(); ++
i) {
319 attributes[
"fillcolor"] =
highlighted(
module->moduleLabel()) ?
"lightgreen" :
"white";
322 auto edge_status = boost::lookup_edge(
module->id(), previous->
id(),
m_graph);
323 bool found = edge_status.second;
326 auto const & edge = edge_status.first;
328 attributes[
"style"] =
"dashed";
331 attributes[
"color"] =
"darkgreen";
337 for (
unsigned int i = 0;
i < endps.size(); ++
i) {
342 attributes[
"fillcolor"] =
highlighted(
module->moduleLabel()) ?
"lightgreen" :
"white";
345 auto edge_status = boost::lookup_edge(
module->id(), previous->
id(),
m_graph);
346 bool found = edge_status.second;
349 auto const & edge = edge_status.first;
351 attributes[
"style"] =
"dashed";
354 attributes[
"color"] =
"darkgreen";
370 boost::write_graphviz(
std::string const & processName() const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
iterator_pair_as_a_range< I > make_range(std::pair< I, I > p)
void watchPreSourceConstruction(PreSourceConstruction::slot_type const &iSlot)
void preBeginJob(PathsAndConsumesOfModulesBase const &, ProcessContext const &)
std::vector< ModuleDescription const * > const & modulesOnEndPath(unsigned int endPathIndex) const
std::string const & moduleName() const
std::vector< ModuleDescription const * > const & modulesOnPath(unsigned int pathIndex) const
std::string const & moduleLabel() const
std::vector< ModuleDescription const * > const & allModules() const
std::vector< std::string > const & endPaths() const
U second(std::pair< T, U > const &p)
std::map< std::string, std::string > GraphvizAttributes
void preSourceConstruction(ModuleDescription const &)
const std::complex< double > I
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
boost::subgraph< boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, boost::property< boost::vertex_attribute_t, GraphvizAttributes, node >, boost::property< boost::edge_index_t, int, boost::property< boost::edge_attribute_t, GraphvizAttributes > >, boost::property< boost::graph_name_t, std::string, boost::property< boost::graph_graph_attribute_t, GraphvizAttributes, boost::property< boost::graph_vertex_attribute_t, GraphvizAttributes, boost::property< boost::graph_edge_attribute_t, GraphvizAttributes > > > > > > m_graph
static const char * edmModuleType(edm::ModuleDescription const &module)
std::unordered_set< std::string > m_highlightModules
#define DEFINE_FWK_SERVICE(type)
bool m_showPathDependencies
bool isProcessWideService(ZombieKillerService const *)
static EDMModuleType edmModuleTypeEnum(edm::ModuleDescription const &module)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::vector< ModuleDescription const * > const & modulesWhoseProductsAreConsumedBy(unsigned int moduleID) const
void watchPreBeginJob(PreBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
DependencyGraph(const ParameterSet &, ActivityRegistry &)
std::vector< std::string > const & paths() const
static const char * shapes[]
ParameterSetID const & parameterSetID() const
bool highlighted(std::string const &module)
static const char * module_type_desc[]
bool isSubProcess() const
T get(const Candidate &c)
static Registry * instance()
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal