1 |
|
---|
2 | //=======================================================================
|
---|
3 | template<typename Traits>
|
---|
4 | void PHX::EvaluatorManager<Traits>::
|
---|
5 | writeGraphvizFile(const std::string filename,
|
---|
6 | bool writeEvaluatedFields,
|
---|
7 | bool writeDependentFields,
|
---|
8 | bool debugRegisteredEvaluators) const
|
---|
9 | {
|
---|
10 | #if defined(BOOST_VERSION)&&(BOOST_VERSION>=104200)
|
---|
11 |
|
---|
12 | using std::string;
|
---|
13 | using std::vector;
|
---|
14 | using std::map;
|
---|
15 | using std::pair;
|
---|
16 | using Teuchos::RCP;
|
---|
17 | using PHX::FieldTag;
|
---|
18 |
|
---|
19 | TEST_FOR_EXCEPTION(!sorting_called_ && !debugRegisteredEvaluators, std::logic_error, "Error sorting of evaluators must be done before writing graphviz file.");
|
---|
20 |
|
---|
21 | // Create the Graph object and attribute vectors
|
---|
22 | typedef boost::GraphvizDigraph Graph;
|
---|
23 | Graph g_dot;
|
---|
24 |
|
---|
25 | boost::property_map<Graph,boost::vertex_attribute_t>::type
|
---|
26 | vertex_attr_map = get(boost::vertex_attribute, g_dot);
|
---|
27 |
|
---|
28 | boost::property_map<Graph,boost::edge_attribute_t>::type
|
---|
29 | edge_attr_map = get(boost::edge_attribute, g_dot);
|
---|
30 |
|
---|
31 | typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
|
---|
32 | typedef typename boost::graph_traits<Graph>::edge_descriptor edge_t;
|
---|
33 |
|
---|
34 | // link fields to their evaluators
|
---|
35 | std::vector< Teuchos::RCP<PHX::Evaluator<Traits> > > evaluators;
|
---|
36 | if (!debugRegisteredEvaluators) {
|
---|
37 | for (vector<int>::const_iterator index = providerEvalOrderIndex.begin();
|
---|
38 | index != providerEvalOrderIndex.end(); ++index)
|
---|
39 | evaluators.push_back(varProviders[*index]);
|
---|
40 | }
|
---|
41 | else{
|
---|
42 | evaluators = varProviders;
|
---|
43 | }
|
---|
44 |
|
---|
45 | map<string,vertex_t> field_to_evaluator_index;
|
---|
46 | vertex_t index = 0;
|
---|
47 | for (typename vector< RCP<PHX::Evaluator<Traits> > >::const_iterator
|
---|
48 | evaluator = evaluators.begin(); evaluator != evaluators.end();
|
---|
49 | ++evaluator, ++index) {
|
---|
50 |
|
---|
51 | const vector< RCP<FieldTag> >& eval_fields =
|
---|
52 | (*evaluator)->evaluatedFields();
|
---|
53 |
|
---|
54 | for (vector< RCP<FieldTag> >::const_iterator tag =
|
---|
55 | eval_fields.begin(); tag != eval_fields.end(); ++tag) {
|
---|
56 |
|
---|
57 | field_to_evaluator_index[(*tag)->identifier()] = index;
|
---|
58 |
|
---|
59 | }
|
---|
60 | }
|
---|
61 |
|
---|
62 | // Create an edgelist with unique edges (by insterting into a map)
|
---|
63 | map<string,pair<vertex_t,vertex_t> > graph_edges;
|
---|
64 | for (map<string,std::size_t>::const_iterator field =
|
---|
65 | field_to_evaluator_index.begin();
|
---|
66 | field != field_to_evaluator_index.end(); ++field) {
|
---|
67 |
|
---|
68 | const vector< RCP<FieldTag> >& dep_fields =
|
---|
69 | (evaluators[field->second])->dependentFields();
|
---|
70 |
|
---|
71 | for (vector< RCP<FieldTag> >::const_iterator dep_field =
|
---|
72 | dep_fields.begin(); dep_field != dep_fields.end(); ++dep_field) {
|
---|
73 |
|
---|
74 | // Only add the edge of the out node exists
|
---|
75 | map<string,vertex_t>::const_iterator search =
|
---|
76 | field_to_evaluator_index.find((*dep_field)->identifier());
|
---|
77 | if (search != field_to_evaluator_index.end()) {
|
---|
78 |
|
---|
79 | std::ostringstream edge_name;
|
---|
80 | edge_name << field->second << ":"
|
---|
81 | << field_to_evaluator_index[(*dep_field)->identifier()];
|
---|
82 |
|
---|
83 | graph_edges[edge_name.str()] = std::pair<vertex_t,vertex_t>
|
---|
84 | (field->second, field_to_evaluator_index[(*dep_field)->identifier()]);
|
---|
85 | }
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 |
|
---|
90 | // Create edge graph between evaluators
|
---|
91 | for (map<string,pair<vertex_t,vertex_t> >::const_iterator edge =
|
---|
92 | graph_edges.begin(); edge != graph_edges.end(); ++edge) {
|
---|
93 |
|
---|
94 | std::pair<edge_t, bool> boost_edge =
|
---|
95 | boost::add_edge(edge->second.first, edge->second.second, g_dot);
|
---|
96 | //boost::add_edge(0, 1, g_dot);
|
---|
97 |
|
---|
98 | edge_attr_map[boost_edge.first]["label"] = edge->first;
|
---|
99 | }
|
---|
100 |
|
---|
101 | boost::graph_traits<boost::GraphvizDigraph>::vertex_iterator vi, vi_end;
|
---|
102 | for (boost::tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi) {
|
---|
103 |
|
---|
104 | string label = evaluators[*vi]->getName();
|
---|
105 |
|
---|
106 | if (writeEvaluatedFields) {
|
---|
107 |
|
---|
108 | const vector< RCP<FieldTag> >& eval_fields =
|
---|
109 | (evaluators[*vi])->evaluatedFields();
|
---|
110 |
|
---|
111 | label += "\\n Evaluates:";
|
---|
112 | if (eval_fields.size() > 0) {
|
---|
113 | for (vector< RCP<FieldTag> >::const_iterator field =
|
---|
114 | eval_fields.begin(); field != eval_fields.end(); ++field) {
|
---|
115 | label += "\\n ";
|
---|
116 | label += (*field)->name()
|
---|
117 | + " : " + (*field)->dataLayout().identifier()
|
---|
118 | + " : " + Teuchos::demangleName((*field)->dataTypeInfo().name());
|
---|
119 | }
|
---|
120 | }
|
---|
121 | else
|
---|
122 | label += " None!";
|
---|
123 |
|
---|
124 | }
|
---|
125 |
|
---|
126 | if (writeDependentFields) {
|
---|
127 | const vector< RCP<FieldTag> >& dep_fields =
|
---|
128 | (evaluators[*vi])->dependentFields();
|
---|
129 |
|
---|
130 | label += "\\n Dependencies:";
|
---|
131 | if (dep_fields.size() > 0) {
|
---|
132 | for (vector< RCP<FieldTag> >::const_iterator field =
|
---|
133 | dep_fields.begin(); field != dep_fields.end(); ++field) {
|
---|
134 |
|
---|
135 | // Mark any broken evaluators in red
|
---|
136 | bool found = true;
|
---|
137 | if (debugRegisteredEvaluators) {
|
---|
138 |
|
---|
139 | map<string,vertex_t>::const_iterator testing =
|
---|
140 | field_to_evaluator_index.find((*field)->identifier());
|
---|
141 | if (testing == field_to_evaluator_index.end()) {
|
---|
142 | found = false;
|
---|
143 | vertex_attr_map[*vi]["fontcolor"] = "red";
|
---|
144 | }
|
---|
145 |
|
---|
146 | }
|
---|
147 |
|
---|
148 | if (found)
|
---|
149 | label += "\\n ";
|
---|
150 | else
|
---|
151 | label += "\\n *****MISSING**** ";
|
---|
152 |
|
---|
153 | label += (*field)->name()
|
---|
154 | + " : " + (*field)->dataLayout().identifier()
|
---|
155 | + " : " + Teuchos::demangleName((*field)->dataTypeInfo().name());
|
---|
156 | }
|
---|
157 | }
|
---|
158 | else
|
---|
159 | label += " None!";
|
---|
160 |
|
---|
161 | }
|
---|
162 |
|
---|
163 | vertex_attr_map[*vi]["label"] = label;
|
---|
164 | }
|
---|
165 |
|
---|
166 | std::ofstream outfile;
|
---|
167 | outfile.open (filename.c_str());
|
---|
168 | boost::write_graphviz(outfile, g_dot);
|
---|
169 | outfile.close();
|
---|
170 |
|
---|
171 | #else
|
---|
172 |
|
---|
173 | std::cout << "WARNING: writeGraphvizFile() was called, but this requires a boost library version 1.42 or higher. \nPlease rebuild Trilinos with a more recent version of boost." << std::endl;
|
---|
174 |
|
---|
175 | #endif // defined(BOOST_VERSION)&&(BOOST_VERSION>=104200)
|
---|
176 | }
|
---|