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