blob: 37f0de9f6f1f84e19da18ef0fc3b0acfafcc6cd8 [file] [log] [blame]
Keith Davis02356de2019-08-26 18:28:17 +01001//
Ryan OSheab5540542022-07-06 09:52:52 +01002// Copyright © 2019, 2022-2023 Arm Ltd and Contributors. All rights reserved.
Keith Davis02356de2019-08-26 18:28:17 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "ProfilingService.hpp"
7
Jim Flynn6c9f17d2022-03-10 23:13:01 +00008#include <common/include/Logging.hpp>
Jim Flynn75c14f42022-03-10 22:05:42 +00009#include <common/include/NumericCast.hpp>
Nikhil Raj7dcc6972021-04-30 15:44:24 +010010#include <common/include/ProfilingGuid.hpp>
Sadik Armagana97a0be2020-03-03 10:44:56 +000011#include <common/include/SocketConnectionException.hpp>
Derek Lamberti08446972019-11-26 16:38:31 +000012
Ryan OSheab5540542022-07-06 09:52:52 +010013#if defined(ARMNN_BUILD_BARE_METAL) || defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynne195a042022-04-12 17:19:28 +010014#include <common/include/IgnoreUnused.hpp>
15#endif
16
17
Jan Eilers156113c2020-09-09 19:11:16 +010018#include <fmt/format.h>
Matteo Martincigha84edee2019-10-02 12:50:57 +010019
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000020namespace arm
Keith Davis02356de2019-08-26 18:28:17 +010021{
22
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000023namespace pipe
Keith Davis02356de2019-08-26 18:28:17 +010024{
25
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000026void ProfilingService::ResetExternalProfilingOptions(const arm::pipe::ProfilingOptions& options,
Matteo Martincigha84edee2019-10-02 12:50:57 +010027 bool resetProfilingService)
Keith Davis02356de2019-08-26 18:28:17 +010028{
Ryan OSheab5540542022-07-06 09:52:52 +010029#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Matteo Martincigha84edee2019-10-02 12:50:57 +010030 // Update the profiling options
31 m_Options = options;
Keith Davis33ed2212020-03-30 10:43:41 +010032 m_TimelineReporting = options.m_TimelineEnabled;
Finn Williamsd7fcafa2020-04-23 17:55:18 +010033 m_ConnectionAcknowledgedCommandHandler.setTimelineEnabled(options.m_TimelineEnabled);
Keith Davis02356de2019-08-26 18:28:17 +010034
Matteo Martincigh54fb9572019-10-02 12:50:57 +010035 // Check if the profiling service needs to be reset
Matteo Martincigha84edee2019-10-02 12:50:57 +010036 if (resetProfilingService)
Keith Davis02356de2019-08-26 18:28:17 +010037 {
Matteo Martincigha84edee2019-10-02 12:50:57 +010038 // Reset the profiling service
Matteo Martincigh54fb9572019-10-02 12:50:57 +010039 Reset();
Keith Davis02356de2019-08-26 18:28:17 +010040 }
Jim Flynne195a042022-04-12 17:19:28 +010041#else
42 IgnoreUnused(options);
43 IgnoreUnused(resetProfilingService);
Ryan OSheab5540542022-07-06 09:52:52 +010044#endif // ARMNN_BUILD_BARE_METAL || ARMNN_EXECUTE_NETWORK_STATIC
Keith Davis02356de2019-08-26 18:28:17 +010045}
46
Jim Flynn64063552020-02-14 10:18:08 +000047bool ProfilingService::IsProfilingEnabled() const
Keith Davise394bd92019-12-02 15:12:19 +000048{
Ryan OSheab5540542022-07-06 09:52:52 +010049#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Keith Davise394bd92019-12-02 15:12:19 +000050 return m_Options.m_EnableProfiling;
Jim Flynn870b96c2022-03-25 21:24:56 +000051#else
52 return false;
Ryan OSheab5540542022-07-06 09:52:52 +010053#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Keith Davise394bd92019-12-02 15:12:19 +000054}
55
Jim Flynn672d06e2019-10-15 10:18:11 +010056ProfilingState ProfilingService::ConfigureProfilingService(
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000057 const ProfilingOptions& options,
Jim Flynn672d06e2019-10-15 10:18:11 +010058 bool resetProfilingService)
59{
Ryan OSheab5540542022-07-06 09:52:52 +010060#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn672d06e2019-10-15 10:18:11 +010061 ResetExternalProfilingOptions(options, resetProfilingService);
62 ProfilingState currentState = m_StateMachine.GetCurrentState();
63 if (options.m_EnableProfiling)
64 {
65 switch (currentState)
66 {
67 case ProfilingState::Uninitialised:
68 Update(); // should transition to NotConnected
69 Update(); // will either stay in NotConnected because there is no server
70 // or will enter WaitingForAck.
71 currentState = m_StateMachine.GetCurrentState();
72 if (currentState == ProfilingState::WaitingForAck)
73 {
74 Update(); // poke it again to send out the metadata packet
75 }
76 currentState = m_StateMachine.GetCurrentState();
77 return currentState;
78 case ProfilingState::NotConnected:
79 Update(); // will either stay in NotConnected because there is no server
80 // or will enter WaitingForAck
81 currentState = m_StateMachine.GetCurrentState();
82 if (currentState == ProfilingState::WaitingForAck)
83 {
84 Update(); // poke it again to send out the metadata packet
85 }
86 currentState = m_StateMachine.GetCurrentState();
87 return currentState;
88 default:
89 return currentState;
90 }
91 }
92 else
93 {
94 // Make sure profiling is shutdown
95 switch (currentState)
96 {
97 case ProfilingState::Uninitialised:
98 case ProfilingState::NotConnected:
99 return currentState;
100 default:
101 Stop();
102 return m_StateMachine.GetCurrentState();
103 }
104 }
Jim Flynne195a042022-04-12 17:19:28 +0100105#else
106 IgnoreUnused(options);
107 IgnoreUnused(resetProfilingService);
108 return ProfilingState::Uninitialised;
Ryan OSheab5540542022-07-06 09:52:52 +0100109#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Jim Flynn672d06e2019-10-15 10:18:11 +0100110}
111
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100112void ProfilingService::Update()
Keith Davis02356de2019-08-26 18:28:17 +0100113{
Ryan OSheab5540542022-07-06 09:52:52 +0100114#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100115 if (!m_Options.m_EnableProfiling)
Matteo Martincigha84edee2019-10-02 12:50:57 +0100116 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100117 // Don't run if profiling is disabled
118 return;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100119 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100120
121 ProfilingState currentState = m_StateMachine.GetCurrentState();
122 switch (currentState)
Keith Davis02356de2019-08-26 18:28:17 +0100123 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100124 case ProfilingState::Uninitialised:
janeil01811ca552019-12-03 17:01:32 +0000125
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100126 // Initialize the profiling service
127 Initialize();
128
129 // Move to the next state
130 m_StateMachine.TransitionToState(ProfilingState::NotConnected);
131 break;
132 case ProfilingState::NotConnected:
Matteo Martincighd0613b52019-10-09 16:47:04 +0100133 // Stop the command thread (if running)
134 m_CommandHandler.Stop();
135
136 // Stop the send thread (if running)
Sadik Armagan3896b472020-02-10 12:24:15 +0000137 m_SendThread.Stop(false);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100138
Matteo Martincighe8485382019-10-10 14:08:21 +0100139 // Stop the periodic counter capture thread (if running)
140 m_PeriodicCounterCapture.Stop();
141
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100142 // Reset any existing profiling connection
143 m_ProfilingConnection.reset();
144
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100145 try
Keith Davis02356de2019-08-26 18:28:17 +0100146 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100147 // Setup the profiling connection
Jim Flynn6730fe92022-03-10 22:57:47 +0000148 ARM_PIPE_ASSERT(m_ProfilingConnectionFactory);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100149 m_ProfilingConnection = m_ProfilingConnectionFactory->GetProfilingConnection(m_Options);
Keith Davis02356de2019-08-26 18:28:17 +0100150 }
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000151 catch (const arm::pipe::ProfilingException& e)
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100152 {
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000153 ARM_PIPE_LOG(warning) << "An error has occurred when creating the profiling connection: "
Derek Lamberti08446972019-11-26 16:38:31 +0000154 << e.what();
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100155 }
Jim Flynnbbfe6032020-07-20 16:57:44 +0100156 catch (const arm::pipe::SocketConnectionException& e)
Sadik Armagana97a0be2020-03-03 10:44:56 +0000157 {
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000158 ARM_PIPE_LOG(warning) << "An error has occurred when creating the profiling connection ["
Sadik Armagana97a0be2020-03-03 10:44:56 +0000159 << e.what() << "] on socket [" << e.GetSocketFd() << "].";
160 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100161
162 // Move to the next state
163 m_StateMachine.TransitionToState(m_ProfilingConnection
164 ? ProfilingState::WaitingForAck // Profiling connection obtained, wait for ack
165 : ProfilingState::NotConnected); // Profiling connection failed, stay in the
166 // "NotConnected" state
167 break;
168 case ProfilingState::WaitingForAck:
Jim Flynn6730fe92022-03-10 22:57:47 +0000169 ARM_PIPE_ASSERT(m_ProfilingConnection);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100170
171 // Start the command thread
172 m_CommandHandler.Start(*m_ProfilingConnection);
173
174 // Start the send thread, while in "WaitingForAck" state it'll send out a "Stream MetaData" packet waiting for
175 // a valid "Connection Acknowledged" packet confirming the connection
Sadik Armagan3896b472020-02-10 12:24:15 +0000176 m_SendThread.Start(*m_ProfilingConnection);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100177
178 // The connection acknowledged command handler will automatically transition the state to "Active" once a
179 // valid "Connection Acknowledged" packet has been received
180
181 break;
182 case ProfilingState::Active:
183
Matteo Martincighe8485382019-10-10 14:08:21 +0100184 // The period counter capture thread is started by the Periodic Counter Selection command handler upon
185 // request by an external profiling service
186
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100187 break;
188 default:
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000189 throw arm::pipe::ProfilingException(fmt::format("Unknown profiling service state: {}",
190 static_cast<int>(currentState)));
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100191 }
Ryan OSheab5540542022-07-06 09:52:52 +0100192#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Keith Davis02356de2019-08-26 18:28:17 +0100193}
194
Jim Flynn53e46992019-10-14 12:31:10 +0100195void ProfilingService::Disconnect()
196{
Ryan OSheab5540542022-07-06 09:52:52 +0100197#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn53e46992019-10-14 12:31:10 +0100198 ProfilingState currentState = m_StateMachine.GetCurrentState();
199 switch (currentState)
200 {
201 case ProfilingState::Uninitialised:
202 case ProfilingState::NotConnected:
203 case ProfilingState::WaitingForAck:
204 return; // NOP
205 case ProfilingState::Active:
206 // Stop the command thread (if running)
207 Stop();
208
209 break;
210 default:
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000211 throw arm::pipe::ProfilingException(fmt::format("Unknown profiling service state: {}",
212 static_cast<int>(currentState)));
Jim Flynn53e46992019-10-14 12:31:10 +0100213 }
Ryan OSheab5540542022-07-06 09:52:52 +0100214#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Jim Flynn53e46992019-10-14 12:31:10 +0100215}
216
David Monahanc1536d62020-02-12 15:52:35 +0000217// Store a profiling context returned from a backend that support profiling, and register its counters
Jim Flynn870b96c2022-03-25 21:24:56 +0000218void ProfilingService::AddBackendProfilingContext(
219 const std::string& backendId,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000220 std::shared_ptr<IBackendProfilingContext> profilingContext)
David Monahanc1536d62020-02-12 15:52:35 +0000221{
Ryan OSheab5540542022-07-06 09:52:52 +0100222#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn6730fe92022-03-10 22:57:47 +0000223 ARM_PIPE_ASSERT(profilingContext != nullptr);
David Monahanc1536d62020-02-12 15:52:35 +0000224 // Register the backend counters
225 m_MaxGlobalCounterId = profilingContext->RegisterCounters(m_MaxGlobalCounterId);
226 m_BackendProfilingContexts.emplace(backendId, std::move(profilingContext));
Jim Flynne195a042022-04-12 17:19:28 +0100227#else
228 IgnoreUnused(backendId);
229 IgnoreUnused(profilingContext);
Ryan OSheab5540542022-07-06 09:52:52 +0100230#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
David Monahanc1536d62020-02-12 15:52:35 +0000231}
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100232const ICounterDirectory& ProfilingService::GetCounterDirectory() const
233{
234 return m_CounterDirectory;
235}
236
Jim Flynn97897022020-02-02 12:52:59 +0000237ICounterRegistry& ProfilingService::GetCounterRegistry()
238{
239 return m_CounterDirectory;
240}
241
Matteo Martincigha84edee2019-10-02 12:50:57 +0100242ProfilingState ProfilingService::GetCurrentState() const
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100243{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100244 return m_StateMachine.GetCurrentState();
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100245}
246
247uint16_t ProfilingService::GetCounterCount() const
248{
249 return m_CounterDirectory.GetCounterCount();
250}
251
Matteo Martincighe8485382019-10-10 14:08:21 +0100252bool ProfilingService::IsCounterRegistered(uint16_t counterUid) const
253{
Finn Williamsb205a332020-05-13 15:04:25 +0100254 return m_CounterDirectory.IsCounterRegistered(counterUid);
Matteo Martincighe8485382019-10-10 14:08:21 +0100255}
256
Finn Williamsf3fcf322020-05-11 14:38:02 +0100257uint32_t ProfilingService::GetAbsoluteCounterValue(uint16_t counterUid) const
Keith Davis02356de2019-08-26 18:28:17 +0100258{
Matteo Martincighe8485382019-10-10 14:08:21 +0100259 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100260 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000261 ARM_PIPE_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100262 return counterValuePtr->load(std::memory_order::memory_order_relaxed);
Keith Davis02356de2019-08-26 18:28:17 +0100263}
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100264
Finn Williamsf3fcf322020-05-11 14:38:02 +0100265uint32_t ProfilingService::GetDeltaCounterValue(uint16_t counterUid)
266{
267 CheckCounterUid(counterUid);
268 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000269 ARM_PIPE_ASSERT(counterValuePtr);
Finn Williamsf3fcf322020-05-11 14:38:02 +0100270 const uint32_t counterValue = counterValuePtr->load(std::memory_order::memory_order_relaxed);
271 SubtractCounterValue(counterUid, counterValue);
272 return counterValue;
273}
274
Jim Flynn8e0c7a62020-01-30 14:10:55 +0000275const ICounterMappings& ProfilingService::GetCounterMappings() const
276{
277 return m_CounterIdMap;
278}
279
Jim Flynn97897022020-02-02 12:52:59 +0000280IRegisterCounterMapping& ProfilingService::GetCounterMappingRegistry()
Jim Flynn8e0c7a62020-01-30 14:10:55 +0000281{
282 return m_CounterIdMap;
283}
284
Jim Flynn34430252022-03-04 15:03:58 +0000285bool ProfilingService::IsCategoryRegistered(const std::string& categoryName) const
286{
287 return m_CounterDirectory.IsCategoryRegistered(categoryName);
288}
289
290bool ProfilingService::IsCounterRegistered(const std::string& counterName) const
291{
292 return m_CounterDirectory.IsCounterRegistered(counterName);
293}
294
James Conroy2dcd3fe2020-02-06 18:34:52 +0000295CaptureData ProfilingService::GetCaptureData()
296{
297 return m_Holder.GetCaptureData();
298}
299
Finn Williams032bc742020-02-12 11:02:34 +0000300void ProfilingService::SetCaptureData(uint32_t capturePeriod,
301 const std::vector<uint16_t>& counterIds,
Cathal Corbett6f073722022-03-04 12:11:09 +0000302 const std::set<std::string>& activeBackends)
James Conroy2dcd3fe2020-02-06 18:34:52 +0000303{
Finn Williams032bc742020-02-12 11:02:34 +0000304 m_Holder.SetCaptureData(capturePeriod, counterIds, activeBackends);
James Conroy2dcd3fe2020-02-06 18:34:52 +0000305}
306
Matteo Martincigha84edee2019-10-02 12:50:57 +0100307void ProfilingService::SetCounterValue(uint16_t counterUid, uint32_t value)
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100308{
Matteo Martincighe8485382019-10-10 14:08:21 +0100309 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100310 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000311 ARM_PIPE_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100312 counterValuePtr->store(value, std::memory_order::memory_order_relaxed);
313}
314
315uint32_t ProfilingService::AddCounterValue(uint16_t counterUid, uint32_t value)
316{
Matteo Martincighe8485382019-10-10 14:08:21 +0100317 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100318 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000319 ARM_PIPE_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100320 return counterValuePtr->fetch_add(value, std::memory_order::memory_order_relaxed);
321}
322
323uint32_t ProfilingService::SubtractCounterValue(uint16_t counterUid, uint32_t value)
324{
Matteo Martincighe8485382019-10-10 14:08:21 +0100325 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100326 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000327 ARM_PIPE_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100328 return counterValuePtr->fetch_sub(value, std::memory_order::memory_order_relaxed);
329}
330
331uint32_t ProfilingService::IncrementCounterValue(uint16_t counterUid)
332{
Matteo Martincighe8485382019-10-10 14:08:21 +0100333 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100334 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000335 ARM_PIPE_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100336 return counterValuePtr->operator++(std::memory_order::memory_order_relaxed);
337}
338
Jim Flynn8b200652019-10-24 18:07:44 +0100339std::unique_ptr<ISendTimelinePacket> ProfilingService::GetSendTimelinePacket() const
340{
341 return m_TimelinePacketWriterFactory.GetSendTimelinePacket();
342}
343
Matteo Martincigha84edee2019-10-02 12:50:57 +0100344void ProfilingService::Initialize()
345{
Ryan OSheab5540542022-07-06 09:52:52 +0100346#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn34430252022-03-04 15:03:58 +0000347 m_Initialiser.InitialiseProfilingService(*this);
Ryan OSheab5540542022-07-06 09:52:52 +0100348#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100349}
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100350
Matteo Martincigha84edee2019-10-02 12:50:57 +0100351void ProfilingService::InitializeCounterValue(uint16_t counterUid)
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100352{
Ryan OSheab5540542022-07-06 09:52:52 +0100353#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Matteo Martincigha84edee2019-10-02 12:50:57 +0100354 // Increase the size of the counter index if necessary
355 if (counterUid >= m_CounterIndex.size())
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100356 {
Jim Flynn75c14f42022-03-10 22:05:42 +0000357 m_CounterIndex.resize(arm::pipe::numeric_cast<size_t>(counterUid) + 1);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100358 }
Matteo Martincigha84edee2019-10-02 12:50:57 +0100359
360 // Create a new atomic counter and add it to the list
361 m_CounterValues.emplace_back(0);
362
363 // Register the new counter to the counter index for quick access
364 std::atomic<uint32_t>* counterValuePtr = &(m_CounterValues.back());
365 m_CounterIndex.at(counterUid) = counterValuePtr;
Jim Flynne195a042022-04-12 17:19:28 +0100366#else
367 IgnoreUnused(counterUid);
Ryan OSheab5540542022-07-06 09:52:52 +0100368#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100369}
370
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100371void ProfilingService::Reset()
372{
Ryan OSheab5540542022-07-06 09:52:52 +0100373#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100374 // Stop the profiling service...
Jim Flynn53e46992019-10-14 12:31:10 +0100375 Stop();
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100376
Jim Flynn53e46992019-10-14 12:31:10 +0100377 // ...then delete all the counter data and configuration...
378 m_CounterIndex.clear();
379 m_CounterValues.clear();
380 m_CounterDirectory.Clear();
Jim Flynn97897022020-02-02 12:52:59 +0000381 m_CounterIdMap.Reset();
Finn Williams09ad6f92019-12-19 17:05:18 +0000382 m_BufferManager.Reset();
Matteo Martincighd0613b52019-10-09 16:47:04 +0100383
Jim Flynn53e46992019-10-14 12:31:10 +0100384 // ...finally reset the profiling state machine
385 m_StateMachine.Reset();
Colm Donelan1aff3932020-02-05 17:48:59 +0000386 m_BackendProfilingContexts.clear();
Ryan OSheab5540542022-07-06 09:52:52 +0100387#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Jim Flynn53e46992019-10-14 12:31:10 +0100388}
389
390void ProfilingService::Stop()
391{
Ryan OSheab5540542022-07-06 09:52:52 +0100392#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn6398a982020-05-27 17:05:21 +0100393 { // only lock when we are updating the inference completed variable
394 std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
395 m_ServiceActive = false;
396 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100397 // The order in which we reset/stop the components is not trivial!
Finn Williams09ad6f92019-12-19 17:05:18 +0000398 // First stop the producing threads
399 // Command Handler first as it is responsible for launching then Periodic Counter capture thread
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100400 m_CommandHandler.Stop();
Matteo Martincighe8485382019-10-10 14:08:21 +0100401 m_PeriodicCounterCapture.Stop();
Finn Williams09ad6f92019-12-19 17:05:18 +0000402 // The the consuming thread
Sadik Armagan3896b472020-02-10 12:24:15 +0000403 m_SendThread.Stop(false);
Matteo Martincighd0613b52019-10-09 16:47:04 +0100404
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100405 // ...then close and destroy the profiling connection...
Jim Flynn53e46992019-10-14 12:31:10 +0100406 if (m_ProfilingConnection != nullptr && m_ProfilingConnection->IsOpen())
407 {
408 m_ProfilingConnection->Close();
409 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100410 m_ProfilingConnection.reset();
411
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100412 // ...then move to the "NotConnected" state
Jim Flynn53e46992019-10-14 12:31:10 +0100413 m_StateMachine.TransitionToState(ProfilingState::NotConnected);
Ryan OSheab5540542022-07-06 09:52:52 +0100414#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100415}
416
Matteo Martincighe8485382019-10-10 14:08:21 +0100417inline void ProfilingService::CheckCounterUid(uint16_t counterUid) const
418{
Ryan OSheab5540542022-07-06 09:52:52 +0100419#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Matteo Martincighe8485382019-10-10 14:08:21 +0100420 if (!IsCounterRegistered(counterUid))
421 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000422 throw arm::pipe::InvalidArgumentException(fmt::format("Counter UID {} is not registered", counterUid));
Matteo Martincighe8485382019-10-10 14:08:21 +0100423 }
Jim Flynne195a042022-04-12 17:19:28 +0100424#else
425 IgnoreUnused(counterUid);
Ryan OSheab5540542022-07-06 09:52:52 +0100426#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Matteo Martincighe8485382019-10-10 14:08:21 +0100427}
428
Keith Davis33ed2212020-03-30 10:43:41 +0100429void ProfilingService::NotifyBackendsForTimelineReporting()
430{
Ryan OSheab5540542022-07-06 09:52:52 +0100431#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Keith Davis33ed2212020-03-30 10:43:41 +0100432 BackendProfilingContext::iterator it = m_BackendProfilingContexts.begin();
433 while (it != m_BackendProfilingContexts.end())
434 {
435 auto& backendProfilingContext = it->second;
436 backendProfilingContext->EnableTimelineReporting(m_TimelineReporting);
437 // Increment the Iterator to point to next entry
438 it++;
439 }
Ryan OSheab5540542022-07-06 09:52:52 +0100440#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Keith Davis33ed2212020-03-30 10:43:41 +0100441}
442
Jim Flynn6398a982020-05-27 17:05:21 +0100443void ProfilingService::NotifyProfilingServiceActive()
444{
Ryan OSheab5540542022-07-06 09:52:52 +0100445#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn6398a982020-05-27 17:05:21 +0100446 { // only lock when we are updating the inference completed variable
447 std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
448 m_ServiceActive = true;
449 }
450 m_ServiceActiveConditionVariable.notify_one();
Ryan OSheab5540542022-07-06 09:52:52 +0100451#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Jim Flynn6398a982020-05-27 17:05:21 +0100452}
453
454void ProfilingService::WaitForProfilingServiceActivation(unsigned int timeout)
455{
Ryan OSheab5540542022-07-06 09:52:52 +0100456#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
Jim Flynn6398a982020-05-27 17:05:21 +0100457 std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
458
459 auto start = std::chrono::high_resolution_clock::now();
460 // Here we we will go back to sleep after a spurious wake up if
461 // m_InferenceCompleted is not yet true.
462 if (!m_ServiceActiveConditionVariable.wait_for(lck,
463 std::chrono::milliseconds(timeout),
464 [&]{return m_ServiceActive == true;}))
465 {
466 if (m_ServiceActive == true)
467 {
468 return;
469 }
470 auto finish = std::chrono::high_resolution_clock::now();
471 std::chrono::duration<double, std::milli> elapsed = finish - start;
472 std::stringstream ss;
473 ss << "Timed out waiting on profiling service activation for " << elapsed.count() << " ms";
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000474 ARM_PIPE_LOG(warning) << ss.str();
Jim Flynn6398a982020-05-27 17:05:21 +0100475 }
Jim Flynne195a042022-04-12 17:19:28 +0100476#else
477 IgnoreUnused(timeout);
Ryan OSheab5540542022-07-06 09:52:52 +0100478#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
Jim Flynn6398a982020-05-27 17:05:21 +0100479}
480
janeil01811ca552019-12-03 17:01:32 +0000481ProfilingService::~ProfilingService()
482{
Ryan OSheab5540542022-07-06 09:52:52 +0100483#if !defined(ARMNN_BUILD_BARE_METAL) && !defined(ARMNN_EXECUTE_NETWORK_STATIC)
janeil01811ca552019-12-03 17:01:32 +0000484 Stop();
Ryan OSheab5540542022-07-06 09:52:52 +0100485#endif // ARMNN_BUILD_BARE_METAL && ARMNN_EXECUTE_NETWORK_STATIC
janeil01811ca552019-12-03 17:01:32 +0000486}
Jim Flynn870b96c2022-03-25 21:24:56 +0000487
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000488} // namespace pipe
Keith Davis02356de2019-08-26 18:28:17 +0100489
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000490} // namespace arm