• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "JSONTimelineDecoder.hpp"
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 
CreateEntity(const Entity & entity)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 
CreateEventClass(const EventClass & eventClass)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 
CreateEvent(const Event & event)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 
CreateLabel(const Label & label)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 
CreateRelationship(const Relationship & relationship)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 
HandleExecutionLink(const ITimelineDecoder::Relationship & relationship)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 
HandleLabelLink(const ITimelineDecoder::Relationship & relationship)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 
HandleTypeLabel(const ITimelineDecoder::Relationship & relationship)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 
HandleNameLabel(const ITimelineDecoder::Relationship & relationship)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 
HandleBackendIdLabel(const ITimelineDecoder::Relationship & relationship)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 
HandleConnectionLabel(const ITimelineDecoder::Relationship & relationship)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 
HandleRetentionLink(const ITimelineDecoder::Relationship & relationship)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 
SetParent(JSONEntity & parent)239 void JSONTimelineDecoder::JSONEntity::SetParent(JSONEntity& parent)
240 {
241     parent.childEntities.push_back(GetGuid());
242 }
243 
PrintJSON(JSONTimelineDecoder::JSONEntity & rootEntity,std::ostream & os)244 void JSONTimelineDecoder::PrintJSON(JSONTimelineDecoder::JSONEntity& rootEntity, std::ostream& os)
245 {
246     std::string jsonString = GetJSONString(rootEntity);
247     os << jsonString;
248 }
249 
GetJSONString(JSONTimelineDecoder::JSONEntity & rootEntity)250 std::string JSONTimelineDecoder::GetJSONString(JSONTimelineDecoder::JSONEntity& rootEntity)
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 
GetJSONEntityString(JSONTimelineDecoder::JSONEntity & entity,int & counter)270 std::string JSONTimelineDecoder::GetJSONEntityString(JSONTimelineDecoder::JSONEntity& entity, int& counter)
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 
GetWorkloadExecutionJSONString(const JSONTimelineDecoder::JSONEntity & entity,std::string & jsonEntityString) const300 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 
GetWorkloadJSONString(const JSONTimelineDecoder::JSONEntity & entity,int & counter,std::string & jsonEntityString)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 
GetLayerJSONString(JSONTimelineDecoder::JSONEntity & entity,int & counter,std::string & jsonEntityString)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 
AddConnection(JSONEntity & headEntity,JSONEntity & connectedEntity)359 void JSONTimelineDecoder::JSONEntity::AddConnection(JSONEntity& headEntity, JSONEntity& connectedEntity)
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 
GetGuid()367 uint64_t JSONTimelineDecoder::JSONEntity::GetGuid()
368 {
369     return m_Guid;
370 }
371 
GetModel()372 const JSONTimelineDecoder::Model &JSONTimelineDecoder::GetModel()
373 {
374     return m_Model;
375 }
376 
SetName(std::string entityName)377 void JSONTimelineDecoder::JSONEntity::SetName(std::string entityName)
378 {
379     this->name = entityName;
380 }
381 
GetName()382 std::string JSONTimelineDecoder::JSONEntity::GetName()
383 {
384     return this->name;
385 }
386 
SetType(std::string entityType)387 void JSONTimelineDecoder::JSONEntity::SetType(std::string entityType)
388 {
389     this->type = entityType;
390 }
391 
GetType()392 std::string JSONTimelineDecoder::JSONEntity::GetType()
393 {
394     return this->type;
395 }
396 
397 }
398 }