blob: 2584c76020ddb997030460ce575281b3a182547d [file] [log] [blame]
Keith Davis02356de2019-08-26 18:28:17 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Jim Flynn8b200652019-10-24 18:07:44 +01008#include "BufferManager.hpp"
9#include "CommandHandler.hpp"
10#include "ConnectionAcknowledgedCommandHandler.hpp"
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010011#include "CounterDirectory.hpp"
Jim Flynn8e0c7a62020-01-30 14:10:55 +000012#include "CounterIdMap.hpp"
Jim Flynn97897022020-02-02 12:52:59 +000013#include "ICounterRegistry.hpp"
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010014#include "ICounterValues.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010015#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010016#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010017#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010018#include "ProfilingConnectionFactory.hpp"
Jim Flynn00f3aaf2019-10-24 11:58:06 +010019#include "ProfilingGuidGenerator.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010020#include "ProfilingStateMachine.hpp"
21#include "RequestCounterDirectoryCommandHandler.hpp"
22#include "SendCounterPacket.hpp"
Sadik Armagan3896b472020-02-10 12:24:15 +000023#include "SendThread.hpp"
Matteo Martincighcdfb9412019-11-08 11:23:06 +000024#include "SendTimelinePacket.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010025#include "TimelinePacketWriterFactory.hpp"
Colm Donelan1aff3932020-02-05 17:48:59 +000026#include <armnn/backends/profiling/IBackendProfilingContext.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010027
28namespace armnn
29{
30
31namespace profiling
32{
Keith Davise394bd92019-12-02 15:12:19 +000033// Static constants describing ArmNN's counter UID's
34static const uint16_t NETWORK_LOADS = 0;
35static const uint16_t NETWORK_UNLOADS = 1;
36static const uint16_t REGISTERED_BACKENDS = 2;
37static const uint16_t UNREGISTERED_BACKENDS = 3;
38static const uint16_t INFERENCES_RUN = 4;
Finn Williams032bc742020-02-12 11:02:34 +000039static const uint16_t MAX_ARMNN_COUNTER = INFERENCES_RUN;
Keith Davis02356de2019-08-26 18:28:17 +010040
Jim Flynn00f3aaf2019-10-24 11:58:06 +010041class ProfilingService : public IReadWriteCounterValues, public IProfilingGuidGenerator
Keith Davis02356de2019-08-26 18:28:17 +010042{
43public:
Narumol Prangnawarat85ad78c2019-11-18 15:34:23 +000044 using ExternalProfilingOptions = IRuntime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010045 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010046 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
47 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
48 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis02356de2019-08-26 18:28:17 +010049
Matteo Martincigha84edee2019-10-02 12:50:57 +010050 // Getter for the singleton instance
51 static ProfilingService& Instance()
52 {
53 static ProfilingService instance;
54 return instance;
55 }
56
57 // Resets the profiling options, optionally clears the profiling service entirely
58 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
Jim Flynn672d06e2019-10-15 10:18:11 +010059 ProfilingState ConfigureProfilingService(const ExternalProfilingOptions& options,
60 bool resetProfilingService = false);
61
Matteo Martincigha84edee2019-10-02 12:50:57 +010062
Matteo Martincigh54fb9572019-10-02 12:50:57 +010063 // Updates the profiling service, making it transition to a new state if necessary
64 void Update();
Keith Davis02356de2019-08-26 18:28:17 +010065
Jim Flynn53e46992019-10-14 12:31:10 +010066 // Disconnects the profiling service from the external server
67 void Disconnect();
68
Colm Donelan1aff3932020-02-05 17:48:59 +000069 // Store a profiling context returned from a backend that support profiling.
70 void AddBackendProfilingContext(const BackendId backendId,
David Monahanc1536d62020-02-12 15:52:35 +000071 std::shared_ptr<armnn::profiling::IBackendProfilingContext> profilingContext);
Colm Donelan1aff3932020-02-05 17:48:59 +000072
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010073 const ICounterDirectory& GetCounterDirectory() const;
Jim Flynn97897022020-02-02 12:52:59 +000074 ICounterRegistry& GetCounterRegistry();
Keith Davis02356de2019-08-26 18:28:17 +010075 ProfilingState GetCurrentState() const;
Matteo Martincighe8485382019-10-10 14:08:21 +010076 bool IsCounterRegistered(uint16_t counterUid) const override;
Matteo Martincigha84edee2019-10-02 12:50:57 +010077 uint32_t GetCounterValue(uint16_t counterUid) const override;
Keith Davise394bd92019-12-02 15:12:19 +000078 uint16_t GetCounterCount() const override;
Jim Flynn8e0c7a62020-01-30 14:10:55 +000079 // counter global/backend mapping functions
80 const ICounterMappings& GetCounterMappings() const;
Jim Flynn97897022020-02-02 12:52:59 +000081 IRegisterCounterMapping& GetCounterMappingRegistry();
Jim Flynn8e0c7a62020-01-30 14:10:55 +000082
83 // Getters for the profiling service state
Keith Davise394bd92019-12-02 15:12:19 +000084 bool IsProfilingEnabled();
Keith Davis02356de2019-08-26 18:28:17 +010085
James Conroy2dcd3fe2020-02-06 18:34:52 +000086 CaptureData GetCaptureData();
Finn Williams032bc742020-02-12 11:02:34 +000087 void SetCaptureData(uint32_t capturePeriod,
88 const std::vector<uint16_t>& counterIds,
89 const std::set<BackendId>& activeBackends);
James Conroy2dcd3fe2020-02-06 18:34:52 +000090
Matteo Martincigha84edee2019-10-02 12:50:57 +010091 // Setters for the profiling service state
92 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
93 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
94 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
95 uint32_t IncrementCounterValue(uint16_t counterUid) override;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +010096
Jim Flynn00f3aaf2019-10-24 11:58:06 +010097 // IProfilingGuidGenerator functions
98 /// Return the next random Guid in the sequence
99 ProfilingDynamicGuid NextGuid() override;
100 /// Create a ProfilingStaticGuid based on a hash of the string
101 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
102
Jim Flynn8b200652019-10-24 18:07:44 +0100103 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const;
104
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000105 /// Check if the profiling is enabled
106 bool IsEnabled() { return m_Options.m_EnableProfiling; }
107
Keith Davis02356de2019-08-26 18:28:17 +0100108private:
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100109 // Copy/move constructors/destructors and copy/move assignment operators are deleted
Matteo Martincigha84edee2019-10-02 12:50:57 +0100110 ProfilingService(const ProfilingService&) = delete;
111 ProfilingService(ProfilingService&&) = delete;
112 ProfilingService& operator=(const ProfilingService&) = delete;
113 ProfilingService& operator=(ProfilingService&&) = delete;
Keith Davis02356de2019-08-26 18:28:17 +0100114
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100115 // Initialization/reset functions
Matteo Martincigha84edee2019-10-02 12:50:57 +0100116 void Initialize();
117 void InitializeCounterValue(uint16_t counterUid);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100118 void Reset();
Jim Flynn53e46992019-10-14 12:31:10 +0100119 void Stop();
Matteo Martincigha84edee2019-10-02 12:50:57 +0100120
Matteo Martincighe8485382019-10-10 14:08:21 +0100121 // Helper function
122 void CheckCounterUid(uint16_t counterUid) const;
123
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100124 // Profiling service components
Matteo Martincigha84edee2019-10-02 12:50:57 +0100125 ExternalProfilingOptions m_Options;
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100126 CounterDirectory m_CounterDirectory;
Jim Flynn8e0c7a62020-01-30 14:10:55 +0000127 CounterIdMap m_CounterIdMap;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100128 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100129 IProfilingConnectionPtr m_ProfilingConnection;
130 ProfilingStateMachine m_StateMachine;
131 CounterIndices m_CounterIndex;
132 CounterValues m_CounterValues;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100133 CommandHandlerRegistry m_CommandHandlerRegistry;
134 PacketVersionResolver m_PacketVersionResolver;
135 CommandHandler m_CommandHandler;
136 BufferManager m_BufferManager;
137 SendCounterPacket m_SendCounterPacket;
Sadik Armagan3896b472020-02-10 12:24:15 +0000138 SendThread m_SendThread;
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000139 SendTimelinePacket m_SendTimelinePacket;
Matteo Martincighe8485382019-10-10 14:08:21 +0100140 Holder m_Holder;
141 PeriodicCounterCapture m_PeriodicCounterCapture;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100142 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100143 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
Matteo Martincighe8485382019-10-10 14:08:21 +0100144 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
Matteo Martincigh994b5342019-10-11 17:19:56 +0100145 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100146 ProfilingGuidGenerator m_GuidGenerator;
Jim Flynn8b200652019-10-24 18:07:44 +0100147 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Colm Donelan1aff3932020-02-05 17:48:59 +0000148 std::unordered_map<BackendId,
Finn Williams032bc742020-02-12 11:02:34 +0000149 std::shared_ptr<armnn::profiling::IBackendProfilingContext>> m_BackendProfilingContexts;
David Monahanc1536d62020-02-12 15:52:35 +0000150 uint16_t m_MaxGlobalCounterId;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100151
152protected:
153 // Default constructor/destructor kept protected for testing
154 ProfilingService()
155 : m_Options()
156 , m_CounterDirectory()
157 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
158 , m_ProfilingConnection()
159 , m_StateMachine()
160 , m_CounterIndex()
161 , m_CounterValues()
162 , m_CommandHandlerRegistry()
163 , m_PacketVersionResolver()
164 , m_CommandHandler(1000,
165 false,
166 m_CommandHandlerRegistry,
167 m_PacketVersionResolver)
168 , m_BufferManager()
Sadik Armagan3896b472020-02-10 12:24:15 +0000169 , m_SendCounterPacket(m_BufferManager)
170 , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket)
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000171 , m_SendTimelinePacket(m_BufferManager)
Finn Williams032bc742020-02-12 11:02:34 +0000172 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +0100173 , m_ConnectionAcknowledgedCommandHandler(0,
174 1,
Jim Flynned25e0e2019-10-18 13:21:43 +0100175 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +0100176 m_CounterDirectory,
177 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000178 m_SendTimelinePacket,
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100179 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100180 , m_RequestCounterDirectoryCommandHandler(0,
181 3,
Jim Flynned25e0e2019-10-18 13:21:43 +0100182 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100183 m_CounterDirectory,
184 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +0000185 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100186 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100187 , m_PeriodicCounterSelectionCommandHandler(0,
188 4,
Jim Flynned25e0e2019-10-18 13:21:43 +0100189 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Finn Williams032bc742020-02-12 11:02:34 +0000190 m_BackendProfilingContexts,
191 m_CounterIdMap,
Matteo Martincighe8485382019-10-10 14:08:21 +0100192 m_Holder,
Finn Williams032bc742020-02-12 11:02:34 +0000193 MAX_ARMNN_COUNTER,
Matteo Martincighe8485382019-10-10 14:08:21 +0100194 m_PeriodicCounterCapture,
195 *this,
196 m_SendCounterPacket,
197 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100198 , m_PerJobCounterSelectionCommandHandler(0,
199 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100200 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100201 m_StateMachine)
Jim Flynn8b200652019-10-24 18:07:44 +0100202 , m_TimelinePacketWriterFactory(m_BufferManager)
David Monahanc1536d62020-02-12 15:52:35 +0000203 , m_MaxGlobalCounterId(armnn::profiling::INFERENCES_RUN)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100204 {
205 // Register the "Connection Acknowledged" command handler
206 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100207
208 // Register the "Request Counter Directory" command handler
209 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100210
211 // Register the "Periodic Counter Selection" command handler
212 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100213
214 // Register the "Per-Job Counter Selection" command handler
215 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100216 }
janeil01811ca552019-12-03 17:01:32 +0000217 ~ProfilingService();
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100218
Matteo Martincighd0613b52019-10-09 16:47:04 +0100219 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100220 void SwapProfilingConnectionFactory(ProfilingService& instance,
221 IProfilingConnectionFactory* other,
222 IProfilingConnectionFactory*& backup)
223 {
224 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
225 BOOST_ASSERT(other);
226
227 backup = instance.m_ProfilingConnectionFactory.release();
228 instance.m_ProfilingConnectionFactory.reset(other);
229 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100230 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
231 {
232 return instance.m_ProfilingConnection.get();
233 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100234 void TransitionToState(ProfilingService& instance, ProfilingState newState)
235 {
236 instance.m_StateMachine.TransitionToState(newState);
237 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000238 bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100239 {
Sadik Armagan3896b472020-02-10 12:24:15 +0000240 return instance.m_SendThread.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100241 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000242
243 BufferManager& GetBufferManager(ProfilingService& instance)
244 {
245 return instance.m_BufferManager;
246 }
Keith Davis02356de2019-08-26 18:28:17 +0100247};
248
249} // namespace profiling
250
Matteo Martincigha84edee2019-10-02 12:50:57 +0100251} // namespace armnn