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