blob: 24ced4494201d7c8bbb3f30f6eb947581ef40c7a [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"
Nikhil Raj77fe76b2021-06-09 14:55:32 +01007
8#include <common/include/LabelsAndEventClasses.hpp>
Jim Flynn6398a982020-05-27 17:05:21 +01009
10#include <algorithm>
Jim Flynn4e755a52020-03-29 17:48:26 +010011
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000012namespace arm
Jim Flynn4e755a52020-03-29 17:48:26 +010013{
14
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000015namespace pipe
Jim Flynn4e755a52020-03-29 17:48:26 +010016{
17
Jim Flynnbbfe6032020-07-20 16:57:44 +010018void TimelineModel::AddLabel(const arm::pipe::ITimelineDecoder::Label& label)
Jim Flynn4e755a52020-03-29 17:48:26 +010019{
20 m_LabelMap.emplace(label.m_Guid, label);
21}
22
Jim Flynn6398a982020-05-27 17:05:21 +010023std::string* TimelineModel::FindLabel(uint64_t guid)
24{
25 auto iter = m_LabelMap.find(guid);
26 if (iter != m_LabelMap.end())
27 {
28 return &iter->second.m_Name;
29 }
30 else
31 {
32 return nullptr;
33 }
34}
35
Jim Flynn4e755a52020-03-29 17:48:26 +010036void TimelineModel::AddEntity(uint64_t guid)
37{
38 m_Entities.emplace(guid, guid);
39}
40
Jim Flynn6398a982020-05-27 17:05:21 +010041Entity* TimelineModel::FindEntity(uint64_t id)
Jim Flynn4e755a52020-03-29 17:48:26 +010042{
43 auto iter = m_Entities.find(id);
44 if (iter != m_Entities.end())
45 {
46 return &(iter->second);
47 }
48 else
49 {
50 return nullptr;
51 }
52}
53
Jim Flynnbbfe6032020-07-20 16:57:44 +010054void TimelineModel::AddRelationship(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn4e755a52020-03-29 17:48:26 +010055{
56 m_Relationships.emplace(relationship.m_Guid, relationship);
Jim Flynnbbfe6032020-07-20 16:57:44 +010057 if (relationship.m_RelationshipType == arm::pipe::ITimelineDecoder::RelationshipType::LabelLink)
Jim Flynn6398a982020-05-27 17:05:21 +010058 {
59 HandleLabelLink(relationship);
60 }
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000061 else if (relationship.m_RelationshipType == ITimelineDecoder::RelationshipType::RetentionLink)
Jim Flynn6398a982020-05-27 17:05:21 +010062 {
63 // Take care of the special case of a connection between layers in ArmNN
64 // modelled by a retention link between two layer entities with an attribute GUID
65 // of connection
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000066 if (relationship.m_AttributeGuid == LabelsAndEventClasses::CONNECTION_GUID)
Jim Flynn6398a982020-05-27 17:05:21 +010067 {
68 HandleConnection(relationship);
69 }
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000070 else if (relationship.m_AttributeGuid == LabelsAndEventClasses::CHILD_GUID)
Jim Flynn6398a982020-05-27 17:05:21 +010071 {
72 HandleChild(relationship);
73 }
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000074 else if (relationship.m_AttributeGuid == LabelsAndEventClasses::EXECUTION_OF_GUID)
Jim Flynn6398a982020-05-27 17:05:21 +010075 {
76 HandleExecutionOf(relationship);
77 }
78 else
79 {
80 // report unknown relationship type
81 std::stringstream ss;
82 ss << "Encountered a RetentionLink of unknown type [" << relationship.m_AttributeGuid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +010083 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +010084 }
85 }
Jim Flynnbbfe6032020-07-20 16:57:44 +010086 else if (relationship.m_RelationshipType == arm::pipe::ITimelineDecoder::RelationshipType::ExecutionLink)
Jim Flynn6398a982020-05-27 17:05:21 +010087 {
88 HandleExecutionLink(relationship);
89 }
Jim Flynn4e755a52020-03-29 17:48:26 +010090}
91
Jim Flynnbbfe6032020-07-20 16:57:44 +010092void TimelineModel::HandleLabelLink(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +010093{
94 Entity* entity = FindEntity(relationship.m_HeadGuid);
95 // we have a label attribute of an entity
96 std::string* value = nullptr;
97 std::string* attribute = nullptr;
98 value = FindLabel(relationship.m_TailGuid);
99 if (value == nullptr)
100 {
101 //report an error
102 std::stringstream ss;
103 ss << "could not find label link [" << relationship.m_Guid <<
104 "] value [" << relationship.m_TailGuid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100105 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100106 }
107 if (relationship.m_AttributeGuid != 0)
108 {
109 attribute = FindLabel(relationship.m_AttributeGuid);
110 if (attribute == nullptr)
111 {
112 //report an error
113 std::stringstream ss;
114 ss << "could not find label link [" << relationship.m_Guid <<
115 "] attribute [" << relationship.m_AttributeGuid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100116 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100117 }
118 }
119 else
120 {
121 //report an error
122 std::stringstream ss;
123 ss << "label link [" << relationship.m_Guid << "] has a zero attribute guid";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100124 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100125 }
126 if (entity != nullptr && attribute != nullptr && value != nullptr)
127 {
128 entity->AddAttribute(*attribute, *value);
129 // if the attribute is 'type' and the value is 'inference'
130 // we need to cache the entity guid as an inference
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000131 if (LabelsAndEventClasses::TYPE_LABEL.compare(*attribute) == 0 &&
132 LabelsAndEventClasses::INFERENCE.compare(*value) == 0)
Jim Flynn6398a982020-05-27 17:05:21 +0100133 {
134 m_InferenceGuids.push_back(relationship.m_HeadGuid);
135 }
136 }
137
138 if (entity == nullptr)
139 {
140 //report an error
141 std::stringstream ss;
142 ss << "could not find label link [" << relationship.m_Guid <<
143 "] entity [" << relationship.m_HeadGuid << "] ";
144 if (value != nullptr)
145 {
146 ss << "value [" << *value << "] ";
147 }
148 if (attribute != nullptr)
149 {
150 ss << "attribute [" << *attribute << "] ";
151 }
Jim Flynnbbfe6032020-07-20 16:57:44 +0100152 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100153 }
154}
155
Jim Flynnbbfe6032020-07-20 16:57:44 +0100156void TimelineModel::HandleConnection(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100157{
158 Entity* outputLayer = FindEntity(relationship.m_HeadGuid);
159 if (outputLayer == nullptr)
160 {
161 std::stringstream ss;
162 ss << "could not find output entity [" << relationship.m_HeadGuid << "]";
163 ss << " of connection [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100164 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100165 return;
166 }
167 Entity* inputLayer = FindEntity(relationship.m_TailGuid);
168 if (inputLayer == nullptr)
169 {
170 std::stringstream ss;
171 ss << "could not find input entity [" << relationship.m_TailGuid << "]";
172 ss << " of connection [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100173 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100174 return;
175 }
176 Connection connection(relationship.m_Guid, outputLayer, inputLayer);
177 outputLayer->AddConnection(connection);
178}
179
Jim Flynnbbfe6032020-07-20 16:57:44 +0100180void TimelineModel::HandleChild(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100181{
182 Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
183 if (parentEntity == nullptr)
184 {
185 std::stringstream ss;
186 ss << "could not find parent entity [" << relationship.m_HeadGuid << "]";
187 ss << " of child relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100188 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100189 return;
190 }
191 Entity* childEntity = FindEntity(relationship.m_TailGuid);
192 if (childEntity == nullptr)
193 {
194 std::stringstream ss;
195 ss << "could not find child entity [" << relationship.m_TailGuid << "]";
196 ss << " of child relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100197 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100198 return;
199 }
200 parentEntity->AddChild(childEntity);
201}
202
Jim Flynnbbfe6032020-07-20 16:57:44 +0100203void TimelineModel::HandleExecutionOf(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100204{
205 Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
206 if (parentEntity == nullptr)
207 {
208 std::stringstream ss;
209 ss << "could not find parent entity [" << relationship.m_HeadGuid << "]";
210 ss << " of execution relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100211 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100212 return;
213 }
214 Entity* executedEntity = FindEntity(relationship.m_TailGuid);
215 if (executedEntity == nullptr)
216 {
217 std::stringstream ss;
218 ss << "could not find executed entity [" << relationship.m_TailGuid << "]";
219 ss << " of execution relationship [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100220 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100221 return;
222 }
223 parentEntity->AddExecution(executedEntity);
224}
225
Jim Flynnbbfe6032020-07-20 16:57:44 +0100226void TimelineModel::HandleExecutionLink(const arm::pipe::ITimelineDecoder::Relationship& relationship)
Jim Flynn6398a982020-05-27 17:05:21 +0100227{
228 // entityGuid,
229 Entity* parentEntity = FindEntity(relationship.m_HeadGuid);
230 if (parentEntity == nullptr)
231 {
232 std::stringstream ss;
233 ss << "could not find entity [" << relationship.m_HeadGuid << "]";
234 ss << " of ExecutionLink [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100235 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100236 return;
237 }
238 // eventGuid,
239 EventObj* eventObj = FindEvent(relationship.m_TailGuid);
240 if (eventObj == nullptr)
241 {
242 std::stringstream ss;
243 ss << "could not find event [" << relationship.m_TailGuid << "]";
244 ss << " of ExecutionLink [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100245 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100246 return;
247 }
248 // eventClassGuid
249 EventClassObj* eventClassObj = FindEventClass(relationship.m_AttributeGuid);
250 if (eventClassObj == nullptr)
251 {
252 std::stringstream ss;
253 ss << "could not find event class [" << relationship.m_TailGuid << "]";
254 ss << " of ExecutionLink [" << relationship.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100255 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100256 return;
257 }
258 eventObj->SetEventClass(eventClassObj);
259 parentEntity->AddEvent(eventObj);
260}
261
262ModelRelationship* TimelineModel::FindRelationship(uint64_t id)
Jim Flynn4e755a52020-03-29 17:48:26 +0100263{
264 auto iter = m_Relationships.find(id);
265 if (iter != m_Relationships.end())
266 {
267 return &(iter->second);
268 }
269 else
270 {
271 return nullptr;
272 }
273}
274
Jim Flynn6398a982020-05-27 17:05:21 +0100275bool TimelineModel::IsInferenceGuid(uint64_t guid) const
276{
277 auto it = std::find(m_InferenceGuids.begin(), m_InferenceGuids.end(), guid);
278 return it != m_InferenceGuids.end();
279}
280
Jim Flynnbbfe6032020-07-20 16:57:44 +0100281void TimelineModel::AddEventClass(const arm::pipe::ITimelineDecoder::EventClass& eventClass)
Jim Flynn6398a982020-05-27 17:05:21 +0100282{
283 std::string* eventClassName = FindLabel(eventClass.m_NameGuid);
284 if (eventClassName != nullptr)
285 {
286 EventClassObj eventClassObj(eventClass.m_Guid, *eventClassName);
287 m_EventClasses.emplace(eventClassObj.GetGuid(), eventClassObj);
288 }
289 else
290 {
291 std::stringstream ss;
292 ss << "could not find name [" << eventClass.m_NameGuid << "]";
293 ss << " of of event class [" << eventClass.m_Guid << "]";
Jim Flynnbbfe6032020-07-20 16:57:44 +0100294 m_Errors.push_back(arm::pipe::ProfilingException(ss.str()));
Jim Flynn6398a982020-05-27 17:05:21 +0100295 }
296}
297
298EventClassObj* TimelineModel::FindEventClass(uint64_t id)
299{
300 auto iter = m_EventClasses.find(id);
301 if (iter != m_EventClasses.end())
302 {
303 return &(iter->second);
304 }
305 else
306 {
307 return nullptr;
308 }
309}
310
Jim Flynnbbfe6032020-07-20 16:57:44 +0100311void TimelineModel::AddEvent(const arm::pipe::ITimelineDecoder::Event& event)
Jim Flynn6398a982020-05-27 17:05:21 +0100312{
313 EventObj evt(event.m_Guid, event.m_TimeStamp, event.m_ThreadId);
314 m_Events.emplace(event.m_Guid, evt);
315}
316
317EventObj* TimelineModel::FindEvent(uint64_t id)
318{
319 auto iter = m_Events.find(id);
320 if (iter != m_Events.end())
321 {
322 return &(iter->second);
323 }
324 else
325 {
326 return nullptr;
327 }
328}
329
330std::vector<std::string> GetModelDescription(const TimelineModel& model)
331{
332 std::vector<std::string> desc;
333 for (auto& entry : model.GetEntities())
334 {
335 auto& entity = entry.second;
336 desc.push_back(GetEntityDescription(entity));
337 for (auto& connection : entity.GetConnections())
338 {
339 desc.push_back(GetConnectionDescription(connection));
340 }
341 for (auto child : entity.GetChildren())
342 {
343 desc.push_back(GetChildDescription(child));
344 }
345 for (auto execution : entity.GetExecutions())
346 {
347 desc.push_back(GetExecutionDescription(execution));
348 }
349 for (auto event : entity.GetEvents())
350 {
351 desc.push_back(GetEventDescription(event));
352 }
353 }
354 return desc;
355}
356
357std::string GetEntityDescription(const Entity& entity)
358{
359 std::stringstream ss;
360 ss << "Entity [" << entity.GetGuid() << "]";
361 for (auto& attributeEntry : entity.GetAttributes())
362 {
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000363 if (LabelsAndEventClasses::PROCESS_ID_LABEL == attributeEntry.second.first)
Jim Flynnf7713212020-07-14 09:50:59 +0100364 {
365 ss << " " << attributeEntry.second.first << " = [processId]";
366 }
367 else {
368 ss << " " << attributeEntry.second.first << " = " << attributeEntry.second.second;
369 }
Jim Flynn6398a982020-05-27 17:05:21 +0100370 }
371 return ss.str();
372}
373
374std::string GetChildDescription(Entity* entity)
375{
376 std::stringstream ss;
377 ss << " child: " << GetEntityDescription(*entity);
378 return ss.str();
379}
380
381std::string GetConnectionDescription(const Connection& connection)
382{
383 std::stringstream ss;
384 ss << " connection [" << connection.GetGuid() << "] from entity [";
385 ss << connection.GetHead()->GetGuid() << "] to entity [" << connection.GetTail()->GetGuid() << "]";
386 return ss.str();
387}
388
389std::string GetExecutionDescription(Entity* execution)
390{
391 std::stringstream ss;
392 ss << " execution: " << GetEntityDescription(*execution);
393 return ss.str();
394}
395
396std::string GetEventDescription(EventObj* event)
397{
398 std::stringstream ss;
399 ss << " event: [" << event->GetGuid() << "] class [" << event->GetEventClass() << "]";
400 return ss.str();
401}
402
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000403} // namespace pipe
Jim Flynn4e755a52020-03-29 17:48:26 +0100404
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000405} // namespace arm