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 Workerstd::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 Workervoid 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 Workervoid 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 Workervoid 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 Workervoid 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 Workervoid 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 Workervoid 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 Workerarm::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 Workerarm::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 Workerarm::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 Workerarm::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 Workerarm::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