xref: /aosp_15_r20/external/armnn/src/armnnUtils/DotSerializer.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "DotSerializer.hpp"
7 #include "armnn/utility/StringUtils.hpp"
8 #include <common/include/ProfilingGuid.hpp>
9 
10 #include <sstream>
11 #include <cstring>
12 
13 namespace armnn
14 {
15 
16 namespace
17 {
Indent(int numSpaces)18 std::string Indent(int numSpaces)
19 {
20     std::stringstream ss;
21     for (int i = 0; i < numSpaces; i++)
22     {
23         ss << " ";
24     }
25     return ss.str();
26 }
27 
Escape(std::string s)28 std::string Escape(std::string s)
29 {
30     armnn::stringUtils::StringReplaceAll(s, "<", "\\<");
31     armnn::stringUtils::StringReplaceAll(s, ">", "\\>");
32     return s;
33 }
34 
35 } //namespace
36 
37 
HtmlFont(std::ostream & stream,int fontSize,const char * color,const char * face)38 HtmlFont::HtmlFont(std::ostream& stream, int fontSize, const char *color, const char *face)
39     : DotBase(stream)
40 {
41     GetStream() << "<FONT";
42 
43     if (fontSize > -1)
44     {
45         GetStream() << " POINT-SIZE=" << "\"" << fontSize << "\"";
46     }
47 
48     if (color && std::strlen(color) != 0)
49     {
50         GetStream() << " COLOR=\"" << color << "\" ";
51     }
52 
53     if (face && std::strlen(face) != 0)
54     {
55         GetStream() << " FACE=\"" << face << "\" ";
56     }
57 
58     GetStream() << ">";
59 }
60 
61 
HtmlFont(std::ostream & stream)62 HtmlFont::HtmlFont(std::ostream& stream)
63     : HtmlFont(stream, -1, nullptr, nullptr)
64 {}
65 
~HtmlFont()66 HtmlFont::~HtmlFont()
67 {
68     GetStream() << "</FONT>";
69 }
70 
71 
DotAttributeSet(std::ostream & stream)72 DotAttributeSet::DotAttributeSet(std::ostream& stream)
73     : DotBase(stream)
74 {
75     GetStream() << "[";
76 }
77 
~DotAttributeSet()78 DotAttributeSet::~DotAttributeSet()
79 {
80     bool doSpace=false;
81     for (auto&& attrib : m_Attributes)
82     {
83         if (doSpace)
84         {
85             GetStream() << " ";
86         }
87 
88         GetStream() << attrib;
89         doSpace=true;
90     }
91 
92     GetStream() << "]";
93 }
94 
AddAttribute(const std::string & name,const std::stringstream & value)95 DotAttributeSet & DotAttributeSet::AddAttribute(const std::string& name, const std::stringstream& value)
96 {
97     std::stringstream ss;
98     ss << name <<"=" << value.str();
99     m_Attributes.push_back(ss.str());
100     return *this;
101 }
102 
AddAttribute(const std::string & name,int value)103 DotAttributeSet & DotAttributeSet::AddAttribute(const std::string& name, int value)
104 {
105     std::stringstream ss;
106     ss << name <<"=" << value;
107     m_Attributes.push_back(ss.str());
108     return *this;
109 }
110 
AddAttribute(const std::string & name,const std::string & value)111 DotAttributeSet & DotAttributeSet::AddAttribute(const std::string& name, const std::string& value)
112 {
113     std::stringstream ss;
114     ss << name <<"=\"" << value << "\"";
115     m_Attributes.push_back(ss.str());
116     return *this;
117 }
118 
DotEdge(std::ostream & stream,LayerGuid fromNodeId,LayerGuid toNodeId)119 DotEdge::DotEdge(std::ostream& stream, LayerGuid fromNodeId, LayerGuid toNodeId)
120     : DotBase(stream)
121 {
122     std::stringstream ss;
123     ss << Indent(4) << fromNodeId << " -> " << toNodeId << " ";
124     GetStream() << ss.str();
125 
126     m_Attributes = std::make_unique<DotAttributeSet>(stream);
127 }
128 
~DotEdge()129 DotEdge::~DotEdge()
130 {
131     m_Attributes.reset(nullptr);
132     GetStream() << ";" << std::endl;
133 }
134 
135 
NodeContent(std::ostream & stream)136 NodeContent::NodeContent(std::ostream& stream)
137     : DotBase(stream)
138 {
139 }
140 
SetName(const std::string & name)141 NodeContent & NodeContent::SetName(const std::string & name)
142 {
143     m_Name = name;
144     return *this;
145 }
146 
AddContent(const std::string & content)147 NodeContent & NodeContent::AddContent(const std::string & content)
148 {
149     m_Contents.push_back(content);
150     return *this;
151 }
152 
~NodeContent()153 NodeContent::~NodeContent()
154 {
155     std::stringstream ss;
156     ss << "label=\"{" << m_Name;
157     if (!m_Contents.empty())
158     {
159         ss << "|";
160     }
161     for (auto & content : m_Contents)
162     {
163         ss << Escape(content);
164         ss << "\\l";
165     }
166     ss << "}\"";
167 
168     std::string s;
169     try
170     {
171         // Coverity fix: std::stringstream::str() may throw an exception of type std::length_error.
172         s = ss.str();
173     }
174     catch (const std::exception&) { } // Swallow any exception.
175 
176     GetStream() << s;
177 }
178 
DotNode(std::ostream & stream,LayerGuid nodeId,const char * label)179 DotNode::DotNode(std::ostream& stream, LayerGuid nodeId, const char* label)
180     : DotBase(stream)
181 {
182     std::stringstream ss;
183     ss << Indent(4) << nodeId;
184 
185     GetStream() << ss.str() << " ";
186 
187     m_Contents = std::make_unique<NodeContent>(stream);
188     m_Attributes = std::make_unique<DotAttributeSet>(stream);
189 
190     if (std::strlen(label) != 0)
191     {
192         m_Contents->SetName(label);
193     }
194     else
195     {
196         m_Contents->SetName("<noname>");
197     }
198 }
199 
~DotNode()200 DotNode::~DotNode()
201 {
202     m_Contents.reset(nullptr);
203     m_Attributes.reset(nullptr);
204     GetStream() << ";" << std::endl;
205 }
206 
207 
DotDefaults(std::ostream & stream,const char * type)208 DotDefaults::DotDefaults(std::ostream& stream, const char* type)
209     : DotBase(stream)
210 {
211     std::stringstream ss;
212     ss << Indent(4) << type;
213 
214     GetStream() << ss.str() << " ";
215     m_Attributes = std::make_unique<DotAttributeSet>(stream);
216 }
217 
~DotDefaults()218 DotDefaults::~DotDefaults()
219 {
220     m_Attributes.reset(nullptr);
221     GetStream() << ";" << std::endl;
222 }
223 
DotGraph(std::ostream & stream,const char * name)224 DotGraph::DotGraph(std::ostream& stream, const char* name)
225     : DotBase(stream)
226 {
227     GetStream() << "digraph " << name << " {" << std::endl;
228 }
229 
~DotGraph()230 DotGraph::~DotGraph()
231 {
232     GetStream() << "}" << std::endl;
233 }
234 
235 } //namespace armnn
236 
237 
238