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 }