• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include <armnn/profiling/ILocalPacketHandler.hpp>
9 #include "DirectoryCaptureCommandHandler.hpp"
10 #include "IProfilingConnection.hpp"
11 #include "ProfilingUtils.hpp"
12 #include "Runtime.hpp"
13 
14 #include <common/include/Packet.hpp>
15 
16 #include <atomic>
17 #include <condition_variable>
18 #include <fstream>
19 #include <mutex>
20 #include <queue>
21 #include <thread>
22 
23 namespace armnn
24 {
25 
26 namespace profiling
27 {
28 
29 // forward declaration
30 class FileOnlyProfilingConnection;
31 
32 class StreamMetaDataProcessor : public ILocalPacketHandler
33 {
34 public:
StreamMetaDataProcessor(FileOnlyProfilingConnection * fileOnlyProfilingConnection)35     explicit StreamMetaDataProcessor(FileOnlyProfilingConnection* fileOnlyProfilingConnection) :
36             m_FileOnlyProfilingConnection(fileOnlyProfilingConnection),
37             m_MetaDataPacketHeader(ConstructHeader(0, 0)) {};
38 
39     std::vector<uint32_t> GetHeadersAccepted() override;
40 
41     void HandlePacket(const arm::pipe::Packet& packet) override;
42 
43 private:
44     FileOnlyProfilingConnection* m_FileOnlyProfilingConnection;
45     uint32_t m_MetaDataPacketHeader;
46 
47     static uint32_t ToUint32(const unsigned char* data, TargetEndianness endianness);
48 };
49 
50 class FileOnlyProfilingConnection : public IProfilingConnection, public IInternalProfilingConnection
51 {
52 public:
FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions & options)53     explicit FileOnlyProfilingConnection(const Runtime::CreationOptions::ExternalProfilingOptions& options)
54         : m_Options(options)
55         , m_Endianness(TargetEndianness::LeWire)    // Set a sensible default.
56                                                     // StreamMetaDataProcessor will set a real value.
57         , m_IsRunning(false)
58         , m_KeepRunning(false)
59         , m_Timeout(1000)
60     {
61         // add the StreamMetaDataProcessor
62         auto streamMetaDataProcessor = std::make_shared<StreamMetaDataProcessor>(this);
63         AddLocalPacketHandler(streamMetaDataProcessor);
64         // and any additional ones added by the users
65         for (const ILocalPacketHandlerSharedPtr& localPacketHandler : options.m_LocalPacketHandlers)
66         {
67             AddLocalPacketHandler(localPacketHandler);
68         }
69         if (!m_PacketHandlers.empty())
70         {
71             StartProcessingThread();
72         }
73         // NOTE: could add timeout to the external profiling options
74     };
75 
76     ~FileOnlyProfilingConnection() override;
77 
78     bool IsOpen() const override;
79 
80     void Close() override;
81 
82     // This is effectively receiving a data packet from ArmNN.
83     bool WritePacket(const unsigned char* buffer, uint32_t length) override;
84 
85     // Sending a packet back to ArmNN.
86     arm::pipe::Packet ReadPacket(uint32_t timeout) override;
87 
SetEndianess(const TargetEndianness & endianness)88     void SetEndianess(const TargetEndianness& endianness) override //IInternalProfilingConnection
89     {
90         m_Endianness = endianness;
91     }
92 
93     void ReturnPacket(arm::pipe::Packet& packet) override; //IInternalProfilingConnection
94 
95 private:
96     void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
97     void StartProcessingThread();
98     void ClearReadableList();
99     void DispatchPacketToHandlers(const arm::pipe::Packet& packet);
100 
101     void Fail(const std::string& errorMessage);
102 
103     void ForwardPacketToHandlers(arm::pipe::Packet& packet);
104     void ServiceLocalHandlers();
105 
106     Runtime::CreationOptions::ExternalProfilingOptions m_Options;
107     std::queue<arm::pipe::Packet> m_PacketQueue;
108     TargetEndianness m_Endianness;
109 
110     std::mutex m_PacketAvailableMutex;
111     std::condition_variable m_ConditionPacketAvailable;
112 
113     std::vector<ILocalPacketHandlerSharedPtr> m_PacketHandlers;
114     std::map<uint32_t, std::vector<ILocalPacketHandlerSharedPtr>> m_IndexedHandlers;
115     std::vector<ILocalPacketHandlerSharedPtr> m_UniversalHandlers;
116 
117     // List of readable packets for the local packet handlers
118     std::queue<arm::pipe::Packet> m_ReadableList;
119     // Mutex and condition variable for the readable packet list
120     std::mutex m_ReadableMutex;
121     std::condition_variable m_ConditionPacketReadable;
122     // thread that takes items from the readable list and dispatches them
123     // to the handlers.
124     std::thread m_LocalHandlersThread;
125     // atomic booleans that control the operation of the local handlers thread
126     std::atomic<bool> m_IsRunning;
127     std::atomic<bool> m_KeepRunning;
128     int m_Timeout;
129 };
130 
131 }    // namespace profiling
132 
133 }    // namespace armnn