1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include "LabelsAndEventClasses.hpp"
6 #include <Threads.hpp>
7 #include "TimelineUtilityMethods.hpp"
8
9 namespace armnn
10 {
11
12 namespace profiling
13 {
14
GetTimelineUtils(ProfilingService & profilingService)15 std::unique_ptr<TimelineUtilityMethods> TimelineUtilityMethods::GetTimelineUtils(ProfilingService& profilingService)
16 {
17 if (profilingService.GetCurrentState() == ProfilingState::Active && profilingService.IsTimelineReportingEnabled())
18 {
19 std::unique_ptr<ISendTimelinePacket> sendTimelinepacket = profilingService.GetSendTimelinePacket();
20 return std::make_unique<TimelineUtilityMethods>(sendTimelinepacket);
21 }
22 else
23 {
24 std::unique_ptr<TimelineUtilityMethods> empty;
25 return empty;
26 }
27 }
28
29
SendWellKnownLabelsAndEventClasses(ISendTimelinePacket & timelinePacket)30 void TimelineUtilityMethods::SendWellKnownLabelsAndEventClasses(ISendTimelinePacket& timelinePacket)
31 {
32 // Send the "name" label, this call throws in case of error
33 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::NAME_GUID,
34 LabelsAndEventClasses::NAME_LABEL);
35
36 // Send the "type" label, this call throws in case of error
37 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::TYPE_GUID,
38 LabelsAndEventClasses::TYPE_LABEL);
39
40 // Send the "index" label, this call throws in case of error
41 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::INDEX_GUID,
42 LabelsAndEventClasses::INDEX_LABEL);
43
44 // Send the "backendId" label, this call throws in case of error
45 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::BACKENDID_GUID,
46 LabelsAndEventClasses::BACKENDID_LABEL);
47
48 // Send the "child" label, this call throws in case of error
49 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::CHILD_GUID,
50 LabelsAndEventClasses::CHILD_LABEL);
51
52 // Send the "execution_of" label, this call throws in case of error
53 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::EXECUTION_OF_GUID,
54 LabelsAndEventClasses::EXECUTION_OF_LABEL);
55
56 // Send the "process_id" label, this call throws in case of error
57 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::PROCESS_ID_GUID,
58 LabelsAndEventClasses::PROCESS_ID_LABEL);
59
60 // Send the "layer" label, this call throws in case of error
61 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::LAYER_GUID,
62 LabelsAndEventClasses::LAYER);
63
64 // Send the "workload" label, this call throws in case of error
65 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::WORKLOAD_GUID,
66 LabelsAndEventClasses::WORKLOAD);
67
68 // Send the "network" label, this call throws in case of error
69 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::NETWORK_GUID,
70 LabelsAndEventClasses::NETWORK);
71
72 // Send the "connection" label, this call throws in case of error
73 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::CONNECTION_GUID,
74 LabelsAndEventClasses::CONNECTION);
75
76 // Send the "inference" label, this call throws in case of error
77 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::INFERENCE_GUID,
78 LabelsAndEventClasses::INFERENCE);
79
80 // Send the "workload_execution" label, this call throws in case of error
81 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID,
82 LabelsAndEventClasses::WORKLOAD_EXECUTION);
83
84 // Send the "start of life" event class, this call throws in case of error
85 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS_NAME_GUID,
86 LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS_NAME);
87 timelinePacket.SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS,
88 LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS_NAME_GUID);
89
90 // Send the "end of life" event class, this call throws in case of error
91 timelinePacket.SendTimelineLabelBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS_NAME_GUID,
92 LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS_NAME);
93 timelinePacket.SendTimelineEventClassBinaryPacket(LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS,
94 LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS_NAME_GUID);
95
96 timelinePacket.Commit();
97 }
98
CreateNamedTypedEntity(const std::string & name,const std::string & type)99 ProfilingDynamicGuid TimelineUtilityMethods::CreateNamedTypedEntity(const std::string& name, const std::string& type)
100 {
101 // Check that the entity name is valid
102 if (name.empty())
103 {
104 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
105 }
106
107 // Check that the entity type is valid
108 if (type.empty())
109 {
110 throw InvalidArgumentException("Invalid entity type, the entity type cannot be empty");
111 }
112
113 // Generate dynamic GUID of the entity
114 ProfilingDynamicGuid entityGuid = profiling::ProfilingService::GetNextGuid();
115
116 CreateNamedTypedEntity(entityGuid, name, type);
117
118 return entityGuid;
119 }
120
CreateNamedTypedEntity(ProfilingGuid entityGuid,const std::string & name,const std::string & type)121 void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingGuid entityGuid,
122 const std::string& name,
123 const std::string& type)
124 {
125 // Check that the entity name is valid
126 if (name.empty())
127 {
128 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
129 }
130
131 // Check that the entity type is valid
132 if (type.empty())
133 {
134 throw InvalidArgumentException("Invalid entity type, the entity type cannot be empty");
135 }
136
137 // Send Entity Binary Packet of the entity to the external profiling service
138 m_SendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
139
140 // Create name entity and send the relationship of the entity with the given name
141 NameEntity(entityGuid, name);
142
143 // Create type entity and send the relationship of the entity with the given type
144 TypeEntity(entityGuid, type);
145 }
146
CreateNamedTypedEntity(ProfilingGuid entityGuid,const std::string & name,ProfilingStaticGuid typeGuid)147 void TimelineUtilityMethods::CreateNamedTypedEntity(ProfilingGuid entityGuid,
148 const std::string& name,
149 ProfilingStaticGuid typeGuid)
150 {
151 // Check that the entity name is valid
152 if (name.empty())
153 {
154 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
155 }
156
157 // Send Entity Binary Packet of the entity to the external profiling service
158 m_SendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
159
160 // Create name entity and send the relationship of the entity with the given name
161 NameEntity(entityGuid, name);
162
163 // Create type entity and send the relationship of the entity with the given type
164 MarkEntityWithType(entityGuid, typeGuid);
165 }
166
DeclareLabel(const std::string & labelName)167 ProfilingStaticGuid TimelineUtilityMethods::DeclareLabel(const std::string& labelName)
168 {
169 // Check that the label name is valid
170 if (labelName.empty())
171 {
172 // The label name is invalid
173 throw InvalidArgumentException("Invalid label name, the label name cannot be empty");
174 }
175
176 // Generate a static GUID for the given label name
177 ProfilingStaticGuid labelGuid = profiling::ProfilingService::GetStaticId(labelName);
178
179 // Send the new label to the external profiling service, this call throws in case of error
180 m_SendTimelinePacket->SendTimelineLabelBinaryPacket(labelGuid, labelName);
181
182 return labelGuid;
183 }
184
MarkEntityWithLabel(ProfilingGuid entityGuid,const std::string & labelName,ProfilingStaticGuid labelTypeGuid)185 void TimelineUtilityMethods::MarkEntityWithLabel(ProfilingGuid entityGuid,
186 const std::string& labelName,
187 ProfilingStaticGuid labelTypeGuid)
188 {
189 // Check that the label name is valid
190 if (labelName.empty())
191 {
192 // The label name is invalid
193 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
194 }
195
196 // Declare a label with the label's name, this call throws in case of error
197 ProfilingStaticGuid labelGuid = DeclareLabel(labelName);
198
199 // Generate a GUID for the label relationship
200 ProfilingDynamicGuid relationshipGuid = profiling::ProfilingService::GetNextGuid();
201
202 // Send the new label link to the external profiling service, this call throws in case of error
203 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
204 relationshipGuid,
205 entityGuid,
206 labelGuid,
207 labelTypeGuid);
208 }
209
MarkEntityWithType(ProfilingGuid entityGuid,ProfilingStaticGuid typeNameGuid)210 void TimelineUtilityMethods::MarkEntityWithType(ProfilingGuid entityGuid,
211 ProfilingStaticGuid typeNameGuid)
212 {
213 // Generate a GUID for the label relationship
214 ProfilingDynamicGuid relationshipGuid = profiling::ProfilingService::GetNextGuid();
215
216 // Send the new label link to the external profiling service, this call throws in case of error
217 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::LabelLink,
218 relationshipGuid,
219 entityGuid,
220 typeNameGuid,
221 LabelsAndEventClasses::TYPE_GUID);
222 }
223
NameEntity(ProfilingGuid entityGuid,const std::string & name)224 void TimelineUtilityMethods::NameEntity(ProfilingGuid entityGuid, const std::string& name)
225 {
226 MarkEntityWithLabel(entityGuid, name, LabelsAndEventClasses::NAME_GUID);
227 }
228
TypeEntity(ProfilingGuid entityGuid,const std::string & type)229 void TimelineUtilityMethods::TypeEntity(ProfilingGuid entityGuid, const std::string& type)
230 {
231 MarkEntityWithLabel(entityGuid, type, LabelsAndEventClasses::TYPE_GUID);
232 }
233
CreateNamedTypedChildEntity(ProfilingGuid parentEntityGuid,const std::string & entityName,const std::string & entityType)234 ProfilingDynamicGuid TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid parentEntityGuid,
235 const std::string& entityName,
236 const std::string& entityType)
237 {
238 // Check that the entity name is valid
239 if (entityName.empty())
240 {
241 // The entity name is invalid
242 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
243 }
244
245 // Check that the entity type is valid
246 if (entityType.empty())
247 {
248 // The entity type is invalid
249 throw InvalidArgumentException("Invalid entity type, the entity type cannot be empty");
250 }
251
252 // Create a named type entity from the given name and type, this call throws in case of error
253 ProfilingDynamicGuid childEntityGuid = CreateNamedTypedEntity(entityName, entityType);
254
255 // Generate a GUID for the retention link relationship
256 ProfilingDynamicGuid retentionLinkGuid = profiling::ProfilingService::GetNextGuid();
257
258 // Send the new retention link to the external profiling service, this call throws in case of error
259 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
260 retentionLinkGuid,
261 parentEntityGuid,
262 childEntityGuid,
263 LabelsAndEventClasses::EMPTY_GUID);
264
265 return childEntityGuid;
266 }
267
CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,ProfilingGuid parentEntityGuid,const std::string & entityName,const std::string & entityType)268 void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,
269 ProfilingGuid parentEntityGuid,
270 const std::string& entityName,
271 const std::string& entityType)
272 {
273 // Check that the entity name is valid
274 if (entityName.empty())
275 {
276 // The entity name is invalid
277 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
278 }
279
280 // Check that the entity type is valid
281 if (entityType.empty())
282 {
283 // The entity type is invalid
284 throw InvalidArgumentException("Invalid entity type, the entity type cannot be empty");
285 }
286
287 // Create a named type entity from the given guid, name and type, this call throws in case of error
288 CreateNamedTypedEntity(childEntityGuid, entityName, entityType);
289
290 // Generate a GUID for the retention link relationship
291 ProfilingDynamicGuid retentionLinkGuid = profiling::ProfilingService::GetNextGuid();
292
293 // Send the new retention link to the external profiling service, this call throws in case of error
294 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
295 retentionLinkGuid,
296 parentEntityGuid,
297 childEntityGuid,
298 LabelsAndEventClasses::CHILD_GUID);
299 }
300
CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,ProfilingGuid parentEntityGuid,const std::string & entityName,ProfilingStaticGuid typeGuid)301 void TimelineUtilityMethods::CreateNamedTypedChildEntity(ProfilingGuid childEntityGuid,
302 ProfilingGuid parentEntityGuid,
303 const std::string& entityName,
304 ProfilingStaticGuid typeGuid)
305 {
306 // Check that the entity name is valid
307 if (entityName.empty())
308 {
309 // The entity name is invalid
310 throw InvalidArgumentException("Invalid entity name, the entity name cannot be empty");
311 }
312
313 // Create a named type entity from the given guid, name and type, this call throws in case of error
314 CreateNamedTypedEntity(childEntityGuid, entityName, typeGuid);
315
316 // Generate a GUID for the retention link relationship
317 ProfilingDynamicGuid retentionLinkGuid = profiling::ProfilingService::GetNextGuid();
318
319 // Send the new retention link to the external profiling service, this call throws in case of error
320 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::RetentionLink,
321 retentionLinkGuid,
322 parentEntityGuid,
323 childEntityGuid,
324 LabelsAndEventClasses::CHILD_GUID);
325 }
326
CreateRelationship(ProfilingRelationshipType relationshipType,ProfilingGuid headGuid,ProfilingGuid tailGuid,ProfilingGuid relationshipCategory)327 ProfilingDynamicGuid TimelineUtilityMethods::CreateRelationship(ProfilingRelationshipType relationshipType,
328 ProfilingGuid headGuid,
329 ProfilingGuid tailGuid,
330 ProfilingGuid relationshipCategory)
331 {
332 // Generate a GUID for the relationship
333 ProfilingDynamicGuid relationshipGuid = profiling::ProfilingService::GetNextGuid();
334
335 // Send the new retention link to the external profiling service, this call throws in case of error
336 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
337 relationshipGuid,
338 headGuid,
339 tailGuid,
340 relationshipCategory);
341 return relationshipGuid;
342 }
343
CreateConnectionRelationship(ProfilingRelationshipType relationshipType,ProfilingGuid headGuid,ProfilingGuid tailGuid)344 ProfilingDynamicGuid TimelineUtilityMethods::CreateConnectionRelationship(ProfilingRelationshipType relationshipType,
345 ProfilingGuid headGuid,
346 ProfilingGuid tailGuid)
347 {
348 // Generate a GUID for the relationship
349 ProfilingDynamicGuid relationshipGuid = profiling::ProfilingService::GetNextGuid();
350
351 // Send the new retention link to the external profiling service, this call throws in case of error
352 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(relationshipType,
353 relationshipGuid,
354 headGuid,
355 tailGuid,
356 LabelsAndEventClasses::CONNECTION_GUID);
357 return relationshipGuid;
358 }
359
CreateTypedEntity(ProfilingGuid entityGuid,ProfilingStaticGuid entityTypeGuid)360 void TimelineUtilityMethods::CreateTypedEntity(ProfilingGuid entityGuid, ProfilingStaticGuid entityTypeGuid)
361 {
362 // Send Entity Binary Packet of the entity to the external profiling service
363 m_SendTimelinePacket->SendTimelineEntityBinaryPacket(entityGuid);
364
365 // Create type entity and send the relationship of the entity with the given type
366 MarkEntityWithType(entityGuid, entityTypeGuid);
367 }
368
RecordEvent(ProfilingGuid entityGuid,ProfilingStaticGuid eventClassGuid)369 ProfilingDynamicGuid TimelineUtilityMethods::RecordEvent(ProfilingGuid entityGuid, ProfilingStaticGuid eventClassGuid)
370 {
371 // Take a timestamp
372 uint64_t timestamp = GetTimestamp();
373
374 // Get the thread id
375 int threadId = armnnUtils::Threads::GetCurrentThreadId();
376
377 // Generate a GUID for the event
378 ProfilingDynamicGuid eventGuid = profiling::ProfilingService::GetNextGuid();
379
380 // Send the new timeline event to the external profiling service, this call throws in case of error
381 m_SendTimelinePacket->SendTimelineEventBinaryPacket(timestamp, threadId, eventGuid);
382
383 // Generate a GUID for the execution link
384 ProfilingDynamicGuid executionLinkId = profiling::ProfilingService::GetNextGuid();
385
386 // Send the new execution link to the external profiling service, this call throws in case of error
387 m_SendTimelinePacket->SendTimelineRelationshipBinaryPacket(ProfilingRelationshipType::ExecutionLink,
388 executionLinkId,
389 entityGuid,
390 eventGuid,
391 eventClassGuid);
392
393 return eventGuid;
394 }
395
RecordWorkloadInferenceAndStartOfLifeEvent(ProfilingGuid workloadGuid,ProfilingGuid inferenceGuid)396 ProfilingDynamicGuid TimelineUtilityMethods::RecordWorkloadInferenceAndStartOfLifeEvent(ProfilingGuid workloadGuid,
397 ProfilingGuid inferenceGuid)
398 {
399 ProfilingDynamicGuid workloadInferenceGuid = profiling::ProfilingService::GetNextGuid();
400 CreateTypedEntity(workloadInferenceGuid, LabelsAndEventClasses::WORKLOAD_EXECUTION_GUID);
401 CreateRelationship(ProfilingRelationshipType::RetentionLink,
402 inferenceGuid,
403 workloadInferenceGuid,
404 LabelsAndEventClasses::CHILD_GUID);
405 CreateRelationship(ProfilingRelationshipType::RetentionLink,
406 workloadGuid,
407 workloadInferenceGuid,
408 LabelsAndEventClasses::EXECUTION_OF_GUID);
409 RecordEvent(workloadInferenceGuid, LabelsAndEventClasses::ARMNN_PROFILING_SOL_EVENT_CLASS);
410 return workloadInferenceGuid;
411 }
412
RecordEndOfLifeEvent(ProfilingGuid entityGuid)413 void TimelineUtilityMethods::RecordEndOfLifeEvent(ProfilingGuid entityGuid)
414 {
415 RecordEvent(entityGuid, LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS);
416 }
417
418 } // namespace profiling
419
420 } // namespace armnn
421