blob: f6e409daebba2a5dfc7e16485105e11dde621e49 [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"
Jim Flynn64063552020-02-14 10:18:08 +000015#include "IProfilingService.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010016#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010017#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010018#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010019#include "ProfilingConnectionFactory.hpp"
Jim Flynn00f3aaf2019-10-24 11:58:06 +010020#include "ProfilingGuidGenerator.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010021#include "ProfilingStateMachine.hpp"
22#include "RequestCounterDirectoryCommandHandler.hpp"
23#include "SendCounterPacket.hpp"
Sadik Armagan3896b472020-02-10 12:24:15 +000024#include "SendThread.hpp"
Matteo Martincighcdfb9412019-11-08 11:23:06 +000025#include "SendTimelinePacket.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010026#include "TimelinePacketWriterFactory.hpp"
Colm Donelan1aff3932020-02-05 17:48:59 +000027#include <armnn/backends/profiling/IBackendProfilingContext.hpp>
Keith Davis02356de2019-08-26 18:28:17 +010028
29namespace armnn
30{
31
32namespace profiling
33{
Keith Davise394bd92019-12-02 15:12:19 +000034// Static constants describing ArmNN's counter UID's
35static const uint16_t NETWORK_LOADS = 0;
36static const uint16_t NETWORK_UNLOADS = 1;
37static const uint16_t REGISTERED_BACKENDS = 2;
38static const uint16_t UNREGISTERED_BACKENDS = 3;
39static const uint16_t INFERENCES_RUN = 4;
Finn Williams032bc742020-02-12 11:02:34 +000040static const uint16_t MAX_ARMNN_COUNTER = INFERENCES_RUN;
Keith Davis02356de2019-08-26 18:28:17 +010041
Jim Flynn64063552020-02-14 10:18:08 +000042class ProfilingService : public IReadWriteCounterValues, public IProfilingService
Keith Davis02356de2019-08-26 18:28:17 +010043{
44public:
Narumol Prangnawarat85ad78c2019-11-18 15:34:23 +000045 using ExternalProfilingOptions = IRuntime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010046 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010047 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
48 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
49 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis02356de2019-08-26 18:28:17 +010050
Matteo Martincigh54fb9572019-10-02 12:50:57 +010051 // Default constructor/destructor kept protected for testing
52 ProfilingService()
53 : m_Options()
54 , m_CounterDirectory()
55 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
56 , m_ProfilingConnection()
57 , m_StateMachine()
58 , m_CounterIndex()
59 , m_CounterValues()
60 , m_CommandHandlerRegistry()
61 , m_PacketVersionResolver()
62 , m_CommandHandler(1000,
63 false,
64 m_CommandHandlerRegistry,
65 m_PacketVersionResolver)
66 , m_BufferManager()
Sadik Armagan3896b472020-02-10 12:24:15 +000067 , m_SendCounterPacket(m_BufferManager)
68 , m_SendThread(m_StateMachine, m_BufferManager, m_SendCounterPacket)
Matteo Martincighcdfb9412019-11-08 11:23:06 +000069 , m_SendTimelinePacket(m_BufferManager)
Finn Williams032bc742020-02-12 11:02:34 +000070 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this, m_CounterIdMap, m_BackendProfilingContexts)
Jim Flynn397043f2019-10-17 17:37:10 +010071 , m_ConnectionAcknowledgedCommandHandler(0,
72 1,
Jim Flynned25e0e2019-10-18 13:21:43 +010073 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +010074 m_CounterDirectory,
75 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +000076 m_SendTimelinePacket,
Matteo Martincigh54fb9572019-10-02 12:50:57 +010077 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010078 , m_RequestCounterDirectoryCommandHandler(0,
79 3,
Jim Flynned25e0e2019-10-18 13:21:43 +010080 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +010081 m_CounterDirectory,
82 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +000083 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +010084 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010085 , m_PeriodicCounterSelectionCommandHandler(0,
86 4,
Jim Flynned25e0e2019-10-18 13:21:43 +010087 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Finn Williams032bc742020-02-12 11:02:34 +000088 m_BackendProfilingContexts,
89 m_CounterIdMap,
Matteo Martincighe8485382019-10-10 14:08:21 +010090 m_Holder,
Finn Williams032bc742020-02-12 11:02:34 +000091 MAX_ARMNN_COUNTER,
Matteo Martincighe8485382019-10-10 14:08:21 +010092 m_PeriodicCounterCapture,
93 *this,
94 m_SendCounterPacket,
95 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +010096 , m_PerJobCounterSelectionCommandHandler(0,
97 5,
Jim Flynned25e0e2019-10-18 13:21:43 +010098 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +010099 m_StateMachine)
Jim Flynn8b200652019-10-24 18:07:44 +0100100 , m_TimelinePacketWriterFactory(m_BufferManager)
David Monahanc1536d62020-02-12 15:52:35 +0000101 , m_MaxGlobalCounterId(armnn::profiling::INFERENCES_RUN)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100102 {
103 // Register the "Connection Acknowledged" command handler
104 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100105
106 // Register the "Request Counter Directory" command handler
107 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100108
109 // Register the "Periodic Counter Selection" command handler
110 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100111
112 // Register the "Per-Job Counter Selection" command handler
113 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100114 }
Sadik Armagan3184c902020-03-18 10:57:30 +0000115
janeil01811ca552019-12-03 17:01:32 +0000116 ~ProfilingService();
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100117
Sadik Armagan3184c902020-03-18 10:57:30 +0000118 // Resets the profiling options, optionally clears the profiling service entirely
119 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
120 ProfilingState ConfigureProfilingService(const ExternalProfilingOptions& options,
121 bool resetProfilingService = false);
122
123
124 // Updates the profiling service, making it transition to a new state if necessary
125 void Update();
126
127 // Disconnects the profiling service from the external server
128 void Disconnect();
129
130 // Store a profiling context returned from a backend that support profiling.
131 void AddBackendProfilingContext(const BackendId backendId,
132 std::shared_ptr<armnn::profiling::IBackendProfilingContext> profilingContext);
133
134 const ICounterDirectory& GetCounterDirectory() const;
135 ICounterRegistry& GetCounterRegistry();
136 ProfilingState GetCurrentState() const;
137 bool IsCounterRegistered(uint16_t counterUid) const override;
138 uint32_t GetCounterValue(uint16_t counterUid) const override;
139 uint16_t GetCounterCount() const override;
140 // counter global/backend mapping functions
141 const ICounterMappings& GetCounterMappings() const override;
142 IRegisterCounterMapping& GetCounterMappingRegistry();
143
144 // Getters for the profiling service state
145 bool IsProfilingEnabled() const override;
146
147 CaptureData GetCaptureData() override;
148 void SetCaptureData(uint32_t capturePeriod,
149 const std::vector<uint16_t>& counterIds,
150 const std::set<BackendId>& activeBackends);
151
152 // Setters for the profiling service state
153 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
154 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
155 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
156 uint32_t IncrementCounterValue(uint16_t counterUid) override;
157
158 // IProfilingGuidGenerator functions
159 /// Return the next random Guid in the sequence
160 ProfilingDynamicGuid NextGuid() override;
161 /// Create a ProfilingStaticGuid based on a hash of the string
162 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
163
164 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const override;
165
166 ISendCounterPacket& GetSendCounterPacket() override
167 {
168 return m_SendCounterPacket;
169 }
170
171 /// Check if the profiling is enabled
172 bool IsEnabled() { return m_Options.m_EnableProfiling; }
173
174 static ProfilingDynamicGuid GetNextGuid();
175
176 static ProfilingStaticGuid GetStaticId(const std::string& str);
177
178private:
179 //Copy/move constructors/destructors and copy/move assignment operators are deleted
180 ProfilingService(const ProfilingService&) = delete;
181 ProfilingService(ProfilingService&&) = delete;
182 ProfilingService& operator=(const ProfilingService&) = delete;
183 ProfilingService& operator=(ProfilingService&&) = delete;
184
185 // Initialization/reset functions
186 void Initialize();
187 void InitializeCounterValue(uint16_t counterUid);
188 void Reset();
189 void Stop();
190
191 // Helper function
192 void CheckCounterUid(uint16_t counterUid) const;
193
194 // Profiling service components
195 ExternalProfilingOptions m_Options;
196 CounterDirectory m_CounterDirectory;
197 CounterIdMap m_CounterIdMap;
198 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
199 IProfilingConnectionPtr m_ProfilingConnection;
200 ProfilingStateMachine m_StateMachine;
201 CounterIndices m_CounterIndex;
202 CounterValues m_CounterValues;
203 CommandHandlerRegistry m_CommandHandlerRegistry;
204 PacketVersionResolver m_PacketVersionResolver;
205 CommandHandler m_CommandHandler;
206 BufferManager m_BufferManager;
207 SendCounterPacket m_SendCounterPacket;
208 SendThread m_SendThread;
209 SendTimelinePacket m_SendTimelinePacket;
210 Holder m_Holder;
211 PeriodicCounterCapture m_PeriodicCounterCapture;
212 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
213 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
214 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
215 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
216
217 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
218 std::unordered_map<BackendId,
219 std::shared_ptr<armnn::profiling::IBackendProfilingContext>> m_BackendProfilingContexts;
220 uint16_t m_MaxGlobalCounterId;
221
222 static ProfilingGuidGenerator m_GuidGenerator;
223
224protected:
225
Matteo Martincighd0613b52019-10-09 16:47:04 +0100226 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100227 void SwapProfilingConnectionFactory(ProfilingService& instance,
228 IProfilingConnectionFactory* other,
229 IProfilingConnectionFactory*& backup)
230 {
231 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
232 BOOST_ASSERT(other);
233
234 backup = instance.m_ProfilingConnectionFactory.release();
235 instance.m_ProfilingConnectionFactory.reset(other);
236 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100237 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
238 {
239 return instance.m_ProfilingConnection.get();
240 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100241 void TransitionToState(ProfilingService& instance, ProfilingState newState)
242 {
243 instance.m_StateMachine.TransitionToState(newState);
244 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000245 bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100246 {
Sadik Armagan3896b472020-02-10 12:24:15 +0000247 return instance.m_SendThread.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100248 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000249
250 BufferManager& GetBufferManager(ProfilingService& instance)
251 {
252 return instance.m_BufferManager;
253 }
Keith Davis02356de2019-08-26 18:28:17 +0100254};
255
256} // namespace profiling
257
Matteo Martincigha84edee2019-10-02 12:50:57 +0100258} // namespace armnn