1 /*
2 * Copyright (c) Glow Contributors. See CONTRIBUTORS file.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "NNPIUtils.h"
16 #include "DebugMacros.h"
17 #include <fstream>
18 #include <sstream>
19
20 unsigned DotWriter::graphId_(0);
21 std::map<std::string, std::set<std::string>> DotWriter::subGraphNodes_;
22 std::map<std::string, std::string> DotWriter::subGraphLabels_;
23 std::set<std::string> DotWriter::edges_;
24
getColorString(unsigned i)25 static const std::string &getColorString(unsigned i) {
26 // Taking colors from the SVG scheme
27 static const std::vector<std::string> nodeColors = {
28 "mistyrose", // function
29 "lightgreen", // host resource
30 "lightblue", // normal device resource
31 "plum", // static device resource
32 "lightcoral", // p2p device resource
33 "wheat", // drt device resource
34 "lightgray", // reserved
35 "sandybrown", // reserved
36 "turquoise", // reserved
37 "seagreen", // reserved
38 };
39 return nodeColors.at(i % nodeColors.size());
40 }
41
clear()42 void DotWriter::clear() {
43 DotWriter::subGraphNodes_.clear();
44 DotWriter::subGraphLabels_.clear();
45 DotWriter::edges_.clear();
46 }
47
addNode(std::string name,std::string label,unsigned color,std::string subGraph)48 void DotWriter::addNode(std::string name, std::string label, unsigned color,
49 std::string subGraph) {
50 ostringstream os;
51 os << name << " [\n";
52 os << "\tlabel = \"" << label << "\"\n";
53 os << "\tstyle=\"filled,rounded\"\n";
54 os << "\tfillcolor=" << getColorString(color) << "\n";
55 os << "];\n";
56 if (!subGraph.empty()) {
57 subGraphNodes_[subGraph].insert(os.str() /*name*/);
58 }
59 }
60
addEdge(std::string src,std::string dst)61 void DotWriter::addEdge(std::string src, std::string dst) {
62 edges_.insert(src + " -> " + dst + ";\n");
63 }
64
writeToFile(std::string filename)65 void DotWriter::writeToFile(std::string filename) {
66 if (filename.empty()) {
67 filename = "dot_graph";
68 }
69 filename = filename + std::to_string(graphId_++) + ".dot";
70 std::ofstream outFile(filename);
71 if (!outFile.is_open()) {
72 LOG(INFO) << "Failed to write dor file: " << filename;
73 return;
74 }
75 outFile << "digraph {\n";
76 outFile << "\tedge[color = black];\n";
77 outFile << "\trank = TB;\n";
78 outFile << "\tnode[shape = Mrecord, penwidth=2];\n";
79 outFile << "\n";
80
81 for (const auto &sg : subGraphNodes_) {
82 outFile << "subgraph "
83 << "cluster_" << sg.first << " {\n";
84 outFile << "\tlabel = \"" << subGraphLabels_.at(sg.first) << "\";\n";
85 for (const auto &n : sg.second) {
86 outFile << n; //<< ";\n";
87 }
88 outFile << "}\n";
89 }
90 for (const auto &e : edges_) {
91 outFile << e;
92 }
93
94 outFile << "\n";
95 outFile << "\t}\n";
96 }
97
addSubGraph(std::string name,std::string label)98 void DotWriter::addSubGraph(std::string name, std::string label) {
99 subGraphLabels_[name] = label;
100 }
101
getHexStr(uint64_t h)102 std::string DotWriter::getHexStr(uint64_t h) {
103 std::ostringstream os;
104 os << std::hex << h;
105 return os.str();
106 }