aboutsummaryrefslogtreecommitdiff
path: root/src/profiling/test/TestTimelinePacketHandler.cpp
blob: ccb806b2380379009c533ec00119dabefc25f26d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//
// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "TestTimelinePacketHandler.hpp"
#include "IProfilingConnection.hpp"
#include <LabelsAndEventClasses.hpp>

#include <armnn/utility/IgnoreUnused.hpp>

#include <chrono>
#include <iostream>
#include <sstream>

namespace armnn
{

namespace profiling
{

std::vector<uint32_t> TestTimelinePacketHandler::GetHeadersAccepted()
{
    std::vector<uint32_t> headers;
    headers.push_back(m_DirectoryHeader); // message directory
    headers.push_back(m_MessageHeader); // message
    return headers;
}

void TestTimelinePacketHandler::HandlePacket(const Packet& packet)
{
    if (packet.GetHeader() == m_DirectoryHeader)
    {
        ProcessDirectoryPacket(packet);
    }
    else if (packet.GetHeader() == m_MessageHeader)
    {
        ProcessMessagePacket(packet);
    }
    else
    {
        std::stringstream ss;
        ss << "Received a packet with unknown header [" << packet.GetHeader() << "]";
        throw armnn::Exception(ss.str());
    }
}

void TestTimelinePacketHandler::Stop()
{
    m_Connection->Close();
}

void TestTimelinePacketHandler::WaitOnInferenceCompletion(unsigned int timeout)
{
    std::unique_lock<std::mutex> lck(m_InferenceCompletedMutex);

    auto start = std::chrono::high_resolution_clock::now();
    // Here we we will go back to sleep after a spurious wake up if
    // m_InferenceCompleted is not yet true.
    if (!m_InferenceCompletedConditionVariable.wait_for(lck,
                                                        std::chrono::milliseconds(timeout),
                                                        [&]{return m_InferenceCompleted == true;}))
    {
        auto finish = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double, std::milli> elapsed = finish - start;
        std::stringstream ss;
        ss << "Timed out waiting on inference completion for " << elapsed.count() << " ms";
        throw armnn::TimeoutException(ss.str());
    }
    return;
}

void TestTimelinePacketHandler::SetInferenceComplete()
{
    {   // only lock when we are updating the inference completed variable
        std::unique_lock<std::mutex> lck(m_InferenceCompletedMutex);
        m_InferenceCompleted = true;
    }
    m_InferenceCompletedConditionVariable.notify_one();
}

void TestTimelinePacketHandler::ProcessDirectoryPacket(const Packet& packet)
{
    m_DirectoryDecoder(packet);
}

void TestTimelinePacketHandler::ProcessMessagePacket(const Packet& packet)
{
    m_Decoder(packet);
}

// TimelineMessageDecoder functions
ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEntity(const Entity& entity)
{
    m_TimelineModel.AddEntity(entity.m_Guid);
    return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
}

ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEventClass(
    const ITimelineDecoder::EventClass& eventClass)
{
    m_TimelineModel.AddEventClass(eventClass);
    return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
}

ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateEvent(const ITimelineDecoder::Event& event)
{
    m_TimelineModel.AddEvent(event);
    return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
}

ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateLabel(const ITimelineDecoder::Label& label)
{
    m_TimelineModel.AddLabel(label);
    return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
}

ITimelineDecoder::TimelineStatus TimelineMessageDecoder::CreateRelationship(
    const ITimelineDecoder::Relationship& relationship)
{
    m_TimelineModel.AddRelationship(relationship);
    // check to see if this is an execution link to an inference of event class end of life
    // if so the inference has completed so send out a notification...
    if (relationship.m_RelationshipType == RelationshipType::ExecutionLink &&
        m_TimelineModel.IsInferenceGuid(relationship.m_HeadGuid))
    {
        ProfilingStaticGuid attributeGuid(relationship.m_AttributeGuid);
        if (attributeGuid == armnn::profiling::LabelsAndEventClasses::ARMNN_PROFILING_EOL_EVENT_CLASS)
        {
            if (m_PacketHandler != nullptr)
            {
                m_PacketHandler->SetInferenceComplete();
            }
        }
    }
    return ITimelineDecoder::TimelineStatus::TimelineStatus_Success;
}

} // namespace profiling

} // namespace armnn