blob: 2f999791ada5f22306ebb3df99e56998d945803d [file] [log] [blame]
Éanna Ó Catháin0de47122020-04-01 15:40:12 +01001//
Jan Eilers1f249442020-07-01 15:37:50 +01002// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
Éanna Ó Catháin0de47122020-04-01 15:40:12 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "JSONTimelineDecoder.hpp"
Jim Flynn3e9bc192022-03-23 23:01:26 +00007
8#include <client/src/ProfilingUtils.hpp>
Éanna Ó Catháin0de47122020-04-01 15:40:12 +01009
10#include <string>
Éanna Ó Catháin0de47122020-04-01 15:40:12 +010011
12namespace armnn
13{
14namespace timelinedecoder
15{
16
17static const char *const CONNECTION = "connection";
18static const char *const BACKEND_ID = "backendId";
19static const char *const NAME = "name";
20static const char *const TYPE = "type";
21static const char *const WORKLOAD = "workload";
22static const char *const WORKLOAD_EXECUTION = "workload_execution";
23static const char *const INFERENCE = "inference";
24static const char *const LAYER = "layer";
25static const char *const ENTITY = "Entity";
26static const char *const EVENTCLASS = "EventClass";
27static const char *const EVENT = "Event";
28
29JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEntity(const Entity& entity)
30{
31 JSONEntity jsonEntity(entity.m_Guid);
32 jsonEntity.SetType(ENTITY);
33 this->m_Model.jsonEntities.insert({entity.m_Guid, jsonEntity});
34 return TimelineStatus::TimelineStatus_Success;
35}
36
37JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEventClass(const EventClass& eventClass)
38{
39 JSONEntity jsonEntity(eventClass.m_Guid);
40 jsonEntity.SetType(EVENTCLASS);
41 this->m_Model.eventClasses.insert({eventClass.m_Guid, eventClass});
42 this->m_Model.jsonEntities.insert({eventClass.m_Guid, jsonEntity});
43 return TimelineStatus::TimelineStatus_Success;
44}
45
46JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEvent(const Event& event)
47{
48 JSONEntity jsonEntity(event.m_Guid);
49 jsonEntity.SetType(EVENT);
50 this->m_Model.events.insert({event.m_Guid, event});
51 this->m_Model.jsonEntities.insert({jsonEntity.GetGuid(), jsonEntity});
52 return TimelineStatus::TimelineStatus_Success;
53}
54
55JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateLabel(const Label& label)
56{
57 this->m_Model.labels.insert({label.m_Guid, label});
58 return TimelineStatus::TimelineStatus_Success;
59}
60
61JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateRelationship(const Relationship& relationship)
62{
63 if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::RetentionLink)
64 {
65 HandleRetentionLink(relationship);
66 }
67 else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::LabelLink)
68 {
69 HandleLabelLink(relationship);
70 }
71 else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::ExecutionLink)
72 {
73 HandleExecutionLink(relationship);
74 }
75 else
76 {
77 /*
78 * TODO Handle DataLink
79 */
80 m_Model.relationships.insert({relationship.m_Guid, relationship});
81 }
82
83 return TimelineStatus::TimelineStatus_Success;
84}
85
86
87void JSONTimelineDecoder::HandleExecutionLink(const ITimelineDecoder::Relationship& relationship)
88{
89 uint64_t tailGuid = relationship.m_TailGuid;
90 uint64_t headGuid = relationship.m_HeadGuid;
91
92 if (m_Model.jsonEntities.count(relationship.m_HeadGuid) != 0)
93 {
94 JSONEntity& tailJSONEntity = m_Model.jsonEntities.at(tailGuid);
95 JSONEntity& headJSONEntity = m_Model.jsonEntities.at(headGuid);
96 tailJSONEntity.SetParent(headJSONEntity);
97 m_Model.jsonEntities.insert({headGuid, headJSONEntity});
98 m_Model.relationships.insert({relationship.m_Guid, relationship});
99 }
100 else
101 {
102 /*
103 * TODO Add some protection against packet ordering issues
104 */
105 m_Model.relationships.insert({relationship.m_Guid, relationship});
106 }
107}
108
109void JSONTimelineDecoder::HandleLabelLink(const ITimelineDecoder::Relationship& relationship)
110{
111 if (m_Model.labels.count(relationship.m_TailGuid) != 0)
112 {
113 if (m_Model.labels.at(relationship.m_TailGuid).m_Name == CONNECTION)
114 {
115 HandleConnectionLabel(relationship);
116 }
117 else if (m_Model.labels.at(relationship.m_TailGuid).m_Name == BACKEND_ID)
118 {
119 HandleBackendIdLabel(relationship);
120 }
121 else if (m_Model.labels.at(relationship.m_TailGuid).m_Name == NAME)
122 {
123 HandleNameLabel(relationship);
124 }
125 else if (m_Model.labels.at(relationship.m_TailGuid).m_Name == TYPE)
126 {
127 HandleTypeLabel(relationship);
128 }
129 else
130 {
131 /*
132 * TODO Add some protection against packet ordering issues
133 */
134 m_Model.relationships.insert({relationship.m_Guid, relationship});
135 }
136 } else
137 {
138 /*
139 * TODO Add some protection against packet ordering issues
140 */
141 m_Model.relationships.insert({relationship.m_Guid, relationship});
142 }
143}
144
145void JSONTimelineDecoder::HandleTypeLabel(const ITimelineDecoder::Relationship& relationship)
146{
147 if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
148 {
149 Relationship labelRelation = m_Model.relationships.at(relationship.m_HeadGuid);
150 if (m_Model.jsonEntities.count(labelRelation.m_HeadGuid) != 0)
151 {
152 JSONEntity& headEntity = m_Model.jsonEntities.at(labelRelation.m_HeadGuid);
153 std::string type = m_Model.labels.at(labelRelation.m_TailGuid).m_Name;
154 headEntity.SetType(type);
155 }
156 }
157 else
158 {
159 /*
160 * TODO Add some protection against packet ordering issues
161 */
162 m_Model.relationships.insert({relationship.m_Guid, relationship});
163 }
164}
165
166void JSONTimelineDecoder::HandleNameLabel(const ITimelineDecoder::Relationship& relationship)
167{
168 if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
169 {
170 Relationship labelRelation = m_Model.relationships.at(relationship.m_HeadGuid);
171 JSONEntity& headEntity = m_Model.jsonEntities.at(labelRelation.m_HeadGuid);
172 std::string name = m_Model.labels.at(labelRelation.m_TailGuid).m_Name;
173 headEntity.SetName(name);
174 }
175 else
176 {
177 /*
178 * TODO Add some protection against packet ordering issues
179 */
180 m_Model.relationships.insert({relationship.m_Guid, relationship});
181 }
182}
183
184void JSONTimelineDecoder::HandleBackendIdLabel(const ITimelineDecoder::Relationship& relationship)
185{
186 if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
187 {
188 Relationship labelRelation = m_Model.relationships.at(relationship.m_HeadGuid);
189 JSONEntity& headEntity = m_Model.jsonEntities.at(labelRelation.m_HeadGuid);
190 std::string backendName = m_Model.labels.at(labelRelation.m_TailGuid).m_Name;
191 headEntity.extendedData.insert({BACKEND_ID, backendName});
192 }
193 else
194 {
195 /*
196 * TODO Add some protection against packet ordering issues
197 */
198 m_Model.relationships.insert({relationship.m_Guid, relationship});
199 }
200}
201
202void JSONTimelineDecoder::HandleConnectionLabel(const ITimelineDecoder::Relationship& relationship)
203{
204 if (m_Model.relationships.count(relationship.m_HeadGuid) != 0)
205 {
206 Relationship retentionRelation = m_Model.relationships.at(relationship.m_HeadGuid);
207 JSONEntity& headEntity = m_Model.jsonEntities.at(retentionRelation.m_HeadGuid);
208 JSONEntity& tailEntity = m_Model.jsonEntities.at(retentionRelation.m_TailGuid);
209 headEntity.AddConnection(headEntity, tailEntity);
210 }
211 else
212 {
213 /*
214 * TODO Add some protection against packet ordering issues
215 */
216 m_Model.relationships.insert({relationship.m_Guid, relationship});
217 }
218}
219
220void JSONTimelineDecoder::HandleRetentionLink(const ITimelineDecoder::Relationship& relationship)
221{
222 if (m_Model.jsonEntities.count(relationship.m_TailGuid) != 0 && m_Model.jsonEntities
223 .count(relationship.m_HeadGuid) != 0)
224 {
225 JSONEntity& tailJSONEntity = m_Model.jsonEntities.at(relationship.m_TailGuid);
226 JSONEntity& headJSONEntity = m_Model.jsonEntities.at(relationship.m_HeadGuid);
227 tailJSONEntity.SetParent(headJSONEntity);
228 m_Model.jsonEntities.insert({relationship.m_HeadGuid, headJSONEntity});
229 m_Model.relationships.insert({relationship.m_Guid, relationship});
230 }
231 else
232 {
233 /*
234 * TODO Add some protection against packet ordering issues
235 */
236 m_Model.relationships.insert({relationship.m_Guid, relationship});
237 }
238}
239
240void JSONTimelineDecoder::JSONEntity::SetParent(JSONEntity& parent)
241{
242 parent.childEntities.push_back(GetGuid());
243}
244
Jan Eilers1f249442020-07-01 15:37:50 +0100245void JSONTimelineDecoder::PrintJSON(JSONTimelineDecoder::JSONEntity& rootEntity, std::ostream& os)
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100246{
247 std::string jsonString = GetJSONString(rootEntity);
Jan Eilers1f249442020-07-01 15:37:50 +0100248 os << jsonString;
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100249}
250
251std::string JSONTimelineDecoder::GetJSONString(JSONTimelineDecoder::JSONEntity& rootEntity)
252{
253 int counter = 0;
254 std::string json;
255 json.append("{\n");
256 if(rootEntity.GetType() != "")
257 {
258 json.append("\tArmNN");
259 json.append(": {\n");
260
261 for (uint64_t childEntityId : rootEntity.childEntities)
262 {
263 JSONEntity& childEntity = this->m_Model.jsonEntities.at(childEntityId);
264 json.append(GetJSONEntityString(childEntity, counter));
265 }
266 }
267 json.append("}\n");
268 return json;
269}
270
271std::string JSONTimelineDecoder::GetJSONEntityString(JSONTimelineDecoder::JSONEntity& entity, int& counter)
272{
273 std::string jsonEntityString;
274 if(entity.GetType() == LAYER)
275 {
276 return GetLayerJSONString(entity, counter, jsonEntityString);
277 }
278 else if (entity.GetType() == WORKLOAD)
279 {
280 return GetWorkloadJSONString(entity, counter, jsonEntityString);
281 }
282 else if (entity.GetType() == WORKLOAD_EXECUTION)
283 {
284 return GetWorkloadExecutionJSONString(entity, jsonEntityString);
285 }
286 else if (entity.GetType() == INFERENCE)
287 {
288 return jsonEntityString;
289 }
290 else
291 {
292 for (uint64_t child_entity_id : entity.childEntities)
293 {
294 JSONEntity& childEntity = this->m_Model.jsonEntities.at(child_entity_id);
295 jsonEntityString.append(GetJSONEntityString(childEntity, ++counter));
296 }
297 return jsonEntityString;
298 }
299}
300
301std::string JSONTimelineDecoder::GetWorkloadExecutionJSONString(const JSONTimelineDecoder::JSONEntity& entity,
302 std::string& jsonEntityString) const
303{
304 if(entity.childEntities.size() < 2)
305 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000306 throw arm::pipe::ProfilingException(
307 "Workload Execution Entity Packet does not have the expected Event packets attached");
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100308 }
309 JSONEntity jsonEventOne = entity.childEntities[0];
310 JSONEntity jsonEventTwo = entity.childEntities[1];
311
312 Event event1 = m_Model.events.at(jsonEventOne.GetGuid());
313 Event event2 = m_Model.events.at(jsonEventTwo.GetGuid());
314
315 uint64_t wall_clock_time = event2.m_TimeStamp - event1.m_TimeStamp;
316 jsonEntityString.append("\t\t\t");
317 jsonEntityString.append("raw : [");
318 jsonEntityString.append(std::to_string(wall_clock_time));
319 jsonEntityString.append("], \n");
320 jsonEntityString.append("\t\t\t");
321 jsonEntityString.append("unit : us,\n");
322 jsonEntityString.append("\t\t\t");
323 jsonEntityString.append("}\n");
324
325 return jsonEntityString;
326}
327
328std::string JSONTimelineDecoder::GetWorkloadJSONString(const JSONTimelineDecoder::JSONEntity& entity, int& counter,
329 std::string& jsonEntityString)
330{
331 jsonEntityString.append("\t\t\t");
332 jsonEntityString.append("backendId :");
333 jsonEntityString.append(entity.extendedData.at(BACKEND_ID));
334 jsonEntityString.append(",\n");
335 for (uint64_t child_entity_id : entity.childEntities)
336 {
337 JSONEntity &childEntity = m_Model.jsonEntities.at(child_entity_id);
338 jsonEntityString.append(GetJSONEntityString(childEntity, ++counter));
339 }
340 return jsonEntityString;
341}
342
343std::string JSONTimelineDecoder::GetLayerJSONString(JSONTimelineDecoder::JSONEntity& entity, int& counter,
344 std::string& jsonEntityString)
345{
346 jsonEntityString.append("\t\t");
347 jsonEntityString.append(entity.GetName());
348 jsonEntityString.append("_");
349 jsonEntityString.append(std::to_string(counter));
350 jsonEntityString.append(": {\n");
351 jsonEntityString.append("\t\t\t");
352 jsonEntityString.append("type: Measurement,\n");
353 for (uint64_t child_entity_id : entity.childEntities)
354 {
355 JSONEntity& childEntity = m_Model.jsonEntities.at(child_entity_id);
356 jsonEntityString.append(GetJSONEntityString(childEntity, ++counter));
357 }
358 return jsonEntityString;
359}
360
361void JSONTimelineDecoder::JSONEntity::AddConnection(JSONEntity& headEntity, JSONEntity& connectedEntity)
362{
363 std::vector<uint64_t>::iterator it = std::find(headEntity.childEntities.begin(),
364 headEntity.childEntities.end(), connectedEntity.GetGuid());
365 headEntity.childEntities.erase(it);
366 headEntity.connected_entities.push_back(connectedEntity.m_Guid);
367}
368
369uint64_t JSONTimelineDecoder::JSONEntity::GetGuid()
370{
371 return m_Guid;
372}
373
374const JSONTimelineDecoder::Model &JSONTimelineDecoder::GetModel()
375{
376 return m_Model;
377}
378
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100379void JSONTimelineDecoder::JSONEntity::SetName(std::string entityName)
380{
381 this->name = entityName;
382}
383
384std::string JSONTimelineDecoder::JSONEntity::GetName()
385{
386 return this->name;
387}
388
389void JSONTimelineDecoder::JSONEntity::SetType(std::string entityType)
390{
391 this->type = entityType;
392}
393
394std::string JSONTimelineDecoder::JSONEntity::GetType()
395{
396 return this->type;
397}
398
399}
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000400}