blob: 1f02addcf90a72037cbe095157f1915337c4e4aa [file] [log] [blame]
Jim Flynn4e755a52020-03-29 17:48:26 +01001//
Jim Flynn6398a982020-05-27 17:05:21 +01002// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
Jim Flynn4e755a52020-03-29 17:48:26 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "TimelineModel.hpp"
Jim Flynn6398a982020-05-27 17:05:21 +01007#include <LabelsAndEventClasses.hpp>
8
9#include <algorithm>
Jim Flynn4e755a52020-03-29 17:48:26 +010010
11namespace armnn
12{
13
14namespace profiling
15{
16
Jim Flynnbbfe6032020-07-20 16:57:44 +010017void TimelineModel::AddLabel(const arm::pipe::ITimelineDecoder::Label& label)
Jim Flynn4e755a52020-03-29 17:48:26 +010018{
19 m_LabelMap.emplace(label.m_Guid, label);
20}
21
Jim Flynn6398a982020-05-27 17:05:21 +010022std::string* TimelineModel::FindLabel(uint64_t guid)
23{
24 auto iter = m_LabelMap.find(guid);
25 if (iter != m_LabelMap.end())
26 {
27 return &iter->second.m_Name;
28 }
29 else
30 {
31 return nullptr;
32 }
33}
34
Jim Flynn4e755a52020-03-29 17:48:26 +010035void TimelineModel::AddEntity(uint64_t guid)
36{
37 m_Entities.emplace(guid, guid);
38}
39
Jim Flynn6398a982020-05-27 17:05:21 +010040Entity* TimelineModel::FindEntity(uint64_t id)
Jim Flynn4e755a52020-03-29 17:48:26 +010041{
42 auto iter = m_Entities.find(id);
43 if (iter != m_Entities.end())
44 {
45 return &(iter->second);
46 }
47 else
48 {
49 return nullptr;
50 }
51}
52
Jim Flynnbbfe6032020-07-20 16:57:44 +010053void TimelineModel::AddRelationship(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn4e755a52020-03-29 17:48:26 +010054{
55 m_Relationships.emplace(relationship.m_Guid, relationship);
Jim Flynnbbfe6032020-07-20 16:57:44 +010056 if (relationship.m_RelationshipType == arm::pipe::ITimelineDecoder::RelationshipType::LabelLink)
Jim Flynn6398a982020-05-27 17:05:21 +010057 {
58 HandleLabelLink(relationship);
59 }
Jim Flynnbbfe6032020-07-20 16:57:44 +010060 else if (relationship.m_RelationshipType == arm::pipe::ITimelineDecoder::RelationshipType::RetentionLink)
Jim Flynn6398a982020-05-27 17:05:21 +010061 {
62 // Take care of the special case of a connection between layers in ArmNN
63 // modelled by a retention link between two layer entities with an attribute GUID
64 // of connection
65 if (relationship.m_AttributeGuid == armnn::profiling::LabelsAndEventClasses::CONNECTION_GUID)
66 {
67 HandleConnection(relationship);
68 }
69 else if (relationship.m_AttributeGuid == armnn::profiling::LabelsAndEventClasses::CHILD_GUID)
70 {
71 HandleChild(relationship);
72 }
73 else if (relationship.m_AttributeGuid == armnn::profiling::LabelsAndEventClasses::EXECUTION_OF_GUID)
74 {
75 HandleExecutionOf(relationship);
76 }
77 else
78 {
79 // report unknown relationship type
80 std::stringstream ss;
81 ss << "Encountered a RetentionLink of unknown type [" << relationship.m_AttributeGuid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +010082 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +010083 }
84 }
Jim Flynnbbfe6032020-07-20 16:57:44 +010085 else if (relationship.m_RelationshipType == arm::pipe::ITimelineDecoder::RelationshipType::ExecutionLink)
Jim Flynn6398a982020-05-27 17:05:21 +010086 {
87 HandleExecutionLink(relationship);
88 }
Jim Flynn4e755a52020-03-29 17:48:26 +010089}
90
Jim Flynnbbfe6032020-07-20 16:57:44 +010091void TimelineModel::HandleLabelLink(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +010092{
93 Entity* entity = FindEntity(relationship.m_HeadGuid);
94 // we have a label attribute of an entity
95 std::string* value = nullptr;
96 std::string* attribute = nullptr;
97 value = FindLabel(relationship.m_TailGuid);
98 if (value == nullptr)
99 {
100 //report an error
101 std::stringstream ss;
102 ss << "could not find label link [" << relationship.m_Guid <<
103 "] value [" << relationship.m_TailGuid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100104 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100105 }
106 if (relationship.m_AttributeGuid != 0)
107 {
108 attribute = FindLabel(relationship.m_AttributeGuid);
109 if (attribute == nullptr)
110 {
111 //report an error
112 std::stringstream ss;
113 ss << "could not find label link [" << relationship.m_Guid <<
114 "] attribute [" << relationship.m_AttributeGuid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100115 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100116 }
117 }
118 else
119 {
120 //report an error
121 std::stringstream ss;
122 ss << "label link [" << relationship.m_Guid << "] has a zero attribute guid";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100123 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100124 }
125 if (entity != nullptr && attribute != nullptr && value != nullptr)
126 {
127 entity->AddAttribute(*attribute, *value);
128 // if the attribute is 'type' and the value is 'inference'
129 // we need to cache the entity guid as an inference
130 if (armnn::profiling::LabelsAndEventClasses::TYPE_LABEL.compare(*attribute) == 0 &&
131 armnn::profiling::LabelsAndEventClasses::INFERENCE.compare(*value) == 0)
132 {
133 m_InferenceGuids.push_back(relationship.m_HeadGuid);
134 }
135 }
136
137 if (entity == nullptr)
138 {
139 //report an error
140 std::stringstream ss;
141 ss << "could not find label link [" << relationship.m_Guid <<
142 "] entity [" << relationship.m_HeadGuid << "] ";
143 if (value != nullptr)
144 {
145 ss << "value [" << *value << "] ";
146 }
147 if (attribute != nullptr)
148 {
149 ss << "attribute [" << *attribute << "] ";
150 }
Jim Flynnbbfe6032020-07-20 16:57:44 +0100151 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100152 }
153}
154
Jim Flynnbbfe6032020-07-20 16:57:44 +0100155void TimelineModel::HandleConnection(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100156{
157 Entity* outputLayer = FindEntity(relationship.m_HeadGuid);
158 if (outputLayer == nullptr)
159 {
160 std::stringstream ss;
161 ss << "could not find output entity [" << relationship.m_HeadGuid << "]";
162 ss << " of connection [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100163 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100164 return;
165 }
166 Entity* inputLayer = FindEntity(relationship.m_TailGuid);
167 if (inputLayer == nullptr)
168 {
169 std::stringstream ss;
170 ss << "could not find input entity [" << relationship.m_TailGuid << "]";
171 ss << " of connection [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100172 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100173 return;
174 }
175 Connection connection(relationship.m_Guid, outputLayer, inputLayer);
176 outputLayer->AddConnection(connection);
177}
178
Jim Flynnbbfe6032020-07-20 16:57:44 +0100179void TimelineModel::HandleChild(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100180{
181 Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
182 if (parentEntity == nullptr)
183 {
184 std::stringstream ss;
185 ss << "could not find parent entity [" << relationship.m_HeadGuid << "]";
186 ss << " of child relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100187 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100188 return;
189 }
190 Entity* childEntity = FindEntity(relationship.m_TailGuid);
191 if (childEntity == nullptr)
192 {
193 std::stringstream ss;
194 ss << "could not find child entity [" << relationship.m_TailGuid << "]";
195 ss << " of child relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100196 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100197 return;
198 }
199 parentEntity->AddChild(childEntity);
200}
201
Jim Flynnbbfe6032020-07-20 16:57:44 +0100202void TimelineModel::HandleExecutionOf(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100203{
204 Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
205 if (parentEntity == nullptr)
206 {
207 std::stringstream ss;
208 ss << "could not find parent entity [" << relationship.m_HeadGuid << "]";
209 ss << " of execution relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100210 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100211 return;
212 }
213 Entity* executedEntity = FindEntity(relationship.m_TailGuid);
214 if (executedEntity == nullptr)
215 {
216 std::stringstream ss;
217 ss << "could not find executed entity [" << relationship.m_TailGuid << "]";
218 ss << " of execution relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100219 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100220 return;
221 }
222 parentEntity->AddExecution(executedEntity);
223}
224
Jim Flynnbbfe6032020-07-20 16:57:44 +0100225void TimelineModel::HandleExecutionLink(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100226{
227 // entityGuid,
228 Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
229 if (parentEntity == nullptr)
230 {
231 std::stringstream ss;
232 ss << "could not find entity [" << relationship.m_HeadGuid << "]";
233 ss << " of ExecutionLink [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100234 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100235 return;
236 }
237 // eventGuid,
238 EventObj* eventObj = FindEvent(relationship.m_TailGuid);
239 if (eventObj == nullptr)
240 {
241 std::stringstream ss;
242 ss << "could not find event [" << relationship.m_TailGuid << "]";
243 ss << " of ExecutionLink [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100244 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100245 return;
246 }
247 // eventClassGuid
248 EventClassObj* eventClassObj = FindEventClass(relationship.m_AttributeGuid);
249 if (eventClassObj == nullptr)
250 {
251 std::stringstream ss;
252 ss << "could not find event class [" << relationship.m_TailGuid << "]";
253 ss << " of ExecutionLink [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100254 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100255 return;
256 }
257 eventObj->SetEventClass(eventClassObj);
258 parentEntity->AddEvent(eventObj);
259}
260
261ModelRelationship* TimelineModel::FindRelationship(uint64_t id)
Jim Flynn4e755a52020-03-29 17:48:26 +0100262{
263 auto iter = m_Relationships.find(id);
264 if (iter != m_Relationships.end())
265 {
266 return &(iter->second);
267 }
268 else
269 {
270 return nullptr;
271 }
272}
273
Jim Flynn6398a982020-05-27 17:05:21 +0100274bool TimelineModel::IsInferenceGuid(uint64_t guid) const
275{
276 auto it = std::find(m_InferenceGuids.begin(), m_InferenceGuids.end(), guid);
277 return it != m_InferenceGuids.end();
278}
279
Jim Flynnbbfe6032020-07-20 16:57:44 +0100280void TimelineModel::AddEventClass(const arm::pipe::ITimelineDecoder::EventClass& eventClass)
Jim Flynn6398a982020-05-27 17:05:21 +0100281{
282 std::string* eventClassName = FindLabel(eventClass.m_NameGuid);
283 if (eventClassName != nullptr)
284 {
285 EventClassObj eventClassObj(eventClass.m_Guid, *eventClassName);
286 m_EventClasses.emplace(eventClassObj.GetGuid(), eventClassObj);
287 }
288 else
289 {
290 std::stringstream ss;
291 ss << "could not find name [" << eventClass.m_NameGuid << "]";
292 ss << " of of event class [" << eventClass.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100293 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100294 }
295}
296
297EventClassObj* TimelineModel::FindEventClass(uint64_t id)
298{
299 auto iter = m_EventClasses.find(id);
300 if (iter != m_EventClasses.end())
301 {
302 return &(iter->second);
303 }
304 else
305 {
306 return nullptr;
307 }
308}
309
Jim Flynnbbfe6032020-07-20 16:57:44 +0100310void TimelineModel::AddEvent(const arm::pipe::ITimelineDecoder::Event& event)
Jim Flynn6398a982020-05-27 17:05:21 +0100311{
312 EventObj evt(event.m_Guid, event.m_TimeStamp, event.m_ThreadId);
313 m_Events.emplace(event.m_Guid, evt);
314}
315
316EventObj* TimelineModel::FindEvent(uint64_t id)
317{
318 auto iter = m_Events.find(id);
319 if (iter != m_Events.end())
320 {
321 return &(iter->second);
322 }
323 else
324 {
325 return nullptr;
326 }
327}
328
329std::vector<std::string> GetModelDescription(const TimelineModel& model)
330{
331 std::vector<std::string> desc;
332 for (auto& entry : model.GetEntities())
333 {
334 auto& entity = entry.second;
335 desc.push_back(GetEntityDescription(entity));
336 for (auto& connection : entity.GetConnections())
337 {
338 desc.push_back(GetConnectionDescription(connection));
339 }
340 for (auto child : entity.GetChildren())
341 {
342 desc.push_back(GetChildDescription(child));
343 }
344 for (auto execution : entity.GetExecutions())
345 {
346 desc.push_back(GetExecutionDescription(execution));
347 }
348 for (auto event : entity.GetEvents())
349 {
350 desc.push_back(GetEventDescription(event));
351 }
352 }
353 return desc;
354}
355
356std::string GetEntityDescription(const Entity& entity)
357{
358 std::stringstream ss;
359 ss << "Entity [" << entity.GetGuid() << "]";
360 for (auto& attributeEntry : entity.GetAttributes())
361 {
Jim Flynnf7713212020-07-14 09:50:59 +0100362 if (profiling::LabelsAndEventClasses::PROCESS_ID_LABEL == attributeEntry.second.first)
363 {
364 ss << " " << attributeEntry.second.first << " = [processId]";
365 }
366 else {
367 ss << " " << attributeEntry.second.first << " = " << attributeEntry.second.second;
368 }
Jim Flynn6398a982020-05-27 17:05:21 +0100369 }
370 return ss.str();
371}
372
373std::string GetChildDescription(Entity* entity)
374{
375 std::stringstream ss;
376 ss << " child: " << GetEntityDescription(*entity);
377 return ss.str();
378}
379
380std::string GetConnectionDescription(const Connection& connection)
381{
382 std::stringstream ss;
383 ss << " connection [" << connection.GetGuid() << "] from entity [";
384 ss << connection.GetHead()->GetGuid() << "] to entity [" << connection.GetTail()->GetGuid() << "]";
385 return ss.str();
386}
387
388std::string GetExecutionDescription(Entity* execution)
389{
390 std::stringstream ss;
391 ss << " execution: " << GetEntityDescription(*execution);
392 return ss.str();
393}
394
395std::string GetEventDescription(EventObj* event)
396{
397 std::stringstream ss;
398 ss << " event: [" << event->GetGuid() << "] class [" << event->GetEventClass() << "]";
399 return ss.str();
400}
401
Jim Flynn4e755a52020-03-29 17:48:26 +0100402} // namespace profiling
403
404} // namespace armnn