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