blob: 9e788fd4b35f83b374bd7d1620a5259412de5344 [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 Flynn64063552020-02-14 10:18:08 +000018#include "IProfilingService.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +010019#include "IReportStructure.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010020#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010021#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010022#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010023#include "ProfilingConnectionFactory.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010024#include "ProfilingStateMachine.hpp"
25#include "RequestCounterDirectoryCommandHandler.hpp"
26#include "SendCounterPacket.hpp"
Sadik Armagan3896b472020-02-10 12:24:15 +000027#include "SendThread.hpp"
Matteo Martincighcdfb9412019-11-08 11:23:06 +000028#include "SendTimelinePacket.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010029#include "TimelinePacketWriterFactory.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +010030#include "INotifyBackends.hpp"
Colm Donelan1aff3932020-02-05 17:48:59 +000031#include <armnn/backends/profiling/IBackendProfilingContext.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010032
Nikhil Raj5b1bcc92021-06-08 12:31:50 +010033
Jim Flynnbbfe6032020-07-20 16:57:44 +010034#include <list>
35
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000036namespace arm
Keith Davis02356de2019-08-26 18:28:17 +010037{
38
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000039namespace pipe
Keith Davis02356de2019-08-26 18:28:17 +010040{
41
Jim Flynnaf947722022-03-02 11:04:47 +000042class ProfilingService : public IProfilingService, public INotifyBackends
Keith Davis02356de2019-08-26 18:28:17 +010043{
44public:
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>>;
Cathal Corbett6f073722022-03-04 12:11:09 +000049 using BackendProfilingContext = std::unordered_map<std::string,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000050 std::shared_ptr<IBackendProfilingContext>>;
Keith Davis02356de2019-08-26 18:28:17 +010051
Jim Flynn34430252022-03-04 15:03:58 +000052 ProfilingService(uint16_t maxGlobalCounterId,
53 IInitialiseProfilingService& initialiser,
Jim Flynn9c85b412022-03-16 00:27:43 +000054 const std::string& softwareInfo,
55 const std::string& softwareVersion,
56 const std::string& hardwareVersion,
Jim Flynndecd08b2022-03-13 22:35:46 +000057 arm::pipe::Optional<IReportStructure&> reportStructure = arm::pipe::EmptyOptional())
Matteo Martincigh54fb9572019-10-02 12:50:57 +010058 : m_Options()
Keith Davis33ed2212020-03-30 10:43:41 +010059 , m_TimelineReporting(false)
Matteo Martincigh54fb9572019-10-02 12:50:57 +010060 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
61 , m_ProfilingConnection()
62 , m_StateMachine()
63 , m_CounterIndex()
64 , m_CounterValues()
65 , m_CommandHandlerRegistry()
66 , m_PacketVersionResolver()
67 , m_CommandHandler(1000,
68 false,
69 m_CommandHandlerRegistry,
70 m_PacketVersionResolver)
71 , m_BufferManager()
Jim Flynn9c85b412022-03-16 00:27:43 +000072 , m_SendCounterPacket(m_BufferManager, softwareInfo, softwareVersion, hardwareVersion)
Sadik Armagan3896b472020-02-10 12:24:15 +000073 , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket)
Matteo Martincighcdfb9412019-11-08 11:23:06 +000074 , m_SendTimelinePacket(m_BufferManager)
Finn Williams032bc742020-02-12 11:02:34 +000075 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +010076 , m_ConnectionAcknowledgedCommandHandler(0,
77 1,
Jim Flynned25e0e2019-10-18 13:21:43 +010078 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +010079 m_CounterDirectory,
80 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +000081 m_SendTimelinePacket,
Finn Williamsfe5a24b2020-04-09 16:05:28 +010082 m_StateMachine,
Jim Flynn6398a982020-05-27 17:05:21 +010083 *this,
Finn Williamsfe5a24b2020-04-09 16:05:28 +010084 m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +010085 , m_RequestCounterDirectoryCommandHandler(0,
86 3,
Jim Flynned25e0e2019-10-18 13:21:43 +010087 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +010088 m_CounterDirectory,
89 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +000090 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +010091 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010092 , m_PeriodicCounterSelectionCommandHandler(0,
93 4,
Jim Flynned25e0e2019-10-18 13:21:43 +010094 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Finn Williams032bc742020-02-12 11:02:34 +000095 m_BackendProfilingContexts,
96 m_CounterIdMap,
Matteo Martincighe8485382019-10-10 14:08:21 +010097 m_Holder,
Jim Flynn9c85b412022-03-16 00:27:43 +000098 maxGlobalCounterId,
Matteo Martincighe8485382019-10-10 14:08:21 +010099 m_PeriodicCounterCapture,
100 *this,
101 m_SendCounterPacket,
102 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100103 , m_PerJobCounterSelectionCommandHandler(0,
104 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100105 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100106 m_StateMachine)
Keith Davis33ed2212020-03-30 10:43:41 +0100107 , m_ActivateTimelineReportingCommandHandler(0,
108 6,
109 m_PacketVersionResolver.ResolvePacketVersion(0, 6)
110 .GetEncodedValue(),
111 m_SendTimelinePacket,
112 m_StateMachine,
113 reportStructure,
114 m_TimelineReporting,
Jim Flynn9c85b412022-03-16 00:27:43 +0000115 *this,
Keith Davis33ed2212020-03-30 10:43:41 +0100116 *this)
117 , m_DeactivateTimelineReportingCommandHandler(0,
118 7,
119 m_PacketVersionResolver.ResolvePacketVersion(0, 7)
120 .GetEncodedValue(),
121 m_TimelineReporting,
122 m_StateMachine,
123 *this)
Jim Flynn8b200652019-10-24 18:07:44 +0100124 , m_TimelinePacketWriterFactory(m_BufferManager)
Jim Flynn34430252022-03-04 15:03:58 +0000125 , m_MaxGlobalCounterId(maxGlobalCounterId)
Jim Flynn6398a982020-05-27 17:05:21 +0100126 , m_ServiceActive(false)
Jim Flynn34430252022-03-04 15:03:58 +0000127 , m_Initialiser(initialiser)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100128 {
129 // Register the "Connection Acknowledged" command handler
130 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100131
132 // Register the "Request Counter Directory" command handler
133 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100134
135 // Register the "Periodic Counter Selection" command handler
136 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100137
138 // Register the "Per-Job Counter Selection" command handler
139 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Keith Davis33ed2212020-03-30 10:43:41 +0100140
141 m_CommandHandlerRegistry.RegisterFunctor(&m_ActivateTimelineReportingCommandHandler);
142
143 m_CommandHandlerRegistry.RegisterFunctor(&m_DeactivateTimelineReportingCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100144 }
Sadik Armagan3184c902020-03-18 10:57:30 +0000145
janeil01811ca552019-12-03 17:01:32 +0000146 ~ProfilingService();
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100147
Sadik Armagan3184c902020-03-18 10:57:30 +0000148 // Resets the profiling options, optionally clears the profiling service entirely
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000149 void ResetExternalProfilingOptions(const ProfilingOptions& options,
Jim Flynnaf947722022-03-02 11:04:47 +0000150 bool resetProfilingService = false) override;
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000151 ProfilingState ConfigureProfilingService(const ProfilingOptions& options,
Jim Flynnaf947722022-03-02 11:04:47 +0000152 bool resetProfilingService = false) override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000153
154
155 // Updates the profiling service, making it transition to a new state if necessary
156 void Update();
157
158 // Disconnects the profiling service from the external server
Jim Flynn34430252022-03-04 15:03:58 +0000159 void Disconnect() override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000160
161 // Store a profiling context returned from a backend that support profiling.
Cathal Corbett6f073722022-03-04 12:11:09 +0000162 void AddBackendProfilingContext(const std::string& backendId,
Jim Flynnaf947722022-03-02 11:04:47 +0000163 std::shared_ptr<IBackendProfilingContext> profilingContext) override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000164
Keith Davis33ed2212020-03-30 10:43:41 +0100165 // Enable the recording of timeline events and entities
166 void NotifyBackendsForTimelineReporting() override;
167
Sadik Armagan3184c902020-03-18 10:57:30 +0000168 const ICounterDirectory& GetCounterDirectory() const;
Jim Flynnaf947722022-03-02 11:04:47 +0000169 ICounterRegistry& GetCounterRegistry() override;
170 ProfilingState GetCurrentState() const override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000171 bool IsCounterRegistered(uint16_t counterUid) const override;
Finn Williamsf3fcf322020-05-11 14:38:02 +0100172 uint32_t GetAbsoluteCounterValue(uint16_t counterUid) const override;
173 uint32_t GetDeltaCounterValue(uint16_t counterUid) override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000174 uint16_t GetCounterCount() const override;
175 // counter global/backend mapping functions
176 const ICounterMappings& GetCounterMappings() const override;
Jim Flynnaf947722022-03-02 11:04:47 +0000177 IRegisterCounterMapping& GetCounterMappingRegistry() override;
Jim Flynn34430252022-03-04 15:03:58 +0000178 bool IsCategoryRegistered(const std::string& categoryName) const override;
179 bool IsCounterRegistered(const std::string& counterName) const override;
Sadik Armagan3184c902020-03-18 10:57:30 +0000180
181 // Getters for the profiling service state
182 bool IsProfilingEnabled() const override;
183
184 CaptureData GetCaptureData() override;
185 void SetCaptureData(uint32_t capturePeriod,
186 const std::vector<uint16_t>& counterIds,
Cathal Corbett6f073722022-03-04 12:11:09 +0000187 const std::set<std::string>& activeBackends);
Sadik Armagan3184c902020-03-18 10:57:30 +0000188
189 // Setters for the profiling service state
190 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
191 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
192 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
193 uint32_t IncrementCounterValue(uint16_t counterUid) override;
194
Jim Flynn34430252022-03-04 15:03:58 +0000195 void InitializeCounterValue(uint16_t counterUid) override;
196
Sadik Armagan3184c902020-03-18 10:57:30 +0000197 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override;
198
199 ISendCounterPacket& GetSendCounterPacket() override
200 {
201 return m_SendCounterPacket;
202 }
203
Jim Flynnaf947722022-03-02 11:04:47 +0000204 bool IsTimelineReportingEnabled() const override
Keith Davis33ed2212020-03-30 10:43:41 +0100205 {
206 return m_TimelineReporting;
207 }
208
Jim Flynn4e755a52020-03-29 17:48:26 +0100209 void AddLocalPacketHandler(ILocalPacketHandlerSharedPtr localPacketHandler);
Jim Flynn6398a982020-05-27 17:05:21 +0100210
211 void NotifyProfilingServiceActive() override; // IProfilingServiceStatus
212 void WaitForProfilingServiceActivation(unsigned int timeout) override; // IProfilingServiceStatus
213
Sadik Armagan3184c902020-03-18 10:57:30 +0000214private:
215 //Copy/move constructors/destructors and copy/move assignment operators are deleted
216 ProfilingService(const ProfilingService&) = delete;
217 ProfilingService(ProfilingService&&) = delete;
218 ProfilingService& operator=(const ProfilingService&) = delete;
219 ProfilingService& operator=(ProfilingService&&) = delete;
220
221 // Initialization/reset functions
222 void Initialize();
Sadik Armagan3184c902020-03-18 10:57:30 +0000223 void Reset();
224 void Stop();
225
226 // Helper function
227 void CheckCounterUid(uint16_t counterUid) const;
228
229 // Profiling service components
Jim Flynn4c9ed1d2022-01-23 23:57:20 +0000230 ProfilingOptions m_Options;
Jim Flynnbbfe6032020-07-20 16:57:44 +0100231 std::atomic<bool> m_TimelineReporting;
232 CounterDirectory m_CounterDirectory;
233 CounterIdMap m_CounterIdMap;
234 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
235 IProfilingConnectionPtr m_ProfilingConnection;
236 ProfilingStateMachine m_StateMachine;
237 CounterIndices m_CounterIndex;
238 CounterValues m_CounterValues;
239 arm::pipe::CommandHandlerRegistry m_CommandHandlerRegistry;
240 arm::pipe::PacketVersionResolver m_PacketVersionResolver;
241 CommandHandler m_CommandHandler;
242 BufferManager m_BufferManager;
243 SendCounterPacket m_SendCounterPacket;
244 SendThread m_SendThread;
245 SendTimelinePacket m_SendTimelinePacket;
Keith Davis33ed2212020-03-30 10:43:41 +0100246
Sadik Armagan3184c902020-03-18 10:57:30 +0000247 Holder m_Holder;
Keith Davis33ed2212020-03-30 10:43:41 +0100248
Sadik Armagan3184c902020-03-18 10:57:30 +0000249 PeriodicCounterCapture m_PeriodicCounterCapture;
Keith Davis33ed2212020-03-30 10:43:41 +0100250
251 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
252 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
253 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
254 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
255 ActivateTimelineReportingCommandHandler m_ActivateTimelineReportingCommandHandler;
256 DeactivateTimelineReportingCommandHandler m_DeactivateTimelineReportingCommandHandler;
Sadik Armagan3184c902020-03-18 10:57:30 +0000257
258 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Keith Davis33ed2212020-03-30 10:43:41 +0100259 BackendProfilingContext m_BackendProfilingContexts;
260 uint16_t m_MaxGlobalCounterId;
Sadik Armagan3184c902020-03-18 10:57:30 +0000261
Jim Flynn6398a982020-05-27 17:05:21 +0100262 // Signalling to let external actors know when service is active or not
263 std::mutex m_ServiceActiveMutex;
264 std::condition_variable m_ServiceActiveConditionVariable;
265 bool m_ServiceActive;
266
Jim Flynn34430252022-03-04 15:03:58 +0000267 IInitialiseProfilingService& m_Initialiser;
268
Sadik Armagan3184c902020-03-18 10:57:30 +0000269protected:
270
Matteo Martincighd0613b52019-10-09 16:47:04 +0100271 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100272 void SwapProfilingConnectionFactory(ProfilingService& instance,
273 IProfilingConnectionFactory* other,
274 IProfilingConnectionFactory*& backup)
275 {
Jim Flynn6730fe92022-03-10 22:57:47 +0000276 ARM_PIPE_ASSERT(instance.m_ProfilingConnectionFactory);
277 ARM_PIPE_ASSERT(other);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100278
279 backup = instance.m_ProfilingConnectionFactory.release();
280 instance.m_ProfilingConnectionFactory.reset(other);
281 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100282 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
283 {
284 return instance.m_ProfilingConnection.get();
285 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100286 void TransitionToState(ProfilingService& instance, ProfilingState newState)
287 {
288 instance.m_StateMachine.TransitionToState(newState);
289 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000290 bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100291 {
Sadik Armagan3896b472020-02-10 12:24:15 +0000292 return instance.m_SendThread.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100293 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000294
295 BufferManager& GetBufferManager(ProfilingService& instance)
296 {
297 return instance.m_BufferManager;
298 }
Keith Davis02356de2019-08-26 18:28:17 +0100299};
300
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000301} // namespace pipe
Keith Davis02356de2019-08-26 18:28:17 +0100302
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000303} // namespace arm