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