blob: df7bd8f857c4d39f83b6dc1b220c5819ce8768fe [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
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 Flynn64063552020-02-14 10:18:08 +000017#include "IProfilingService.hpp"
Keith Davis33ed2212020-03-30 10:43:41 +010018#include "IReportStructure.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010019#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010020#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010021#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010022#include "ProfilingConnectionFactory.hpp"
Jim Flynn00f3aaf2019-10-24 11:58:06 +010023#include "ProfilingGuidGenerator.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
33namespace armnn
34{
35
36namespace profiling
37{
Keith Davise394bd92019-12-02 15:12:19 +000038// Static constants describing ArmNN's counter UID's
Keith Davis33ed2212020-03-30 10:43:41 +010039static const uint16_t NETWORK_LOADS = 0;
40static const uint16_t NETWORK_UNLOADS = 1;
41static const uint16_t REGISTERED_BACKENDS = 2;
42static const uint16_t UNREGISTERED_BACKENDS = 3;
43static const uint16_t INFERENCES_RUN = 4;
44static const uint16_t MAX_ARMNN_COUNTER = INFERENCES_RUN;
Keith Davis02356de2019-08-26 18:28:17 +010045
Keith Davis33ed2212020-03-30 10:43:41 +010046class ProfilingService : public IReadWriteCounterValues, public IProfilingService, public INotifyBackends
Keith Davis02356de2019-08-26 18:28:17 +010047{
48public:
Narumol Prangnawarat85ad78c2019-11-18 15:34:23 +000049 using ExternalProfilingOptions = IRuntime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010050 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010051 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
52 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
53 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis33ed2212020-03-30 10:43:41 +010054 using BackendProfilingContext = std::unordered_map<BackendId,
55 std::shared_ptr<armnn::profiling::IBackendProfilingContext>>;
Keith Davis02356de2019-08-26 18:28:17 +010056
Keith Davis33ed2212020-03-30 10:43:41 +010057 ProfilingService(Optional<IReportStructure&> reportStructure = 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_CounterDirectory()
61 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
62 , m_ProfilingConnection()
63 , m_StateMachine()
64 , m_CounterIndex()
65 , m_CounterValues()
66 , m_CommandHandlerRegistry()
67 , m_PacketVersionResolver()
68 , m_CommandHandler(1000,
69 false,
70 m_CommandHandlerRegistry,
71 m_PacketVersionResolver)
72 , m_BufferManager()
Sadik Armagan3896b472020-02-10 12:24:15 +000073 , m_SendCounterPacket(m_BufferManager)
74 , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket)
Matteo Martincighcdfb9412019-11-08 11:23:06 +000075 , m_SendTimelinePacket(m_BufferManager)
Finn Williams032bc742020-02-12 11:02:34 +000076 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +010077 , m_ConnectionAcknowledgedCommandHandler(0,
78 1,
Jim Flynned25e0e2019-10-18 13:21:43 +010079 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +010080 m_CounterDirectory,
81 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +000082 m_SendTimelinePacket,
Matteo Martincigh54fb9572019-10-02 12:50:57 +010083 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010084 , m_RequestCounterDirectoryCommandHandler(0,
85 3,
Jim Flynned25e0e2019-10-18 13:21:43 +010086 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +010087 m_CounterDirectory,
88 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +000089 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +010090 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010091 , m_PeriodicCounterSelectionCommandHandler(0,
92 4,
Jim Flynned25e0e2019-10-18 13:21:43 +010093 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Finn Williams032bc742020-02-12 11:02:34 +000094 m_BackendProfilingContexts,
95 m_CounterIdMap,
Matteo Martincighe8485382019-10-10 14:08:21 +010096 m_Holder,
Finn Williams032bc742020-02-12 11:02:34 +000097 MAX_ARMNN_COUNTER,
Matteo Martincighe8485382019-10-10 14:08:21 +010098 m_PeriodicCounterCapture,
99 *this,
100 m_SendCounterPacket,
101 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100102 , m_PerJobCounterSelectionCommandHandler(0,
103 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100104 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100105 m_StateMachine)
Keith Davis33ed2212020-03-30 10:43:41 +0100106 , m_ActivateTimelineReportingCommandHandler(0,
107 6,
108 m_PacketVersionResolver.ResolvePacketVersion(0, 6)
109 .GetEncodedValue(),
110 m_SendTimelinePacket,
111 m_StateMachine,
112 reportStructure,
113 m_TimelineReporting,
114 *this)
115 , m_DeactivateTimelineReportingCommandHandler(0,
116 7,
117 m_PacketVersionResolver.ResolvePacketVersion(0, 7)
118 .GetEncodedValue(),
119 m_TimelineReporting,
120 m_StateMachine,
121 *this)
Jim Flynn8b200652019-10-24 18:07:44 +0100122 , m_TimelinePacketWriterFactory(m_BufferManager)
David Monahanc1536d62020-02-12 15:52:35 +0000123 , m_MaxGlobalCounterId(armnn::profiling::INFERENCES_RUN)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100124 {
125 // Register the "Connection Acknowledged" command handler
126 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100127
128 // Register the "Request Counter Directory" command handler
129 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100130
131 // Register the "Periodic Counter Selection" command handler
132 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100133
134 // Register the "Per-Job Counter Selection" command handler
135 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Keith Davis33ed2212020-03-30 10:43:41 +0100136
137 m_CommandHandlerRegistry.RegisterFunctor(&m_ActivateTimelineReportingCommandHandler);
138
139 m_CommandHandlerRegistry.RegisterFunctor(&m_DeactivateTimelineReportingCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100140 }
Sadik Armagan3184c902020-03-18 10:57:30 +0000141
janeil01811ca552019-12-03 17:01:32 +0000142 ~ProfilingService();
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100143
Sadik Armagan3184c902020-03-18 10:57:30 +0000144 // Resets the profiling options, optionally clears the profiling service entirely
145 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
146 ProfilingState ConfigureProfilingService(const ExternalProfilingOptions& options,
147 bool resetProfilingService = false);
148
149
150 // Updates the profiling service, making it transition to a new state if necessary
151 void Update();
152
153 // Disconnects the profiling service from the external server
154 void Disconnect();
155
156 // Store a profiling context returned from a backend that support profiling.
157 void AddBackendProfilingContext(const BackendId backendId,
158 std::shared_ptr<armnn::profiling::IBackendProfilingContext> profilingContext);
159
Keith Davis33ed2212020-03-30 10:43:41 +0100160 // Enable the recording of timeline events and entities
161 void NotifyBackendsForTimelineReporting() override;
162
Sadik Armagan3184c902020-03-18 10:57:30 +0000163 const ICounterDirectory& GetCounterDirectory() const;
164 ICounterRegistry& GetCounterRegistry();
165 ProfilingState GetCurrentState() const;
166 bool IsCounterRegistered(uint16_t counterUid) const override;
167 uint32_t GetCounterValue(uint16_t counterUid) const override;
168 uint16_t GetCounterCount() const override;
169 // counter global/backend mapping functions
170 const ICounterMappings& GetCounterMappings() const override;
171 IRegisterCounterMapping& GetCounterMappingRegistry();
172
173 // Getters for the profiling service state
174 bool IsProfilingEnabled() const override;
175
176 CaptureData GetCaptureData() override;
177 void SetCaptureData(uint32_t capturePeriod,
178 const std::vector<uint16_t>& counterIds,
179 const std::set<BackendId>& activeBackends);
180
181 // Setters for the profiling service state
182 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
183 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
184 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
185 uint32_t IncrementCounterValue(uint16_t counterUid) override;
186
187 // IProfilingGuidGenerator functions
188 /// Return the next random Guid in the sequence
189 ProfilingDynamicGuid NextGuid() override;
190 /// Create a ProfilingStaticGuid based on a hash of the string
191 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
192
193 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override;
194
195 ISendCounterPacket& GetSendCounterPacket() override
196 {
197 return m_SendCounterPacket;
198 }
199
Sadik Armagan3184c902020-03-18 10:57:30 +0000200 static ProfilingDynamicGuid GetNextGuid();
201
202 static ProfilingStaticGuid GetStaticId(const std::string& str);
203
Keith Davis33ed2212020-03-30 10:43:41 +0100204 bool IsTimelineReportingEnabled()
205 {
206 return m_TimelineReporting;
207 }
208
Sadik Armagan3184c902020-03-18 10:57:30 +0000209private:
210 //Copy/move constructors/destructors and copy/move assignment operators are deleted
211 ProfilingService(const ProfilingService&) = delete;
212 ProfilingService(ProfilingService&&) = delete;
213 ProfilingService& operator=(const ProfilingService&) = delete;
214 ProfilingService& operator=(ProfilingService&&) = delete;
215
216 // Initialization/reset functions
217 void Initialize();
218 void InitializeCounterValue(uint16_t counterUid);
219 void Reset();
220 void Stop();
221
222 // Helper function
223 void CheckCounterUid(uint16_t counterUid) const;
224
225 // Profiling service components
Keith Davis33ed2212020-03-30 10:43:41 +0100226 ExternalProfilingOptions m_Options;
227 std::atomic<bool> m_TimelineReporting;
228 CounterDirectory m_CounterDirectory;
229 CounterIdMap m_CounterIdMap;
Sadik Armagan3184c902020-03-18 10:57:30 +0000230 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
Keith Davis33ed2212020-03-30 10:43:41 +0100231 IProfilingConnectionPtr m_ProfilingConnection;
232 ProfilingStateMachine m_StateMachine;
233 CounterIndices m_CounterIndex;
234 CounterValues m_CounterValues;
235 CommandHandlerRegistry m_CommandHandlerRegistry;
236 PacketVersionResolver m_PacketVersionResolver;
237 CommandHandler m_CommandHandler;
238 BufferManager m_BufferManager;
239 SendCounterPacket m_SendCounterPacket;
240 SendThread m_SendThread;
241 SendTimelinePacket m_SendTimelinePacket;
242
Sadik Armagan3184c902020-03-18 10:57:30 +0000243 Holder m_Holder;
Keith Davis33ed2212020-03-30 10:43:41 +0100244
Sadik Armagan3184c902020-03-18 10:57:30 +0000245 PeriodicCounterCapture m_PeriodicCounterCapture;
Keith Davis33ed2212020-03-30 10:43:41 +0100246
247 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
248 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
249 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
250 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
251 ActivateTimelineReportingCommandHandler m_ActivateTimelineReportingCommandHandler;
252 DeactivateTimelineReportingCommandHandler m_DeactivateTimelineReportingCommandHandler;
Sadik Armagan3184c902020-03-18 10:57:30 +0000253
254 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Keith Davis33ed2212020-03-30 10:43:41 +0100255 BackendProfilingContext m_BackendProfilingContexts;
256 uint16_t m_MaxGlobalCounterId;
Sadik Armagan3184c902020-03-18 10:57:30 +0000257
258 static ProfilingGuidGenerator m_GuidGenerator;
259
260protected:
261
Matteo Martincighd0613b52019-10-09 16:47:04 +0100262 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100263 void SwapProfilingConnectionFactory(ProfilingService& instance,
264 IProfilingConnectionFactory* other,
265 IProfilingConnectionFactory*& backup)
266 {
267 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
268 BOOST_ASSERT(other);
269
270 backup = instance.m_ProfilingConnectionFactory.release();
271 instance.m_ProfilingConnectionFactory.reset(other);
272 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100273 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
274 {
275 return instance.m_ProfilingConnection.get();
276 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100277 void TransitionToState(ProfilingService& instance, ProfilingState newState)
278 {
279 instance.m_StateMachine.TransitionToState(newState);
280 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000281 bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100282 {
Sadik Armagan3896b472020-02-10 12:24:15 +0000283 return instance.m_SendThread.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100284 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000285
286 BufferManager& GetBufferManager(ProfilingService& instance)
287 {
288 return instance.m_BufferManager;
289 }
Keith Davis02356de2019-08-26 18:28:17 +0100290};
291
292} // namespace profiling
293
Matteo Martincigha84edee2019-10-02 12:50:57 +0100294} // namespace armnn