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;
71 "Unknown",
"Source",
"ESSource",
"ESProducer",
"EDAnalyzer",
"EDProducer",
"EDFilter",
"OutputModule"};
73 static constexpr
const char *shapes[]{
99 boost::subgraph<boost::adjacency_list<
106 boost::property<boost::vertex_attribute_t,
110 boost::property<boost::edge_index_t,
112 boost::property<boost::edge_attribute_t, GraphvizAttributes>>,
117 boost::property<boost::graph_graph_attribute_t,
119 boost::property<boost::graph_vertex_attribute_t,
121 boost::property<boost::graph_edge_attribute_t, GraphvizAttributes>>>>>>
137 auto const &
pset = *registry.getMapped(
module.parameterSetID());
144 EDMModuleType::ESSource,
146 EDMModuleType::EDAnalyzer,
147 EDMModuleType::EDProducer,
148 EDMModuleType::EDFilter,
149 EDMModuleType::OutputModule}) {
163 desc.addUntracked<std::vector<std::string>>(
"highlightModules", {});
164 desc.addUntracked<
bool>(
"showPathDependencies",
true);
165 descriptions.
add(
"DependencyGraph",
desc);
172 m_showPathDependencies(
config.getUntrackedParameter<
bool>(
"showPathDependencies")),
173 m_initialized(
false) {
180 template <
typename I>
183 using std::pair<I, I>::pair;
189 template <
typename I>
200 attributes[
"label"] =
module.moduleLabel();
201 attributes[
"tooltip"] =
module.moduleName();
203 attributes[
"style"] =
"filled";
204 attributes[
"color"] =
"black";
205 attributes[
"fillcolor"] =
highlighted(
module.moduleLabel()) ?
"lightgreen" :
"white";
212 edm::LogError(
"DependencyGraph") <<
"You have requested an instance of the DependencyGraph Service in the \"" 214 <<
"\" SubProcess, which is not supported.\nPlease move it to the main process.";
218 if (not
context.isSubProcess()) {
220 boost::get_property(
m_graph, boost::graph_name) =
context.processName();
221 boost::get_property(
m_graph, boost::graph_graph_attribute)[
"label"] =
"process " +
context.processName();
222 boost::get_property(
m_graph, boost::graph_graph_attribute)[
"labelloc"] =
"top";
226 for (
size_t i = 0;
i <
size; ++
i)
232 auto &graph =
m_graph.create_subgraph();
235 boost::get_property(graph, boost::graph_name) =
"cluster" +
context.processName();
236 boost::get_property(graph, boost::graph_graph_attribute)[
"label"] =
"subprocess " +
context.processName();
237 boost::get_property(graph, boost::graph_graph_attribute)[
"labelloc"] =
"top";
241 for (
size_t i = 0;
i <
size; ++
i)
242 boost::add_vertex(graph);
251 attributes[
"label"] =
module->moduleLabel();
252 attributes[
"tooltip"] =
module->moduleName();
254 attributes[
"style"] =
"filled";
255 attributes[
"color"] =
"black";
256 attributes[
"fillcolor"] =
highlighted(
module->moduleLabel()) ?
"green" :
"lightgrey";
261 auto const &endps = pathsAndConsumes.
endPaths();
266 edm::LogInfo(
"DependencyGraph") <<
"module " <<
consumer->moduleLabel() <<
" depends on module " 271 auto const &edge = edge_status.first;
273 attributes[
"color"] =
"darkgreen";
280 for (
unsigned int i = 0;
i <
paths.size(); ++
i) {
285 attributes[
"fillcolor"] =
highlighted(
module->moduleLabel()) ?
"lightgreen" :
"white";
287 edm::LogInfo(
"DependencyGraph") <<
"module " <<
module->moduleLabel() <<
" follows module " 288 <<
previous->moduleLabel() <<
" in Path " <<
i;
290 bool found = edge_status.second;
293 auto const &edge = edge_status.first;
295 edgeAttributes[
"style"] =
"dashed";
298 edgeAttributes[
"color"] =
"darkgreen";
304 for (
unsigned int i = 0;
i < endps.size(); ++
i) {
309 attributes[
"fillcolor"] =
highlighted(
module->moduleLabel()) ?
"lightgreen" :
"white";
311 edm::LogInfo(
"DependencyGraph") <<
"module " <<
module->moduleLabel() <<
" follows module " 312 <<
previous->moduleLabel() <<
" in EndPath " <<
i;
314 bool found = edge_status.second;
317 auto const &edge = edge_status.first;
319 edgeAttributes[
"style"] =
"dashed";
322 edgeAttributes[
"color"] =
"darkgreen";
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
std::vector< ModuleDescription const * > const & allModules() const
unsigned int largestModuleID() const
std::vector< ModuleDescription const * > const & modulesOnPath(unsigned int pathIndex) const
bool isProcessWideService(TFileService const *)
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 &)
constexpr const char * module_type_desc[]
Log< level::Error, false > LogError
std::vector< std::string > const & endPaths() const
EDMModuleType edmModuleTypeEnum(edm::ModuleDescription const &module)
std::vector< ModuleDescription const * > const & modulesOnEndPath(unsigned int endPathIndex) const
U second(std::pair< T, U > const &p)
static constexpr const char * module_type_desc[]
std::map< std::string, std::string > GraphvizAttributes
void preSourceConstruction(ModuleDescription const &)
const std::complex< double > I
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static const char * edmModuleType(edm::ModuleDescription const &module)
std::unordered_set< std::string > m_highlightModules
Log< level::Info, false > LogInfo
#define DEFINE_FWK_SERVICE(type)
bool m_showPathDependencies
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static EDMModuleType edmModuleTypeEnum(edm::ModuleDescription const &module)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void watchPreBeginJob(PreBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
DependencyGraph(const ParameterSet &, ActivityRegistry &)
static constexpr const char * shapes[]
std::vector< ModuleDescription const * > const & modulesWhoseProductsAreConsumedBy(unsigned int moduleID, BranchType branchType=InEvent) const
bool highlighted(std::string const &module)
const char * edmModuleType(edm::ModuleDescription const &module)
static Registry * instance()
std::vector< std::string > const & paths() const
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal