blob: 0eafe493aa882b8ee5c7364eece429c40860cb4b [file] [log] [blame]
Éanna Ó Catháin0de47122020-04-01 15:40:12 +01001//
Jan Eilers1f249442020-07-01 15:37:50 +01002// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
Éanna Ó Catháin0de47122020-04-01 15:40:12 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "JSONTimelineDecoder.hpp"
7#include "../profiling/ProfilingUtils.hpp"
8
9#include <string>
Éanna Ó Catháin0de47122020-04-01 15:40:12 +010010
11namespace armnn
12{
13namespace timelinedecoder
14{
15
16static const char *const CONNECTION = "connection";
17static const char *const BACKEND_ID = "backendId";
18static const char *const NAME = "name";
19static const char *const TYPE = "type";
20static const char *const WORKLOAD = "workload";
21static const char *const WORKLOAD_EXECUTION = "workload_execution";
22static const char *const INFERENCE = "inference";
23static const char *const LAYER = "layer";
24static const char *const ENTITY = "Entity";
25static const char *const EVENTCLASS = "EventClass";
26static const char *const EVENT = "Event";
27
28JSONTimelineDecoder::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
36JSONTimelineDecoder::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
45JSONTimelineDecoder::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
54JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateLabel(const Label& label)
55{
56 this->m_Model.labels.insert({label.m_Guid, label});
57 return TimelineStatus::TimelineStatus_Success;
58}
59
60JSONTimelineDecoder::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
86void 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
108void 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
144void 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
165void 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
183void 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
201void 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
219void 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
239void JSONTimelineDecoder::JSONEntity::SetParent(JSONEntity& parent)
240{
241 parent.childEntities.push_back(GetGuid());
242}
243
Jan Eilers1f249442020-07-01 15:37:50 +0100244void JSONTimelineDecoder::PrintJSON(JSONTimelineDecoder::JSONEntity& rootEntity, std::ostream& os)
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100245{
246 std::string jsonString = GetJSONString(rootEntity);
Jan Eilers1f249442020-07-01 15:37:50 +0100247 os << jsonString;
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100248}
249
250std::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
270std::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
300std::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
326std::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
341std::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
359void 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
367uint64_t JSONTimelineDecoder::JSONEntity::GetGuid()
368{
369 return m_Guid;
370}
371
372const JSONTimelineDecoder::Model &JSONTimelineDecoder::GetModel()
373{
374 return m_Model;
375}
376
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100377void JSONTimelineDecoder::JSONEntity::SetName(std::string entityName)
378{
379 this->name = entityName;
380}
381
382std::string JSONTimelineDecoder::JSONEntity::GetName()
383{
384 return this->name;
385}
386
387void JSONTimelineDecoder::JSONEntity::SetType(std::string entityType)
388{
389 this->type = entityType;
390}
391
392std::string JSONTimelineDecoder::JSONEntity::GetType()
393{
394 return this->type;
395}
396
397}
398}