ArmNN
 22.05
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 
8 #include <client/src/ProfilingUtils.hpp>
9 
10 #include <string>
11 
12 namespace armnn
13 {
14 namespace timelinedecoder
15 {
16 
17 static const char *const CONNECTION = "connection";
18 static const char *const BACKEND_ID = "backendId";
19 static const char *const NAME = "name";
20 static const char *const TYPE = "type";
21 static const char *const WORKLOAD = "workload";
22 static const char *const WORKLOAD_EXECUTION = "workload_execution";
23 static const char *const INFERENCE = "inference";
24 static const char *const LAYER = "layer";
25 static const char *const ENTITY = "Entity";
26 static const char *const EVENTCLASS = "EventClass";
27 static const char *const EVENT = "Event";
28 
29 JSONTimelineDecoder::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 
37 JSONTimelineDecoder::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 
46 JSONTimelineDecoder::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 
55 JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateLabel(const Label& label)
56 {
57  this->m_Model.labels.insert({label.m_Guid, label});
58  return TimelineStatus::TimelineStatus_Success;
59 }
60 
61 JSONTimelineDecoder::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 
87 void 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 
109 void 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 
145 void 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 
166 void 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 
184 void 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 
202 void 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 
220 void 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 
241 {
242  parent.childEntities.push_back(GetGuid());
243 }
244 
246 {
247  std::string jsonString = GetJSONString(rootEntity);
248  os << jsonString;
249 }
250 
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 
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 
301 std::string JSONTimelineDecoder::GetWorkloadExecutionJSONString(const JSONTimelineDecoder::JSONEntity& entity,
302  std::string& jsonEntityString) const
303 {
304  if(entity.childEntities.size() < 2)
305  {
306  throw arm::pipe::ProfilingException(
307  "Workload Execution Entity Packet does not have the expected Event packets attached");
308  }
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 
328 std::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 
343 std::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 
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 
370 {
371  return m_Guid;
372 }
373 
375 {
376  return m_Model;
377 }
378 
379 void JSONTimelineDecoder::JSONEntity::SetName(std::string entityName)
380 {
381  this->name = entityName;
382 }
383 
385 {
386  return this->name;
387 }
388 
389 void JSONTimelineDecoder::JSONEntity::SetType(std::string entityType)
390 {
391  this->type = entityType;
392 }
393 
395 {
396  return this->type;
397 }
398 
399 }
400 }
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)
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