blob: b19b983ebcf80b517d930d3b449e2c3436c4ea63 [file] [log] [blame]
Keith Davis3201eea2019-10-24 17:30:41 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Jim Flynn4e755a52020-03-29 17:48:26 +01008#include <armnn/profiling/ILocalPacketHandler.hpp>
Keith Davis3201eea2019-10-24 17:30:41 +01009#include "DirectoryCaptureCommandHandler.hpp"
10#include "IProfilingConnection.hpp"
Finn Williams56b465d2020-05-15 13:34:12 +010011#include <Packet.hpp>
Keith Davis3201eea2019-10-24 17:30:41 +010012#include "ProfilingUtils.hpp"
13#include "Runtime.hpp"
14
Jim Flynn4e755a52020-03-29 17:48:26 +010015#include <atomic>
Colm Donelan4cace322019-11-20 14:59:12 +000016#include <condition_variable>
Keith Davis3201eea2019-10-24 17:30:41 +010017#include <fstream>
Jim Flynn4e755a52020-03-29 17:48:26 +010018#include <mutex>
Keith Davis3201eea2019-10-24 17:30:41 +010019#include <queue>
Jim Flynn4e755a52020-03-29 17:48:26 +010020#include <thread>
Keith Davis3201eea2019-10-24 17:30:41 +010021
22namespace armnn
23{
24
25namespace profiling
26{
27
Jim Flynn01d02812020-04-29 21:12:13 +010028// forward declaration
29class FileOnlyProfilingConnection;
Keith Davis3201eea2019-10-24 17:30:41 +010030
Jim Flynn01d02812020-04-29 21:12:13 +010031class StreamMetaDataProcessor : public ILocalPacketHandler
Keith Davis3201eea2019-10-24 17:30:41 +010032{
33public:
Jim Flynn01d02812020-04-29 21:12:13 +010034 explicit StreamMetaDataProcessor(FileOnlyProfilingConnection* fileOnlyProfilingConnection) :
35 m_FileOnlyProfilingConnection(fileOnlyProfilingConnection),
36 m_MetaDataPacketHeader(ConstructHeader(0, 0)) {};
37
38 std::vector<uint32_t> GetHeadersAccepted() override;
39
40 void HandlePacket(const Packet& packet) override;
41
42private:
43 FileOnlyProfilingConnection* m_FileOnlyProfilingConnection;
44 uint32_t m_MetaDataPacketHeader;
45
46 static uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
47};
48
49class FileOnlyProfilingConnection : public IProfilingConnection, public IInternalProfilingConnection
50{
51public:
52 explicit FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options)
Keith Davis3201eea2019-10-24 17:30:41 +010053 : m_Options(options)
Jim Flynn01d02812020-04-29 21:12:13 +010054 , m_Endianness(TargetEndianness::LeWire) // Set a sensible default.
55 // StreamMetaDataProcessor will set a real value.
Jim Flynn4e755a52020-03-29 17:48:26 +010056 , m_IsRunning(false)
57 , m_KeepRunning(false)
58 , m_Timeout(1000)
59 {
Jim Flynn01d02812020-04-29 21:12:13 +010060 // add the StreamMetaDataProcessor
61 auto streamMetaDataProcessor = std::make_shared<StreamMetaDataProcessor>(this);
62 AddLocalPacketHandler(streamMetaDataProcessor);
63 // and any additional ones added by the users
64 for (const ILocalPacketHandlerSharedPtr& localPacketHandler : options.m_LocalPacketHandlers)
Jim Flynn4e755a52020-03-29 17:48:26 +010065 {
66 AddLocalPacketHandler(localPacketHandler);
67 }
Jim Flynn01d02812020-04-29 21:12:13 +010068 if (!m_PacketHandlers.empty())
Jim Flynn4e755a52020-03-29 17:48:26 +010069 {
70 StartProcessingThread();
71 }
72 // NOTE: could add timeout to the external profiling options
73 };
Keith Davis3201eea2019-10-24 17:30:41 +010074
Jim Flynn01d02812020-04-29 21:12:13 +010075 ~FileOnlyProfilingConnection() override;
Keith Davis3201eea2019-10-24 17:30:41 +010076
77 bool IsOpen() const override;
78
79 void Close() override;
80
81 // This is effectively receiving a data packet from ArmNN.
82 bool WritePacket(const unsigned char* buffer, uint32_t length) override;
83
84 // Sending a packet back to ArmNN.
85 Packet ReadPacket(uint32_t timeout) override;
86
Jim Flynn01d02812020-04-29 21:12:13 +010087 void SetEndianess(const TargetEndianness& endianness) override //IInternalProfilingConnection
88 {
89 m_Endianness = endianness;
90 }
91
92 void ReturnPacket(Packet& packet) override; //IInternalProfilingConnection
93
Keith Davis3201eea2019-10-24 17:30:41 +010094private:
Jim Flynn4e755a52020-03-29 17:48:26 +010095 void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
96 void StartProcessingThread();
97 void ClearReadableList();
98 void DispatchPacketToHandlers(const Packet& packet);
99
Keith Davis3201eea2019-10-24 17:30:41 +0100100 void Fail(const std::string& errorMessage);
101
Jim Flynn4e755a52020-03-29 17:48:26 +0100102 void ForwardPacketToHandlers(Packet& packet);
103 void ServiceLocalHandlers();
104
Keith Davis3201eea2019-10-24 17:30:41 +0100105 Runtime::CreationOptions::ExternalProfilingOptions m_Options;
Keith Davis3201eea2019-10-24 17:30:41 +0100106 std::queue<Packet> m_PacketQueue;
107 TargetEndianness m_Endianness;
Colm Donelan4cace322019-11-20 14:59:12 +0000108
109 std::mutex m_PacketAvailableMutex;
110 std::condition_variable m_ConditionPacketAvailable;
Jim Flynn4e755a52020-03-29 17:48:26 +0100111
112 std::vector<ILocalPacketHandlerSharedPtr> m_PacketHandlers;
113 std::map<uint32_t, std::vector<ILocalPacketHandlerSharedPtr>> m_IndexedHandlers;
114 std::vector<ILocalPacketHandlerSharedPtr> m_UniversalHandlers;
115
116 // List of readable packets for the local packet handlers
117 std::queue<Packet> m_ReadableList;
118 // Mutex and condition variable for the readable packet list
119 std::mutex m_ReadableMutex;
120 std::condition_variable m_ConditionPacketReadable;
121 // thread that takes items from the readable list and dispatches them
122 // to the handlers.
123 std::thread m_LocalHandlersThread;
124 // atomic booleans that control the operation of the local handlers thread
125 std::atomic<bool> m_IsRunning;
126 std::atomic<bool> m_KeepRunning;
127 int m_Timeout;
Keith Davis3201eea2019-10-24 17:30:41 +0100128};
129
130} // namespace profiling
131
132} // namespace armnn