xref: /aosp_15_r20/external/armnn/src/profiling/test/TestTimelinePacketHandler.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include "TestTimelinePacketHandler.hpp"
7*89c4ff92SAndroid Build Coastguard Worker 
8*89c4ff92SAndroid Build Coastguard Worker #include <client/src/IProfilingConnection.hpp>
9*89c4ff92SAndroid Build Coastguard Worker 
10*89c4ff92SAndroid Build Coastguard Worker #include <common/include/LabelsAndEventClasses.hpp>
11*89c4ff92SAndroid Build Coastguard Worker 
12*89c4ff92SAndroid Build Coastguard Worker #include <chrono>
13*89c4ff92SAndroid Build Coastguard Worker #include <iostream>
14*89c4ff92SAndroid Build Coastguard Worker 
15*89c4ff92SAndroid Build Coastguard Worker namespace arm
16*89c4ff92SAndroid Build Coastguard Worker {
17*89c4ff92SAndroid Build Coastguard Worker 
18*89c4ff92SAndroid Build Coastguard Worker namespace pipe
19*89c4ff92SAndroid Build Coastguard Worker {
20*89c4ff92SAndroid Build Coastguard Worker 
GetHeadersAccepted()21*89c4ff92SAndroid Build Coastguard Worker std::vector<uint32_t> TestTimelinePacketHandler::GetHeadersAccepted()
22*89c4ff92SAndroid Build Coastguard Worker {
23*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint32_t> headers;
24*89c4ff92SAndroid Build Coastguard Worker     headers.push_back(m_DirectoryHeader); // message directory
25*89c4ff92SAndroid Build Coastguard Worker     headers.push_back(m_MessageHeader); // message
26*89c4ff92SAndroid Build Coastguard Worker     return headers;
27*89c4ff92SAndroid Build Coastguard Worker }
28*89c4ff92SAndroid Build Coastguard Worker 
HandlePacket(const arm::pipe::Packet & packet)29*89c4ff92SAndroid Build Coastguard Worker void TestTimelinePacketHandler::HandlePacket(const arm::pipe::Packet& packet)
30*89c4ff92SAndroid Build Coastguard Worker {
31*89c4ff92SAndroid Build Coastguard Worker     if (packet.GetHeader() == m_DirectoryHeader)
32*89c4ff92SAndroid Build Coastguard Worker     {
33*89c4ff92SAndroid Build Coastguard Worker         ProcessDirectoryPacket(packet);
34*89c4ff92SAndroid Build Coastguard Worker     }
35*89c4ff92SAndroid Build Coastguard Worker     else if (packet.GetHeader() == m_MessageHeader)
36*89c4ff92SAndroid Build Coastguard Worker     {
37*89c4ff92SAndroid Build Coastguard Worker         ProcessMessagePacket(packet);
38*89c4ff92SAndroid Build Coastguard Worker     }
39*89c4ff92SAndroid Build Coastguard Worker     else
40*89c4ff92SAndroid Build Coastguard Worker     {
41*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
42*89c4ff92SAndroid Build Coastguard Worker         ss << "Received a packet with unknown header [" << packet.GetHeader() << "]";
43*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::ProfilingException(ss.str());
44*89c4ff92SAndroid Build Coastguard Worker     }
45*89c4ff92SAndroid Build Coastguard Worker }
46*89c4ff92SAndroid Build Coastguard Worker 
Stop()47*89c4ff92SAndroid Build Coastguard Worker void TestTimelinePacketHandler::Stop()
48*89c4ff92SAndroid Build Coastguard Worker {
49*89c4ff92SAndroid Build Coastguard Worker     m_Connection->Close();
50*89c4ff92SAndroid Build Coastguard Worker }
51*89c4ff92SAndroid Build Coastguard Worker 
WaitOnInferenceCompletion(unsigned int timeout)52*89c4ff92SAndroid Build Coastguard Worker void TestTimelinePacketHandler::WaitOnInferenceCompletion(unsigned int timeout)
53*89c4ff92SAndroid Build Coastguard Worker {
54*89c4ff92SAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lck(m_InferenceCompletedMutex);
55*89c4ff92SAndroid Build Coastguard Worker 
56*89c4ff92SAndroid Build Coastguard Worker     auto start = std::chrono::high_resolution_clock::now();
57*89c4ff92SAndroid Build Coastguard Worker     // Here we we will go back to sleep after a spurious wake up if
58*89c4ff92SAndroid Build Coastguard Worker     // m_InferenceCompleted is not yet true.
59*89c4ff92SAndroid Build Coastguard Worker     if (!m_InferenceCompletedConditionVariable.wait_for(lck,
60*89c4ff92SAndroid Build Coastguard Worker                                                         std::chrono::milliseconds(timeout),
61*89c4ff92SAndroid Build Coastguard Worker                                                         [&]{return m_InferenceCompleted == true;}))
62*89c4ff92SAndroid Build Coastguard Worker     {
63*89c4ff92SAndroid Build Coastguard Worker         auto finish = std::chrono::high_resolution_clock::now();
64*89c4ff92SAndroid Build Coastguard Worker         std::chrono::duration<double, std::milli> elapsed = finish - start;
65*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
66*89c4ff92SAndroid Build Coastguard Worker         ss << "Timed out waiting on inference completion for " << elapsed.count() << " ms";
67*89c4ff92SAndroid Build Coastguard Worker         throw arm::pipe::TimeoutException(ss.str());
68*89c4ff92SAndroid Build Coastguard Worker     }
69*89c4ff92SAndroid Build Coastguard Worker     return;
70*89c4ff92SAndroid Build Coastguard Worker }
71*89c4ff92SAndroid Build Coastguard Worker 
SetInferenceComplete()72*89c4ff92SAndroid Build Coastguard Worker void TestTimelinePacketHandler::SetInferenceComplete()
73*89c4ff92SAndroid Build Coastguard Worker {
74*89c4ff92SAndroid Build Coastguard Worker     {   // only lock when we are updating the inference completed variable
75*89c4ff92SAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lck(m_InferenceCompletedMutex);
76*89c4ff92SAndroid Build Coastguard Worker         m_InferenceCompleted = true;
77*89c4ff92SAndroid Build Coastguard Worker     }
78*89c4ff92SAndroid Build Coastguard Worker     m_InferenceCompletedConditionVariable.notify_one();
79*89c4ff92SAndroid Build Coastguard Worker }
80*89c4ff92SAndroid Build Coastguard Worker 
ProcessDirectoryPacket(const arm::pipe::Packet & packet)81*89c4ff92SAndroid Build Coastguard Worker void TestTimelinePacketHandler::ProcessDirectoryPacket(const arm::pipe::Packet& packet)
82*89c4ff92SAndroid Build Coastguard Worker {
83*89c4ff92SAndroid Build Coastguard Worker     m_DirectoryDecoder(packet);
84*89c4ff92SAndroid Build Coastguard Worker }
85*89c4ff92SAndroid Build Coastguard Worker 
ProcessMessagePacket(const arm::pipe::Packet & packet)86*89c4ff92SAndroid Build Coastguard Worker void TestTimelinePacketHandler::ProcessMessagePacket(const arm::pipe::Packet& packet)
87*89c4ff92SAndroid Build Coastguard Worker {
88*89c4ff92SAndroid Build Coastguard Worker     m_Decoder(packet);
89*89c4ff92SAndroid Build Coastguard Worker }
90*89c4ff92SAndroid Build Coastguard Worker 
91*89c4ff92SAndroid Build Coastguard Worker // TimelineMessageDecoder functions
CreateEntity(const Entity & entity)92*89c4ff92SAndroid Build Coastguard Worker arm::pipe::ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEntity(const Entity& entity)
93*89c4ff92SAndroid Build Coastguard Worker {
94*89c4ff92SAndroid Build Coastguard Worker     m_TimelineModel.AddEntity(entity.m_Guid);
95*89c4ff92SAndroid Build Coastguard Worker     return arm::pipe::ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
96*89c4ff92SAndroid Build Coastguard Worker }
97*89c4ff92SAndroid Build Coastguard Worker 
CreateEventClass(const arm::pipe::ITimelineDecoder::EventClass & eventClass)98*89c4ff92SAndroid Build Coastguard Worker arm::pipe::ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEventClass(
99*89c4ff92SAndroid Build Coastguard Worker     const arm::pipe::ITimelineDecoder::EventClass& eventClass)
100*89c4ff92SAndroid Build Coastguard Worker {
101*89c4ff92SAndroid Build Coastguard Worker     m_TimelineModel.AddEventClass(eventClass);
102*89c4ff92SAndroid Build Coastguard Worker     return arm::pipe::ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
103*89c4ff92SAndroid Build Coastguard Worker }
104*89c4ff92SAndroid Build Coastguard Worker 
CreateEvent(const arm::pipe::ITimelineDecoder::Event & event)105*89c4ff92SAndroid Build Coastguard Worker arm::pipe::ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEvent(
106*89c4ff92SAndroid Build Coastguard Worker     const arm::pipe::ITimelineDecoder::Event& event)
107*89c4ff92SAndroid Build Coastguard Worker {
108*89c4ff92SAndroid Build Coastguard Worker     m_TimelineModel.AddEvent(event);
109*89c4ff92SAndroid Build Coastguard Worker     return arm::pipe::ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
110*89c4ff92SAndroid Build Coastguard Worker }
111*89c4ff92SAndroid Build Coastguard Worker 
CreateLabel(const arm::pipe::ITimelineDecoder::Label & label)112*89c4ff92SAndroid Build Coastguard Worker arm::pipe::ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateLabel(
113*89c4ff92SAndroid Build Coastguard Worker     const arm::pipe::ITimelineDecoder::Label& label)
114*89c4ff92SAndroid Build Coastguard Worker {
115*89c4ff92SAndroid Build Coastguard Worker     m_TimelineModel.AddLabel(label);
116*89c4ff92SAndroid Build Coastguard Worker     return arm::pipe::ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
117*89c4ff92SAndroid Build Coastguard Worker }
118*89c4ff92SAndroid Build Coastguard Worker 
CreateRelationship(const arm::pipe::ITimelineDecoder::Relationship & relationship)119*89c4ff92SAndroid Build Coastguard Worker arm::pipe::ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateRelationship(
120*89c4ff92SAndroid Build Coastguard Worker     const arm::pipe::ITimelineDecoder::Relationship& relationship)
121*89c4ff92SAndroid Build Coastguard Worker {
122*89c4ff92SAndroid Build Coastguard Worker     m_TimelineModel.AddRelationship(relationship);
123*89c4ff92SAndroid Build Coastguard Worker     // check to see if this is an execution link to an inference of event class end of life
124*89c4ff92SAndroid Build Coastguard Worker     // if so the inference has completed so send out a notification...
125*89c4ff92SAndroid Build Coastguard Worker     if (relationship.m_RelationshipType == RelationshipType::ExecutionLink &&
126*89c4ff92SAndroid Build Coastguard Worker         m_TimelineModel.IsInferenceGuid(relationship.m_HeadGuid))
127*89c4ff92SAndroid Build Coastguard Worker     {
128*89c4ff92SAndroid Build Coastguard Worker         ProfilingStaticGuid attributeGuid(relationship.m_AttributeGuid);
129*89c4ff92SAndroid Build Coastguard Worker         if (attributeGuid == LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS)
130*89c4ff92SAndroid Build Coastguard Worker         {
131*89c4ff92SAndroid Build Coastguard Worker             if (m_PacketHandler != nullptr)
132*89c4ff92SAndroid Build Coastguard Worker             {
133*89c4ff92SAndroid Build Coastguard Worker                 m_PacketHandler->SetInferenceComplete();
134*89c4ff92SAndroid Build Coastguard Worker             }
135*89c4ff92SAndroid Build Coastguard Worker         }
136*89c4ff92SAndroid Build Coastguard Worker     }
137*89c4ff92SAndroid Build Coastguard Worker     return arm::pipe::ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
138*89c4ff92SAndroid Build Coastguard Worker }
139*89c4ff92SAndroid Build Coastguard Worker 
140*89c4ff92SAndroid Build Coastguard Worker } // namespace pipe
141*89c4ff92SAndroid Build Coastguard Worker 
142*89c4ff92SAndroid Build Coastguard Worker } // namespace arm
143