blob: ab71b0c7684689a5de0ff5b71e9168c332d7a3f9 [file] [log] [blame]
Keith Davis02356de2019-08-26 18:28:17 +01001//
Jim Flynn6398a982020-05-27 17:05:21 +01002// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
Keith Davis02356de2019-08-26 18:28:17 +01003// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Keith Davis33ed2212020-03-30 10:43:41 +01008#include "ActivateTimelineReportingCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +01009#include "BufferManager.hpp"
10#include "CommandHandler.hpp"
11#include "ConnectionAcknowledgedCommandHandler.hpp"
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010012#include "CounterDirectory.hpp"
Jim Flynn8e0c7a62020-01-30 14:10:55 +000013#include "CounterIdMap.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +010014#include "DeactivateTimelineReportingCommandHandler.hpp"
Jim Flynn97897022020-02-02 12:52:59 +000015#include "ICounterRegistry.hpp"
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010016#include "ICounterValues.hpp"
Jim Flynn4e755a52020-03-29 17:48:26 +010017#include <armnn/profiling/ILocalPacketHandler.hpp>
Jim Flynn4c9ed1d2022-01-23 23:57:20 +000018#include <armnn/profiling/ProfilingOptions.hpp>
Jim Flynn64063552020-02-14 10:18:08 +000019#include "IProfilingService.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +010020#include "IReportStructure.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010021#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010022#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010023#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010024#include "ProfilingConnectionFactory.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010025#include "ProfilingStateMachine.hpp"
26#include "RequestCounterDirectoryCommandHandler.hpp"
27#include "SendCounterPacket.hpp"
Sadik Armagan3896b472020-02-10 12:24:15 +000028#include "SendThread.hpp"
Matteo Martincighcdfb9412019-11-08 11:23:06 +000029#include "SendTimelinePacket.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010030#include "TimelinePacketWriterFactory.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +010031#include "INotifyBackends.hpp"
Colm Donelan1aff3932020-02-05 17:48:59 +000032#include <armnn/backends/profiling/IBackendProfilingContext.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010033
Nikhil Raj5b1bcc92021-06-08 12:31:50 +010034#include <common/include/ProfilingGuidGenerator.hpp>
35
Jim Flynnbbfe6032020-07-20 16:57:44 +010036#include <list>
37
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000038namespace arm
Keith Davis02356de2019-08-26 18:28:17 +010039{
40
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000041namespace pipe
Keith Davis02356de2019-08-26 18:28:17 +010042{
Keith Davise394bd92019-12-02 15:12:19 +000043// Static constants describing ArmNN's counter UID's
Keith Davis33ed2212020-03-30 10:43:41 +010044static const uint16_t NETWORK_LOADS = 0;
45static const uint16_t NETWORK_UNLOADS = 1;
46static const uint16_t REGISTERED_BACKENDS = 2;
47static const uint16_t UNREGISTERED_BACKENDS = 3;
48static const uint16_t INFERENCES_RUN = 4;
49static const uint16_t MAX_ARMNN_COUNTER = INFERENCES_RUN;
Keith Davis02356de2019-08-26 18:28:17 +010050
Keith Davis33ed2212020-03-30 10:43:41 +010051class ProfilingService : public IReadWriteCounterValues, public IProfilingService, public INotifyBackends
Keith Davis02356de2019-08-26 18:28:17 +010052{
53public:
Matteo Martincigh54fb9572019-10-02 12:50:57 +010054 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010055 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
56 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
57 using CounterValues = std::list<std::atomic<uint32_t>>;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000058 using BackendProfilingContext = std::unordered_map<armnn::BackendId,
59 std::shared_ptr<IBackendProfilingContext>>;
Keith Davis02356de2019-08-26 18:28:17 +010060
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000061 ProfilingService(armnn::Optional<IReportStructure&> reportStructure = armnn::EmptyOptional())
Matteo Martincigh54fb9572019-10-02 12:50:57 +010062 : m_Options()
Keith Davis33ed2212020-03-30 10:43:41 +010063 , m_TimelineReporting(false)
Matteo Martincigh54fb9572019-10-02 12:50:57 +010064 , m_CounterDirectory()
65 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
66 , m_ProfilingConnection()
67 , m_StateMachine()
68 , m_CounterIndex()
69 , m_CounterValues()
70 , m_CommandHandlerRegistry()
71 , m_PacketVersionResolver()
72 , m_CommandHandler(1000,
73 false,
74 m_CommandHandlerRegistry,
75 m_PacketVersionResolver)
76 , m_BufferManager()
Sadik Armagan3896b472020-02-10 12:24:15 +000077 , m_SendCounterPacket(m_BufferManager)
78 , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket)
Matteo Martincighcdfb9412019-11-08 11:23:06 +000079 , m_SendTimelinePacket(m_BufferManager)
Finn Williams032bc742020-02-12 11:02:34 +000080 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +010081 , m_ConnectionAcknowledgedCommandHandler(0,
82 1,
Jim Flynned25e0e2019-10-18 13:21:43 +010083 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +010084 m_CounterDirectory,
85 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +000086 m_SendTimelinePacket,
Finn Williamsfe5a24b2020-04-09 16:05:28 +010087 m_StateMachine,
Jim Flynn6398a982020-05-27 17:05:21 +010088 *this,
Finn Williamsfe5a24b2020-04-09 16:05:28 +010089 m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +010090 , m_RequestCounterDirectoryCommandHandler(0,
91 3,
Jim Flynned25e0e2019-10-18 13:21:43 +010092 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +010093 m_CounterDirectory,
94 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +000095 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +010096 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010097 , m_PeriodicCounterSelectionCommandHandler(0,
98 4,
Jim Flynned25e0e2019-10-18 13:21:43 +010099 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Finn Williams032bc742020-02-12 11:02:34 +0000100 m_BackendProfilingContexts,
101 m_CounterIdMap,
Matteo Martincighe8485382019-10-10 14:08:21 +0100102 m_Holder,
Finn Williams032bc742020-02-12 11:02:34 +0000103 MAX_ARMNN_COUNTER,
Matteo Martincighe8485382019-10-10 14:08:21 +0100104 m_PeriodicCounterCapture,
105 *this,
106 m_SendCounterPacket,
107 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100108 , m_PerJobCounterSelectionCommandHandler(0,
109 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100110 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100111 m_StateMachine)
Keith Davis33ed2212020-03-30 10:43:41 +0100112 , m_ActivateTimelineReportingCommandHandler(0,
113 6,
114 m_PacketVersionResolver.ResolvePacketVersion(0, 6)
115 .GetEncodedValue(),
116 m_SendTimelinePacket,
117 m_StateMachine,
118 reportStructure,
119 m_TimelineReporting,
120 *this)
121 , m_DeactivateTimelineReportingCommandHandler(0,
122 7,
123 m_PacketVersionResolver.ResolvePacketVersion(0, 7)
124 .GetEncodedValue(),
125 m_TimelineReporting,
126 m_StateMachine,
127 *this)
Jim Flynn8b200652019-10-24 18:07:44 +0100128 , m_TimelinePacketWriterFactory(m_BufferManager)
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000129 , m_MaxGlobalCounterId(INFERENCES_RUN)
Jim Flynn6398a982020-05-27 17:05:21 +0100130 , m_ServiceActive(false)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100131 {
132 // Register the "Connection Acknowledged" command handler
133 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100134
135 // Register the "Request Counter Directory" command handler
136 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100137
138 // Register the "Periodic Counter Selection" command handler
139 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100140
141 // Register the "Per-Job Counter Selection" command handler
142 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Keith Davis33ed2212020-03-30 10:43:41 +0100143
144 m_CommandHandlerRegistry.RegisterFunctor(&m_ActivateTimelineReportingCommandHandler);
145
146 m_CommandHandlerRegistry.RegisterFunctor(&m_DeactivateTimelineReportingCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100147 }
Sadik Armagan3184c902020-03-18 10:57:30 +0000148
janeil01811ca552019-12-03 17:01:32 +0000149 ~ProfilingService();
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100150
Sadik Armagan3184c902020-03-18 10:57:30 +0000151 // Resets the profiling options, optionally clears the profiling service entirely
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000152 void ResetExternalProfilingOptions(const ProfilingOptions& options,
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000153 bool resetProfilingService = false);
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000154 ProfilingState ConfigureProfilingService(const ProfilingOptions& options,
Sadik Armagan3184c902020-03-18 10:57:30 +0000155 bool resetProfilingService = false);
156
157
158 // Updates the profiling service, making it transition to a new state if necessary
159 void Update();
160
161 // Disconnects the profiling service from the external server
162 void Disconnect();
163
164 // Store a profiling context returned from a backend that support profiling.
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000165 void AddBackendProfilingContext(const armnn::BackendId backendId,
166 std::shared_ptr<IBackendProfilingContext> profilingContext);
Sadik Armagan3184c902020-03-18 10:57:30 +0000167
Keith Davis33ed2212020-03-30 10:43:41 +0100168 // Enable the recording of timeline events and entities
169 void NotifyBackendsForTimelineReporting() override;
170
Sadik Armagan3184c902020-03-18 10:57:30 +0000171 const ICounterDirectory& GetCounterDirectory() const;
172 ICounterRegistry& GetCounterRegistry();
173 ProfilingState GetCurrentState() const;
174 bool IsCounterRegistered(uint16_t counterUid) const override;
Finn Williamsf3fcf322020-05-11 14:38:02 +0100175 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override;
176 uint32_t GetDeltaCounterValue(uint16_t counterUid) override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000177 uint16_t GetCounterCount() const override;
178 // counter global/backend mapping functions
179 const ICounterMappings& GetCounterMappings() const override;
180 IRegisterCounterMapping& GetCounterMappingRegistry();
181
182 // Getters for the profiling service state
183 bool IsProfilingEnabled() const override;
184
185 CaptureData GetCaptureData() override;
186 void SetCaptureData(uint32_t capturePeriod,
187 const std::vector<uint16_t>& counterIds,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000188 const std::set<armnn::BackendId>& activeBackends);
Sadik Armagan3184c902020-03-18 10:57:30 +0000189
190 // Setters for the profiling service state
191 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
192 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
193 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
194 uint32_t IncrementCounterValue(uint16_t counterUid) override;
195
196 // IProfilingGuidGenerator functions
197 /// Return the next random Guid in the sequence
198 ProfilingDynamicGuid NextGuid() override;
199 /// Create a ProfilingStaticGuid based on a hash of the string
200 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
201
Jim Flynn6398a982020-05-27 17:05:21 +0100202
Sadik Armagan3184c902020-03-18 10:57:30 +0000203 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override;
204
205 ISendCounterPacket& GetSendCounterPacket() override
206 {
207 return m_SendCounterPacket;
208 }
209
Sadik Armagan3184c902020-03-18 10:57:30 +0000210 static ProfilingDynamicGuid GetNextGuid();
211
212 static ProfilingStaticGuid GetStaticId(const std::string& str);
213
Jim Flynn6398a982020-05-27 17:05:21 +0100214 void ResetGuidGenerator();
215
Keith Davis33ed2212020-03-30 10:43:41 +0100216 bool IsTimelineReportingEnabled()
217 {
218 return m_TimelineReporting;
219 }
220
Jim Flynn4e755a52020-03-29 17:48:26 +0100221 void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
Jim Flynn6398a982020-05-27 17:05:21 +0100222
223 void NotifyProfilingServiceActive() override; // IProfilingServiceStatus
224 void WaitForProfilingServiceActivation(unsigned int timeout) override; // IProfilingServiceStatus
225
Sadik Armagan3184c902020-03-18 10:57:30 +0000226private:
227 //Copy/move constructors/destructors and copy/move assignment operators are deleted
228 ProfilingService(const ProfilingService&) = delete;
229 ProfilingService(ProfilingService&&) = delete;
230 ProfilingService& operator=(const ProfilingService&) = delete;
231 ProfilingService& operator=(ProfilingService&&) = delete;
232
233 // Initialization/reset functions
234 void Initialize();
235 void InitializeCounterValue(uint16_t counterUid);
236 void Reset();
237 void Stop();
238
239 // Helper function
240 void CheckCounterUid(uint16_t counterUid) const;
241
242 // Profiling service components
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000243 ProfilingOptions m_Options;
Jim Flynnbbfe6032020-07-20 16:57:44 +0100244 std::atomic<bool> m_TimelineReporting;
245 CounterDirectory m_CounterDirectory;
246 CounterIdMap m_CounterIdMap;
247 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
248 IProfilingConnectionPtr m_ProfilingConnection;
249 ProfilingStateMachine m_StateMachine;
250 CounterIndices m_CounterIndex;
251 CounterValues m_CounterValues;
252 arm::pipe::CommandHandlerRegistry m_CommandHandlerRegistry;
253 arm::pipe::PacketVersionResolver m_PacketVersionResolver;
254 CommandHandler m_CommandHandler;
255 BufferManager m_BufferManager;
256 SendCounterPacket m_SendCounterPacket;
257 SendThread m_SendThread;
258 SendTimelinePacket m_SendTimelinePacket;
Keith Davis33ed2212020-03-30 10:43:41 +0100259
Sadik Armagan3184c902020-03-18 10:57:30 +0000260 Holder m_Holder;
Keith Davis33ed2212020-03-30 10:43:41 +0100261
Sadik Armagan3184c902020-03-18 10:57:30 +0000262 PeriodicCounterCapture m_PeriodicCounterCapture;
Keith Davis33ed2212020-03-30 10:43:41 +0100263
264 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
265 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
266 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
267 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
268 ActivateTimelineReportingCommandHandler m_ActivateTimelineReportingCommandHandler;
269 DeactivateTimelineReportingCommandHandler m_DeactivateTimelineReportingCommandHandler;
Sadik Armagan3184c902020-03-18 10:57:30 +0000270
271 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Keith Davis33ed2212020-03-30 10:43:41 +0100272 BackendProfilingContext m_BackendProfilingContexts;
273 uint16_t m_MaxGlobalCounterId;
Sadik Armagan3184c902020-03-18 10:57:30 +0000274
275 static ProfilingGuidGenerator m_GuidGenerator;
276
Jim Flynn6398a982020-05-27 17:05:21 +0100277 // Signalling to let external actors know when service is active or not
278 std::mutex m_ServiceActiveMutex;
279 std::condition_variable m_ServiceActiveConditionVariable;
280 bool m_ServiceActive;
281
Sadik Armagan3184c902020-03-18 10:57:30 +0000282protected:
283
Matteo Martincighd0613b52019-10-09 16:47:04 +0100284 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100285 void SwapProfilingConnectionFactory(ProfilingService& instance,
286 IProfilingConnectionFactory* other,
287 IProfilingConnectionFactory*& backup)
288 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100289 ARMNN_ASSERT(instance.m_ProfilingConnectionFactory);
290 ARMNN_ASSERT(other);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100291
292 backup = instance.m_ProfilingConnectionFactory.release();
293 instance.m_ProfilingConnectionFactory.reset(other);
294 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100295 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
296 {
297 return instance.m_ProfilingConnection.get();
298 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100299 void TransitionToState(ProfilingService& instance, ProfilingState newState)
300 {
301 instance.m_StateMachine.TransitionToState(newState);
302 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000303 bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100304 {
Sadik Armagan3896b472020-02-10 12:24:15 +0000305 return instance.m_SendThread.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100306 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000307
308 BufferManager& GetBufferManager(ProfilingService& instance)
309 {
310 return instance.m_BufferManager;
311 }
Keith Davis02356de2019-08-26 18:28:17 +0100312};
313
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000314} // namespace pipe
Keith Davis02356de2019-08-26 18:28:17 +0100315
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000316} // namespace arm