| 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 | }
|
|---|