1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "JsonPrinter.hpp"
7
8 #include <iomanip>
9 #include <iostream>
10 #include <sstream>
11
12 namespace armnn
13 {
14
PrintJsonChildObject(const JsonChildObject & object,size_t & id)15 void JsonPrinter::PrintJsonChildObject(const JsonChildObject& object, size_t& id)
16 {
17 if (object.GetType() == JsonObjectType::Event)
18 {
19 // Increase the Id for new events. This ensures a new event has a unique ID and any measurements belonging
20 // to the event have the same id. This id is appended to the name during the call to PrintLabel() below.
21 id++;
22 }
23
24 if (object.GetType() != JsonObjectType::ExecObjectDesc)
25 {
26 PrintLabel(object.m_Label, id);
27 if (object.m_Guid.has_value())
28 {
29 PrintGuid(object.m_Guid.value());
30 }
31 PrintType(object.m_Type);
32 }
33
34 if (!object.m_Measurements.empty() || !object.m_Children.empty())
35 {
36 PrintSeparator();
37 PrintNewLine();
38 }
39 if (object.GetType() == JsonObjectType::Measurement)
40 {
41 PrintMeasurementsList(object.m_Measurements);
42 PrintSeparator();
43 PrintNewLine();
44 PrintUnit(object.m_Unit);
45 }
46 else if (object.GetType() == JsonObjectType::ExecObjectDesc)
47 {
48 // Add details opening
49 DecrementNumberOfTabs();
50 PrintTabs();
51 m_OutputStream << std::quoted("Graph") << ":[";
52 PrintNewLine();
53
54 // Fill details body
55 for (std::string stringLine : object.m_LayerDetailsList)
56 {
57 PrintTabs();
58 m_OutputStream << stringLine;
59 PrintNewLine();
60 }
61
62 // Close out details
63 PrintTabs();
64 object.IsDetailsOnlyEnabled() ? m_OutputStream << "]" : m_OutputStream << "],";
65
66 PrintNewLine();
67 IncrementNumberOfTabs();
68 }
69 if (!object.m_Children.empty())
70 {
71 for (unsigned int childIndex = 0; childIndex < object.m_Children.size(); ++childIndex)
72 {
73 PrintJsonChildObject(object.m_Children[childIndex], id);
74 // Only print separator and new line if current child is not the last element.
75 if (&object.m_Children[childIndex] != &object.m_Children.back())
76 {
77 PrintSeparator();
78 PrintNewLine();
79 }
80 }
81 }
82 if (object.GetType() != JsonObjectType::ExecObjectDesc)
83 {
84 PrintNewLine();
85 PrintFooter();
86 }
87 }
88
MakeKey(const std::string & label,size_t id)89 std::string JsonPrinter::MakeKey(const std::string& label, size_t id)
90 {
91 std::stringstream ss;
92 ss << label << std::string("_#") << id;
93 return ss.str();
94 }
95
PrintLabel(const std::string & label,size_t id)96 void JsonPrinter::PrintLabel(const std::string& label, size_t id)
97 {
98 PrintTabs();
99 m_OutputStream << R"(")" << MakeKey(label, id) << R"(": {)" << std::endl;
100 IncrementNumberOfTabs();
101 }
102
PrintUnit(armnn::Measurement::Unit unit)103 void JsonPrinter::PrintUnit(armnn::Measurement::Unit unit)
104 {
105 PrintTabs();
106 m_OutputStream << R"("unit": ")";
107 m_OutputStream << armnn::Measurement::ToString(unit);
108 m_OutputStream << R"(")";
109 }
110
PrintType(armnn::JsonObjectType type)111 void JsonPrinter::PrintType(armnn::JsonObjectType type)
112 {
113 auto ToString = [](armnn::JsonObjectType type)
114 {
115 switch (type)
116 {
117 case JsonObjectType::Measurement:
118 {
119 return "Measurement";
120 }
121 case JsonObjectType::Event:
122 {
123 return "Event";
124 }
125 case JsonObjectType::ExecObjectDesc:
126 {
127 return "Operator Description";
128 }
129 default:
130 {
131 return "Unknown";
132 }
133 }
134 };
135 PrintTabs();
136 m_OutputStream << R"("type": ")";
137 m_OutputStream << ToString(type);
138 m_OutputStream << R"(")";
139 }
140
PrintGuid(arm::pipe::ProfilingGuid guid)141 void JsonPrinter::PrintGuid(arm::pipe::ProfilingGuid guid)
142 {
143 PrintTabs();
144 m_OutputStream << std::quoted("GUID") << ": " << std::quoted(std::to_string(guid)) << "," << std::endl;
145 }
146
PrintMeasurementsList(const std::vector<double> & measurementsVector)147 void JsonPrinter::PrintMeasurementsList(const std::vector<double>& measurementsVector)
148 {
149 if (measurementsVector.empty())
150 {
151 return;
152 }
153
154 PrintTabs();
155 m_OutputStream << R"("raw": [)" << std::endl;
156 IncrementNumberOfTabs();
157 PrintTabs();
158 auto iter = measurementsVector.begin();
159 m_OutputStream << *iter;
160 for (iter = std::next(iter); iter != measurementsVector.end(); ++iter)
161 {
162 m_OutputStream << "," << std::endl;
163 PrintTabs();
164 m_OutputStream << *iter;
165 }
166 m_OutputStream << std::endl;
167 DecrementNumberOfTabs();
168 PrintTabs();
169 m_OutputStream << "]";
170 }
171
172 } // namespace armnn