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