• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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