blob: 9cf7545205229c0904a7cbbbd4f11d0d63797d30 [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"
Matteo Martincighe0e6efc2019-10-04 17:17:42 +010013#include "ICounterValues.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010014#include "PeriodicCounterCapture.hpp"
Matteo Martincighe8485382019-10-10 14:08:21 +010015#include "PeriodicCounterSelectionCommandHandler.hpp"
Matteo Martincigh994b5342019-10-11 17:19:56 +010016#include "PerJobCounterSelectionCommandHandler.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010017#include "ProfilingConnectionFactory.hpp"
Jim Flynn00f3aaf2019-10-24 11:58:06 +010018#include "ProfilingGuidGenerator.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010019#include "ProfilingStateMachine.hpp"
20#include "RequestCounterDirectoryCommandHandler.hpp"
21#include "SendCounterPacket.hpp"
Matteo Martincighcdfb9412019-11-08 11:23:06 +000022#include "SendTimelinePacket.hpp"
Jim Flynn8b200652019-10-24 18:07:44 +010023#include "TimelinePacketWriterFactory.hpp"
Keith Davis02356de2019-08-26 18:28:17 +010024
25namespace armnn
26{
27
28namespace profiling
29{
Keith Davise394bd92019-12-02 15:12:19 +000030// Static constants describing ArmNN's counter UID's
31static const uint16_t NETWORK_LOADS = 0;
32static const uint16_t NETWORK_UNLOADS = 1;
33static const uint16_t REGISTERED_BACKENDS = 2;
34static const uint16_t UNREGISTERED_BACKENDS = 3;
35static const uint16_t INFERENCES_RUN = 4;
Keith Davis02356de2019-08-26 18:28:17 +010036
Jim Flynn00f3aaf2019-10-24 11:58:06 +010037class ProfilingService : public IReadWriteCounterValues, public IProfilingGuidGenerator
Keith Davis02356de2019-08-26 18:28:17 +010038{
39public:
Narumol Prangnawarat85ad78c2019-11-18 15:34:23 +000040 using ExternalProfilingOptions = IRuntime::CreationOptions::ExternalProfilingOptions;
Matteo Martincigh54fb9572019-10-02 12:50:57 +010041 using IProfilingConnectionFactoryPtr = std::unique_ptr<IProfilingConnectionFactory>;
Matteo Martincigha84edee2019-10-02 12:50:57 +010042 using IProfilingConnectionPtr = std::unique_ptr<IProfilingConnection>;
43 using CounterIndices = std::vector<std::atomic<uint32_t>*>;
44 using CounterValues = std::list<std::atomic<uint32_t>>;
Keith Davis02356de2019-08-26 18:28:17 +010045
Matteo Martincigha84edee2019-10-02 12:50:57 +010046 // Getter for the singleton instance
47 static ProfilingService& Instance()
48 {
49 static ProfilingService instance;
50 return instance;
51 }
52
53 // Resets the profiling options, optionally clears the profiling service entirely
54 void ResetExternalProfilingOptions(const ExternalProfilingOptions& options, bool resetProfilingService = false);
Jim Flynn672d06e2019-10-15 10:18:11 +010055 ProfilingState ConfigureProfilingService(const ExternalProfilingOptions& options,
56 bool resetProfilingService = false);
57
Matteo Martincigha84edee2019-10-02 12:50:57 +010058
Matteo Martincigh54fb9572019-10-02 12:50:57 +010059 // Updates the profiling service, making it transition to a new state if necessary
60 void Update();
Keith Davis02356de2019-08-26 18:28:17 +010061
Jim Flynn53e46992019-10-14 12:31:10 +010062 // Disconnects the profiling service from the external server
63 void Disconnect();
64
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010065 const ICounterDirectory& GetCounterDirectory() const;
Keith Davis02356de2019-08-26 18:28:17 +010066 ProfilingState GetCurrentState() const;
Matteo Martincighe8485382019-10-10 14:08:21 +010067 bool IsCounterRegistered(uint16_t counterUid) const override;
Matteo Martincigha84edee2019-10-02 12:50:57 +010068 uint32_t GetCounterValue(uint16_t counterUid) const override;
Keith Davise394bd92019-12-02 15:12:19 +000069 uint16_t GetCounterCount() const override;
Jim Flynn8e0c7a62020-01-30 14:10:55 +000070 // counter global/backend mapping functions
71 const ICounterMappings& GetCounterMappings() const;
72 IRegisterCounterMapping& GetCounterMappingRegistrar();
73
74 // Getters for the profiling service state
Keith Davise394bd92019-12-02 15:12:19 +000075 bool IsProfilingEnabled();
Keith Davis02356de2019-08-26 18:28:17 +010076
Matteo Martincigha84edee2019-10-02 12:50:57 +010077 // Setters for the profiling service state
78 void SetCounterValue(uint16_t counterUid, uint32_t value) override;
79 uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override;
80 uint32_t SubtractCounterValue(uint16_t counterUid, uint32_t value) override;
81 uint32_t IncrementCounterValue(uint16_t counterUid) override;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +010082
Jim Flynn00f3aaf2019-10-24 11:58:06 +010083 // IProfilingGuidGenerator functions
84 /// Return the next random Guid in the sequence
85 ProfilingDynamicGuid NextGuid() override;
86 /// Create a ProfilingStaticGuid based on a hash of the string
87 ProfilingStaticGuid GenerateStaticId(const std::string& str) override;
88
Jim Flynn8b200652019-10-24 18:07:44 +010089 std::unique_ptr<ISendTimelinePacket> GetSendTimelinePacket() const;
90
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +000091 /// Check if the profiling is enabled
92 bool IsEnabled() { return m_Options.m_EnableProfiling; }
93
Keith Davis02356de2019-08-26 18:28:17 +010094private:
Matteo Martincigh54fb9572019-10-02 12:50:57 +010095 // Copy/move constructors/destructors and copy/move assignment operators are deleted
Matteo Martincigha84edee2019-10-02 12:50:57 +010096 ProfilingService(const ProfilingService&) = delete;
97 ProfilingService(ProfilingService&&) = delete;
98 ProfilingService& operator=(const ProfilingService&) = delete;
99 ProfilingService& operator=(ProfilingService&&) = delete;
Keith Davis02356de2019-08-26 18:28:17 +0100100
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100101 // Initialization/reset functions
Matteo Martincigha84edee2019-10-02 12:50:57 +0100102 void Initialize();
103 void InitializeCounterValue(uint16_t counterUid);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100104 void Reset();
Jim Flynn53e46992019-10-14 12:31:10 +0100105 void Stop();
Matteo Martincigha84edee2019-10-02 12:50:57 +0100106
Matteo Martincighe8485382019-10-10 14:08:21 +0100107 // Helper function
108 void CheckCounterUid(uint16_t counterUid) const;
109
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100110 // Profiling service components
Matteo Martincigha84edee2019-10-02 12:50:57 +0100111 ExternalProfilingOptions m_Options;
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100112 CounterDirectory m_CounterDirectory;
Jim Flynn8e0c7a62020-01-30 14:10:55 +0000113 CounterIdMap m_CounterIdMap;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100114 IProfilingConnectionFactoryPtr m_ProfilingConnectionFactory;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100115 IProfilingConnectionPtr m_ProfilingConnection;
116 ProfilingStateMachine m_StateMachine;
117 CounterIndices m_CounterIndex;
118 CounterValues m_CounterValues;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100119 CommandHandlerRegistry m_CommandHandlerRegistry;
120 PacketVersionResolver m_PacketVersionResolver;
121 CommandHandler m_CommandHandler;
122 BufferManager m_BufferManager;
123 SendCounterPacket m_SendCounterPacket;
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000124 SendTimelinePacket m_SendTimelinePacket;
Matteo Martincighe8485382019-10-10 14:08:21 +0100125 Holder m_Holder;
126 PeriodicCounterCapture m_PeriodicCounterCapture;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100127 ConnectionAcknowledgedCommandHandler m_ConnectionAcknowledgedCommandHandler;
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100128 RequestCounterDirectoryCommandHandler m_RequestCounterDirectoryCommandHandler;
Matteo Martincighe8485382019-10-10 14:08:21 +0100129 PeriodicCounterSelectionCommandHandler m_PeriodicCounterSelectionCommandHandler;
Matteo Martincigh994b5342019-10-11 17:19:56 +0100130 PerJobCounterSelectionCommandHandler m_PerJobCounterSelectionCommandHandler;
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100131 ProfilingGuidGenerator m_GuidGenerator;
Jim Flynn8b200652019-10-24 18:07:44 +0100132 TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100133
134protected:
135 // Default constructor/destructor kept protected for testing
136 ProfilingService()
137 : m_Options()
138 , m_CounterDirectory()
139 , m_ProfilingConnectionFactory(new ProfilingConnectionFactory())
140 , m_ProfilingConnection()
141 , m_StateMachine()
142 , m_CounterIndex()
143 , m_CounterValues()
144 , m_CommandHandlerRegistry()
145 , m_PacketVersionResolver()
146 , m_CommandHandler(1000,
147 false,
148 m_CommandHandlerRegistry,
149 m_PacketVersionResolver)
150 , m_BufferManager()
151 , m_SendCounterPacket(m_StateMachine, m_BufferManager)
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000152 , m_SendTimelinePacket(m_BufferManager)
Matteo Martincighe8485382019-10-10 14:08:21 +0100153 , m_PeriodicCounterCapture(m_Holder, m_SendCounterPacket, *this)
Jim Flynn397043f2019-10-17 17:37:10 +0100154 , m_ConnectionAcknowledgedCommandHandler(0,
155 1,
Jim Flynned25e0e2019-10-18 13:21:43 +0100156 m_PacketVersionResolver.ResolvePacketVersion(0, 1).GetEncodedValue(),
Keith Davis3201eea2019-10-24 17:30:41 +0100157 m_CounterDirectory,
158 m_SendCounterPacket,
Matteo Martincighcdfb9412019-11-08 11:23:06 +0000159 m_SendTimelinePacket,
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100160 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100161 , m_RequestCounterDirectoryCommandHandler(0,
162 3,
Jim Flynned25e0e2019-10-18 13:21:43 +0100163 m_PacketVersionResolver.ResolvePacketVersion(0, 3).GetEncodedValue(),
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100164 m_CounterDirectory,
165 m_SendCounterPacket,
Matteo Martincigh9723d022019-11-13 10:56:41 +0000166 m_SendTimelinePacket,
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100167 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100168 , m_PeriodicCounterSelectionCommandHandler(0,
169 4,
Jim Flynned25e0e2019-10-18 13:21:43 +0100170 m_PacketVersionResolver.ResolvePacketVersion(0, 4).GetEncodedValue(),
Matteo Martincighe8485382019-10-10 14:08:21 +0100171 m_Holder,
172 m_PeriodicCounterCapture,
173 *this,
174 m_SendCounterPacket,
175 m_StateMachine)
Jim Flynn397043f2019-10-17 17:37:10 +0100176 , m_PerJobCounterSelectionCommandHandler(0,
177 5,
Jim Flynned25e0e2019-10-18 13:21:43 +0100178 m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(),
Matteo Martincigh994b5342019-10-11 17:19:56 +0100179 m_StateMachine)
Jim Flynn8b200652019-10-24 18:07:44 +0100180 , m_TimelinePacketWriterFactory(m_BufferManager)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100181 {
182 // Register the "Connection Acknowledged" command handler
183 m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler);
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100184
185 // Register the "Request Counter Directory" command handler
186 m_CommandHandlerRegistry.RegisterFunctor(&m_RequestCounterDirectoryCommandHandler);
Matteo Martincighe8485382019-10-10 14:08:21 +0100187
188 // Register the "Periodic Counter Selection" command handler
189 m_CommandHandlerRegistry.RegisterFunctor(&m_PeriodicCounterSelectionCommandHandler);
Matteo Martincigh994b5342019-10-11 17:19:56 +0100190
191 // Register the "Per-Job Counter Selection" command handler
192 m_CommandHandlerRegistry.RegisterFunctor(&m_PerJobCounterSelectionCommandHandler);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100193 }
janeil01811ca552019-12-03 17:01:32 +0000194 ~ProfilingService();
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100195
Matteo Martincighd0613b52019-10-09 16:47:04 +0100196 // Protected methods for testing
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100197 void SwapProfilingConnectionFactory(ProfilingService& instance,
198 IProfilingConnectionFactory* other,
199 IProfilingConnectionFactory*& backup)
200 {
201 BOOST_ASSERT(instance.m_ProfilingConnectionFactory);
202 BOOST_ASSERT(other);
203
204 backup = instance.m_ProfilingConnectionFactory.release();
205 instance.m_ProfilingConnectionFactory.reset(other);
206 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100207 IProfilingConnection* GetProfilingConnection(ProfilingService& instance)
208 {
209 return instance.m_ProfilingConnection.get();
210 }
Matteo Martincigh8efc5002019-10-10 14:30:29 +0100211 void TransitionToState(ProfilingService& instance, ProfilingState newState)
212 {
213 instance.m_StateMachine.TransitionToState(newState);
214 }
Finn Williams09ad6f92019-12-19 17:05:18 +0000215 bool WaitForPacketSent(ProfilingService& instance, uint32_t timeout = 1000)
Matteo Martincighe8485382019-10-10 14:08:21 +0100216 {
Colm Donelan2ba48d22019-11-29 09:10:59 +0000217 return instance.m_SendCounterPacket.WaitForPacketSent(timeout);
Matteo Martincighe8485382019-10-10 14:08:21 +0100218 }
Narumol Prangnawaratdf31cfe2019-11-22 11:26:06 +0000219
220 BufferManager& GetBufferManager(ProfilingService& instance)
221 {
222 return instance.m_BufferManager;
223 }
Keith Davis02356de2019-08-26 18:28:17 +0100224};
225
226} // namespace profiling
227
Matteo Martincigha84edee2019-10-02 12:50:57 +0100228} // namespace armnn