blob: 84472d8c990ea24092d004963ba051da104c3677 [file] [log] [blame]
Éanna Ó Catháin0de47122020-04-01 15:40:12 +01001//
2// Copyright © 2020 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "JSONTimelineDecoder.hpp"
7#include "../profiling/ProfilingUtils.hpp"
8
9#include <string>
10#include <fstream>
Éanna Ó Catháin49c52a12020-04-27 12:54:11 +010011#include <boost/filesystem/fstream.hpp>
Éanna Ó Catháin0de47122020-04-01 15:40:12 +010012
13namespace armnn
14{
15namespace timelinedecoder
16{
17
18static const char *const CONNECTION = "connection";
19static const char *const BACKEND_ID = "backendId";
20static const char *const NAME = "name";
21static const char *const TYPE = "type";
22static const char *const WORKLOAD = "workload";
23static const char *const WORKLOAD_EXECUTION = "workload_execution";
24static const char *const INFERENCE = "inference";
25static const char *const LAYER = "layer";
26static const char *const ENTITY = "Entity";
27static const char *const EVENTCLASS = "EventClass";
28static const char *const EVENT = "Event";
29
30JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEntity(const Entity& entity)
31{
32 JSONEntity jsonEntity(entity.m_Guid);
33 jsonEntity.SetType(ENTITY);
34 this->m_Model.jsonEntities.insert({entity.m_Guid, jsonEntity});
35 return TimelineStatus::TimelineStatus_Success;
36}
37
38JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEventClass(const EventClass& eventClass)
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});
44 return TimelineStatus::TimelineStatus_Success;
45}
46
47JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateEvent(const Event& event)
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});
53 return TimelineStatus::TimelineStatus_Success;
54}
55
56JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateLabel(const Label& label)
57{
58 this->m_Model.labels.insert({label.m_Guid, label});
59 return TimelineStatus::TimelineStatus_Success;
60}
61
62JSONTimelineDecoder::TimelineStatus JSONTimelineDecoder::CreateRelationship(const Relationship& relationship)
63{
64 if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::RetentionLink)
65 {
66 HandleRetentionLink(relationship);
67 }
68 else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::LabelLink)
69 {
70 HandleLabelLink(relationship);
71 }
72 else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::ExecutionLink)
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
84 return TimelineStatus::TimelineStatus_Success;
85}
86
87
88void 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
110void 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
146void 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
167void 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
185void 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
203void 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
221void 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
241void JSONTimelineDecoder::JSONEntity::SetParent(JSONEntity& parent)
242{
243 parent.childEntities.push_back(GetGuid());
244}
245
246void JSONTimelineDecoder::PrintJSON(JSONTimelineDecoder::JSONEntity& rootEntity)
247{
248 std::string jsonString = GetJSONString(rootEntity);
Éanna Ó Catháin49c52a12020-04-27 12:54:11 +0100249 boost::filesystem::ofstream ofs{this->outputJSONFile};
250 ofs << jsonString;
251 ofs.close();
Éanna Ó Catháin0de47122020-04-01 15:40:12 +0100252}
253
254std::string JSONTimelineDecoder::GetJSONString(JSONTimelineDecoder::JSONEntity& rootEntity)
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
274std::string JSONTimelineDecoder::GetJSONEntityString(JSONTimelineDecoder::JSONEntity& entity, int& counter)
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
304std::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
330std::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
345std::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
363void JSONTimelineDecoder::JSONEntity::AddConnection(JSONEntity& headEntity, JSONEntity& connectedEntity)
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
371uint64_t JSONTimelineDecoder::JSONEntity::GetGuid()
372{
373 return m_Guid;
374}
375
376const JSONTimelineDecoder::Model &JSONTimelineDecoder::GetModel()
377{
378 return m_Model;
379}
380
381void JSONTimelineDecoder::SetOutgoingCaptureFile(const std::string& outgoingCaptureFile)
382{
383 this->outputJSONFile = outgoingCaptureFile;
384}
385
386void JSONTimelineDecoder::JSONEntity::SetName(std::string entityName)
387{
388 this->name = entityName;
389}
390
391std::string JSONTimelineDecoder::JSONEntity::GetName()
392{
393 return this->name;
394}
395
396void JSONTimelineDecoder::JSONEntity::SetType(std::string entityType)
397{
398 this->type = entityType;
399}
400
401std::string JSONTimelineDecoder::JSONEntity::GetType()
402{
403 return this->type;
404}
405
406}
407}