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