blob: 6fe52f845ea6ef5aa7a919c08fca59e22fadf0fc [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#include "ProfilingService.hpp"
7
Keith Davise394bd92019-12-02 15:12:19 +00008#include <armnn/BackendId.hpp>
Derek Lamberti08446972019-11-26 16:38:31 +00009#include <armnn/Logging.hpp>
Matthew Sloyan371b70e2020-09-11 10:14:57 +010010#include <armnn/utility/NumericCast.hpp>
11
Sadik Armagana97a0be2020-03-03 10:44:56 +000012#include <common/include/SocketConnectionException.hpp>
Derek Lamberti08446972019-11-26 16:38:31 +000013
Jan Eilers156113c2020-09-09 19:11:16 +010014#include <fmt/format.h>
Matteo Martincigha84edee2019-10-02 12:50:57 +010015
Keith Davis02356de2019-08-26 18:28:17 +010016namespace armnn
17{
18
19namespace profiling
20{
21
Sadik Armagan3184c902020-03-18 10:57:30 +000022ProfilingGuidGenerator ProfilingService::m_GuidGenerator;
23
24ProfilingDynamicGuid ProfilingService::GetNextGuid()
25{
26 return m_GuidGenerator.NextGuid();
27}
28
29ProfilingStaticGuid ProfilingService::GetStaticId(const std::string& str)
30{
31 return m_GuidGenerator.GenerateStaticId(str);
32}
33
Jim Flynn6398a982020-05-27 17:05:21 +010034void ProfilingService::ResetGuidGenerator()
35{
36 m_GuidGenerator.Reset();
37}
38
Matteo Martincigha84edee2019-10-02 12:50:57 +010039void ProfilingService::ResetExternalProfilingOptions(const ExternalProfilingOptions& options,
40 bool resetProfilingService)
Keith Davis02356de2019-08-26 18:28:17 +010041{
Matteo Martincigha84edee2019-10-02 12:50:57 +010042 // Update the profiling options
43 m_Options = options;
Keith Davis33ed2212020-03-30 10:43:41 +010044 m_TimelineReporting = options.m_TimelineEnabled;
Finn Williamsd7fcafa2020-04-23 17:55:18 +010045 m_ConnectionAcknowledgedCommandHandler.setTimelineEnabled(options.m_TimelineEnabled);
Keith Davis02356de2019-08-26 18:28:17 +010046
Matteo Martincigh54fb9572019-10-02 12:50:57 +010047 // Check if the profiling service needs to be reset
Matteo Martincigha84edee2019-10-02 12:50:57 +010048 if (resetProfilingService)
Keith Davis02356de2019-08-26 18:28:17 +010049 {
Matteo Martincigha84edee2019-10-02 12:50:57 +010050 // Reset the profiling service
Matteo Martincigh54fb9572019-10-02 12:50:57 +010051 Reset();
Keith Davis02356de2019-08-26 18:28:17 +010052 }
53}
54
Jim Flynn64063552020-02-14 10:18:08 +000055bool ProfilingService::IsProfilingEnabled() const
Keith Davise394bd92019-12-02 15:12:19 +000056{
57 return m_Options.m_EnableProfiling;
58}
59
Jim Flynn672d06e2019-10-15 10:18:11 +010060ProfilingState ProfilingService::ConfigureProfilingService(
61 const ExternalProfilingOptions& options,
62 bool resetProfilingService)
63{
64 ResetExternalProfilingOptions(options, resetProfilingService);
65 ProfilingState currentState = m_StateMachine.GetCurrentState();
66 if (options.m_EnableProfiling)
67 {
68 switch (currentState)
69 {
70 case ProfilingState::Uninitialised:
71 Update(); // should transition to NotConnected
72 Update(); // will either stay in NotConnected because there is no server
73 // or will enter WaitingForAck.
74 currentState = m_StateMachine.GetCurrentState();
75 if (currentState == ProfilingState::WaitingForAck)
76 {
77 Update(); // poke it again to send out the metadata packet
78 }
79 currentState = m_StateMachine.GetCurrentState();
80 return currentState;
81 case ProfilingState::NotConnected:
82 Update(); // will either stay in NotConnected because there is no server
83 // or will enter WaitingForAck
84 currentState = m_StateMachine.GetCurrentState();
85 if (currentState == ProfilingState::WaitingForAck)
86 {
87 Update(); // poke it again to send out the metadata packet
88 }
89 currentState = m_StateMachine.GetCurrentState();
90 return currentState;
91 default:
92 return currentState;
93 }
94 }
95 else
96 {
97 // Make sure profiling is shutdown
98 switch (currentState)
99 {
100 case ProfilingState::Uninitialised:
101 case ProfilingState::NotConnected:
102 return currentState;
103 default:
104 Stop();
105 return m_StateMachine.GetCurrentState();
106 }
107 }
108}
109
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100110void ProfilingService::Update()
Keith Davis02356de2019-08-26 18:28:17 +0100111{
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100112 if (!m_Options.m_EnableProfiling)
Matteo Martincigha84edee2019-10-02 12:50:57 +0100113 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100114 // Don't run if profiling is disabled
115 return;
Matteo Martincigha84edee2019-10-02 12:50:57 +0100116 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100117
118 ProfilingState currentState = m_StateMachine.GetCurrentState();
119 switch (currentState)
Keith Davis02356de2019-08-26 18:28:17 +0100120 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100121 case ProfilingState::Uninitialised:
janeil01811ca552019-12-03 17:01:32 +0000122
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100123 // Initialize the profiling service
124 Initialize();
125
126 // Move to the next state
127 m_StateMachine.TransitionToState(ProfilingState::NotConnected);
128 break;
129 case ProfilingState::NotConnected:
Matteo Martincighd0613b52019-10-09 16:47:04 +0100130 // Stop the command thread (if running)
131 m_CommandHandler.Stop();
132
133 // Stop the send thread (if running)
Sadik Armagan3896b472020-02-10 12:24:15 +0000134 m_SendThread.Stop(false);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100135
Matteo Martincighe8485382019-10-10 14:08:21 +0100136 // Stop the periodic counter capture thread (if running)
137 m_PeriodicCounterCapture.Stop();
138
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100139 // Reset any existing profiling connection
140 m_ProfilingConnection.reset();
141
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100142 try
Keith Davis02356de2019-08-26 18:28:17 +0100143 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100144 // Setup the profiling connection
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100145 ARMNN_ASSERT(m_ProfilingConnectionFactory);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100146 m_ProfilingConnection = m_ProfilingConnectionFactory->GetProfilingConnection(m_Options);
Keith Davis02356de2019-08-26 18:28:17 +0100147 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100148 catch (const Exception& e)
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100149 {
Derek Lamberti08446972019-11-26 16:38:31 +0000150 ARMNN_LOG(warning) << "An error has occurred when creating the profiling connection: "
151 << e.what();
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100152 }
Jim Flynnbbfe6032020-07-20 16:57:44 +0100153 catch (const arm::pipe::SocketConnectionException& e)
Sadik Armagana97a0be2020-03-03 10:44:56 +0000154 {
155 ARMNN_LOG(warning) << "An error has occurred when creating the profiling connection ["
156 << e.what() << "] on socket [" << e.GetSocketFd() << "].";
157 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100158
159 // Move to the next state
160 m_StateMachine.TransitionToState(m_ProfilingConnection
161 ? ProfilingState::WaitingForAck // Profiling connection obtained, wait for ack
162 : ProfilingState::NotConnected); // Profiling connection failed, stay in the
163 // "NotConnected" state
164 break;
165 case ProfilingState::WaitingForAck:
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100166 ARMNN_ASSERT(m_ProfilingConnection);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100167
168 // Start the command thread
169 m_CommandHandler.Start(*m_ProfilingConnection);
170
171 // Start the send thread, while in "WaitingForAck" state it'll send out a "Stream MetaData" packet waiting for
172 // a valid "Connection Acknowledged" packet confirming the connection
Sadik Armagan3896b472020-02-10 12:24:15 +0000173 m_SendThread.Start(*m_ProfilingConnection);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100174
175 // The connection acknowledged command handler will automatically transition the state to "Active" once a
176 // valid "Connection Acknowledged" packet has been received
177
178 break;
179 case ProfilingState::Active:
180
Matteo Martincighe8485382019-10-10 14:08:21 +0100181 // The period counter capture thread is started by the Periodic Counter Selection command handler upon
182 // request by an external profiling service
183
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100184 break;
185 default:
Jan Eilers156113c2020-09-09 19:11:16 +0100186 throw RuntimeException(fmt::format("Unknown profiling service state: {}",
187 static_cast<int>(currentState)));
Sadik Armaganbd9e2c52019-09-26 23:13:31 +0100188 }
Keith Davis02356de2019-08-26 18:28:17 +0100189}
190
Jim Flynn53e46992019-10-14 12:31:10 +0100191void ProfilingService::Disconnect()
192{
193 ProfilingState currentState = m_StateMachine.GetCurrentState();
194 switch (currentState)
195 {
196 case ProfilingState::Uninitialised:
197 case ProfilingState::NotConnected:
198 case ProfilingState::WaitingForAck:
199 return; // NOP
200 case ProfilingState::Active:
201 // Stop the command thread (if running)
202 Stop();
203
204 break;
205 default:
Jan Eilers156113c2020-09-09 19:11:16 +0100206 throw RuntimeException(fmt::format("Unknown profiling service state: {}",
207 static_cast<int>(currentState)));
Jim Flynn53e46992019-10-14 12:31:10 +0100208 }
209}
210
David Monahanc1536d62020-02-12 15:52:35 +0000211// Store a profiling context returned from a backend that support profiling, and register its counters
212void ProfilingService::AddBackendProfilingContext(const BackendId backendId,
213 std::shared_ptr<armnn::profiling::IBackendProfilingContext> profilingContext)
214{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100215 ARMNN_ASSERT(profilingContext != nullptr);
David Monahanc1536d62020-02-12 15:52:35 +0000216 // Register the backend counters
217 m_MaxGlobalCounterId = profilingContext->RegisterCounters(m_MaxGlobalCounterId);
218 m_BackendProfilingContexts.emplace(backendId, std::move(profilingContext));
219}
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100220const ICounterDirectory& ProfilingService::GetCounterDirectory() const
221{
222 return m_CounterDirectory;
223}
224
Jim Flynn97897022020-02-02 12:52:59 +0000225ICounterRegistry& ProfilingService::GetCounterRegistry()
226{
227 return m_CounterDirectory;
228}
229
Matteo Martincigha84edee2019-10-02 12:50:57 +0100230ProfilingState ProfilingService::GetCurrentState() const
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100231{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100232 return m_StateMachine.GetCurrentState();
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100233}
234
235uint16_t ProfilingService::GetCounterCount() const
236{
237 return m_CounterDirectory.GetCounterCount();
238}
239
Matteo Martincighe8485382019-10-10 14:08:21 +0100240bool ProfilingService::IsCounterRegistered(uint16_t counterUid) const
241{
Finn Williamsb205a332020-05-13 15:04:25 +0100242 return m_CounterDirectory.IsCounterRegistered(counterUid);
Matteo Martincighe8485382019-10-10 14:08:21 +0100243}
244
Finn Williamsf3fcf322020-05-11 14:38:02 +0100245uint32_t ProfilingService::GetAbsoluteCounterValue(uint16_t counterUid) const
Keith Davis02356de2019-08-26 18:28:17 +0100246{
Matteo Martincighe8485382019-10-10 14:08:21 +0100247 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100248 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100249 ARMNN_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100250 return counterValuePtr->load(std::memory_order::memory_order_relaxed);
Keith Davis02356de2019-08-26 18:28:17 +0100251}
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100252
Finn Williamsf3fcf322020-05-11 14:38:02 +0100253uint32_t ProfilingService::GetDeltaCounterValue(uint16_t counterUid)
254{
255 CheckCounterUid(counterUid);
256 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
257 ARMNN_ASSERT(counterValuePtr);
258 const uint32_t counterValue = counterValuePtr->load(std::memory_order::memory_order_relaxed);
259 SubtractCounterValue(counterUid, counterValue);
260 return counterValue;
261}
262
Jim Flynn8e0c7a62020-01-30 14:10:55 +0000263const ICounterMappings& ProfilingService::GetCounterMappings() const
264{
265 return m_CounterIdMap;
266}
267
Jim Flynn97897022020-02-02 12:52:59 +0000268IRegisterCounterMapping& ProfilingService::GetCounterMappingRegistry()
Jim Flynn8e0c7a62020-01-30 14:10:55 +0000269{
270 return m_CounterIdMap;
271}
272
James Conroy2dcd3fe2020-02-06 18:34:52 +0000273CaptureData ProfilingService::GetCaptureData()
274{
275 return m_Holder.GetCaptureData();
276}
277
Finn Williams032bc742020-02-12 11:02:34 +0000278void ProfilingService::SetCaptureData(uint32_t capturePeriod,
279 const std::vector<uint16_t>& counterIds,
280 const std::set<BackendId>& activeBackends)
James Conroy2dcd3fe2020-02-06 18:34:52 +0000281{
Finn Williams032bc742020-02-12 11:02:34 +0000282 m_Holder.SetCaptureData(capturePeriod, counterIds, activeBackends);
James Conroy2dcd3fe2020-02-06 18:34:52 +0000283}
284
Matteo Martincigha84edee2019-10-02 12:50:57 +0100285void ProfilingService::SetCounterValue(uint16_t counterUid, uint32_t value)
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100286{
Matteo Martincighe8485382019-10-10 14:08:21 +0100287 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100288 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100289 ARMNN_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100290 counterValuePtr->store(value, std::memory_order::memory_order_relaxed);
291}
292
293uint32_t ProfilingService::AddCounterValue(uint16_t counterUid, uint32_t value)
294{
Matteo Martincighe8485382019-10-10 14:08:21 +0100295 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100296 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100297 ARMNN_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100298 return counterValuePtr->fetch_add(value, std::memory_order::memory_order_relaxed);
299}
300
301uint32_t ProfilingService::SubtractCounterValue(uint16_t counterUid, uint32_t value)
302{
Matteo Martincighe8485382019-10-10 14:08:21 +0100303 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100304 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100305 ARMNN_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100306 return counterValuePtr->fetch_sub(value, std::memory_order::memory_order_relaxed);
307}
308
309uint32_t ProfilingService::IncrementCounterValue(uint16_t counterUid)
310{
Matteo Martincighe8485382019-10-10 14:08:21 +0100311 CheckCounterUid(counterUid);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100312 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100313 ARMNN_ASSERT(counterValuePtr);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100314 return counterValuePtr->operator++(std::memory_order::memory_order_relaxed);
315}
316
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100317ProfilingDynamicGuid ProfilingService::NextGuid()
318{
Sadik Armagan3184c902020-03-18 10:57:30 +0000319 return ProfilingService::GetNextGuid();
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100320}
321
322ProfilingStaticGuid ProfilingService::GenerateStaticId(const std::string& str)
323{
Sadik Armagan3184c902020-03-18 10:57:30 +0000324 return ProfilingService::GetStaticId(str);
Jim Flynn00f3aaf2019-10-24 11:58:06 +0100325}
326
Jim Flynn8b200652019-10-24 18:07:44 +0100327std::unique_ptr<ISendTimelinePacket> ProfilingService::GetSendTimelinePacket() const
328{
329 return m_TimelinePacketWriterFactory.GetSendTimelinePacket();
330}
331
Matteo Martincigha84edee2019-10-02 12:50:57 +0100332void ProfilingService::Initialize()
333{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100334 // Register a category for the basic runtime counters
335 if (!m_CounterDirectory.IsCategoryRegistered("ArmNN_Runtime"))
336 {
337 m_CounterDirectory.RegisterCategory("ArmNN_Runtime");
338 }
339
Keith Davise394bd92019-12-02 15:12:19 +0000340 // Register a counter for the number of Network loads
341 if (!m_CounterDirectory.IsCounterRegistered("Network loads"))
Matteo Martincigha84edee2019-10-02 12:50:57 +0100342 {
343 const Counter* loadedNetworksCounter =
Keith Davise394bd92019-12-02 15:12:19 +0000344 m_CounterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
345 armnn::profiling::NETWORK_LOADS,
346 "ArmNN_Runtime",
Finn Williamsf3fcf322020-05-11 14:38:02 +0100347 0,
Matteo Martincigha84edee2019-10-02 12:50:57 +0100348 0,
349 1.f,
Keith Davise394bd92019-12-02 15:12:19 +0000350 "Network loads",
Matteo Martincigha84edee2019-10-02 12:50:57 +0100351 "The number of networks loaded at runtime",
352 std::string("networks"));
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100353 ARMNN_ASSERT(loadedNetworksCounter);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100354 InitializeCounterValue(loadedNetworksCounter->m_Uid);
355 }
Keith Davise394bd92019-12-02 15:12:19 +0000356 // Register a counter for the number of unloaded networks
357 if (!m_CounterDirectory.IsCounterRegistered("Network unloads"))
Matteo Martincigha84edee2019-10-02 12:50:57 +0100358 {
Keith Davise394bd92019-12-02 15:12:19 +0000359 const Counter* unloadedNetworksCounter =
360 m_CounterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
361 armnn::profiling::NETWORK_UNLOADS,
362 "ArmNN_Runtime",
Finn Williamsf3fcf322020-05-11 14:38:02 +0100363 0,
Matteo Martincigha84edee2019-10-02 12:50:57 +0100364 0,
365 1.f,
Keith Davise394bd92019-12-02 15:12:19 +0000366 "Network unloads",
367 "The number of networks unloaded at runtime",
368 std::string("networks"));
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100369 ARMNN_ASSERT(unloadedNetworksCounter);
Keith Davise394bd92019-12-02 15:12:19 +0000370 InitializeCounterValue(unloadedNetworksCounter->m_Uid);
371 }
372 // Register a counter for the number of registered backends
373 if (!m_CounterDirectory.IsCounterRegistered("Backends registered"))
374 {
375 const Counter* registeredBackendsCounter =
376 m_CounterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
377 armnn::profiling::REGISTERED_BACKENDS,
378 "ArmNN_Runtime",
Finn Williamsf3fcf322020-05-11 14:38:02 +0100379 0,
Keith Davise394bd92019-12-02 15:12:19 +0000380 0,
381 1.f,
382 "Backends registered",
Matteo Martincigha84edee2019-10-02 12:50:57 +0100383 "The number of registered backends",
384 std::string("backends"));
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100385 ARMNN_ASSERT(registeredBackendsCounter);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100386 InitializeCounterValue(registeredBackendsCounter->m_Uid);
Finn Williams45a73622020-05-15 18:41:05 +0100387
388 // Due to backends being registered before the profiling service becomes active,
389 // we need to set the counter to the correct value here
390 SetCounterValue(armnn::profiling::REGISTERED_BACKENDS, static_cast<uint32_t>(BackendRegistryInstance().Size()));
Matteo Martincigha84edee2019-10-02 12:50:57 +0100391 }
Keith Davise394bd92019-12-02 15:12:19 +0000392 // Register a counter for the number of registered backends
393 if (!m_CounterDirectory.IsCounterRegistered("Backends unregistered"))
394 {
395 const Counter* unregisteredBackendsCounter =
396 m_CounterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
397 armnn::profiling::UNREGISTERED_BACKENDS,
398 "ArmNN_Runtime",
Finn Williamsf3fcf322020-05-11 14:38:02 +0100399 0,
Keith Davise394bd92019-12-02 15:12:19 +0000400 0,
401 1.f,
402 "Backends unregistered",
403 "The number of unregistered backends",
404 std::string("backends"));
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100405 ARMNN_ASSERT(unregisteredBackendsCounter);
Keith Davise394bd92019-12-02 15:12:19 +0000406 InitializeCounterValue(unregisteredBackendsCounter->m_Uid);
407 }
Matteo Martincigha84edee2019-10-02 12:50:57 +0100408 // Register a counter for the number of inferences run
409 if (!m_CounterDirectory.IsCounterRegistered("Inferences run"))
410 {
411 const Counter* inferencesRunCounter =
Keith Davise394bd92019-12-02 15:12:19 +0000412 m_CounterDirectory.RegisterCounter(armnn::profiling::BACKEND_ID,
413 armnn::profiling::INFERENCES_RUN,
414 "ArmNN_Runtime",
Finn Williamsf3fcf322020-05-11 14:38:02 +0100415 0,
Matteo Martincigha84edee2019-10-02 12:50:57 +0100416 0,
417 1.f,
418 "Inferences run",
419 "The number of inferences run",
420 std::string("inferences"));
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100421 ARMNN_ASSERT(inferencesRunCounter);
Matteo Martincigha84edee2019-10-02 12:50:57 +0100422 InitializeCounterValue(inferencesRunCounter->m_Uid);
423 }
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100424}
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100425
Matteo Martincigha84edee2019-10-02 12:50:57 +0100426void ProfilingService::InitializeCounterValue(uint16_t counterUid)
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100427{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100428 // Increase the size of the counter index if necessary
429 if (counterUid >= m_CounterIndex.size())
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100430 {
Matthew Sloyan371b70e2020-09-11 10:14:57 +0100431 m_CounterIndex.resize(armnn::numeric_cast<size_t>(counterUid) + 1);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100432 }
Matteo Martincigha84edee2019-10-02 12:50:57 +0100433
434 // Create a new atomic counter and add it to the list
435 m_CounterValues.emplace_back(0);
436
437 // Register the new counter to the counter index for quick access
438 std::atomic<uint32_t>* counterValuePtr = &(m_CounterValues.back());
439 m_CounterIndex.at(counterUid) = counterValuePtr;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100440}
441
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100442void ProfilingService::Reset()
443{
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100444 // Stop the profiling service...
Jim Flynn53e46992019-10-14 12:31:10 +0100445 Stop();
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100446
Jim Flynn53e46992019-10-14 12:31:10 +0100447 // ...then delete all the counter data and configuration...
448 m_CounterIndex.clear();
449 m_CounterValues.clear();
450 m_CounterDirectory.Clear();
Jim Flynn97897022020-02-02 12:52:59 +0000451 m_CounterIdMap.Reset();
Finn Williams09ad6f92019-12-19 17:05:18 +0000452 m_BufferManager.Reset();
Matteo Martincighd0613b52019-10-09 16:47:04 +0100453
Jim Flynn53e46992019-10-14 12:31:10 +0100454 // ...finally reset the profiling state machine
455 m_StateMachine.Reset();
Colm Donelan1aff3932020-02-05 17:48:59 +0000456 m_BackendProfilingContexts.clear();
Keith Davis33ed2212020-03-30 10:43:41 +0100457 m_MaxGlobalCounterId = armnn::profiling::MAX_ARMNN_COUNTER;
Jim Flynn53e46992019-10-14 12:31:10 +0100458}
459
460void ProfilingService::Stop()
461{
Jim Flynn6398a982020-05-27 17:05:21 +0100462 { // only lock when we are updating the inference completed variable
463 std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
464 m_ServiceActive = false;
465 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100466 // The order in which we reset/stop the components is not trivial!
Finn Williams09ad6f92019-12-19 17:05:18 +0000467 // First stop the producing threads
468 // Command Handler first as it is responsible for launching then Periodic Counter capture thread
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100469 m_CommandHandler.Stop();
Matteo Martincighe8485382019-10-10 14:08:21 +0100470 m_PeriodicCounterCapture.Stop();
Finn Williams09ad6f92019-12-19 17:05:18 +0000471 // The the consuming thread
Sadik Armagan3896b472020-02-10 12:24:15 +0000472 m_SendThread.Stop(false);
Matteo Martincighd0613b52019-10-09 16:47:04 +0100473
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100474 // ...then close and destroy the profiling connection...
Jim Flynn53e46992019-10-14 12:31:10 +0100475 if (m_ProfilingConnection != nullptr && m_ProfilingConnection->IsOpen())
476 {
477 m_ProfilingConnection->Close();
478 }
Matteo Martincighd0613b52019-10-09 16:47:04 +0100479 m_ProfilingConnection.reset();
480
Matteo Martincigh8d9590e2019-10-15 09:35:29 +0100481 // ...then move to the "NotConnected" state
Jim Flynn53e46992019-10-14 12:31:10 +0100482 m_StateMachine.TransitionToState(ProfilingState::NotConnected);
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100483}
484
Matteo Martincighe8485382019-10-10 14:08:21 +0100485inline void ProfilingService::CheckCounterUid(uint16_t counterUid) const
486{
487 if (!IsCounterRegistered(counterUid))
488 {
Jan Eilers156113c2020-09-09 19:11:16 +0100489 throw InvalidArgumentException(fmt::format("Counter UID {} is not registered", counterUid));
Matteo Martincighe8485382019-10-10 14:08:21 +0100490 }
491}
492
Keith Davis33ed2212020-03-30 10:43:41 +0100493void ProfilingService::NotifyBackendsForTimelineReporting()
494{
495 BackendProfilingContext::iterator it = m_BackendProfilingContexts.begin();
496 while (it != m_BackendProfilingContexts.end())
497 {
498 auto& backendProfilingContext = it->second;
499 backendProfilingContext->EnableTimelineReporting(m_TimelineReporting);
500 // Increment the Iterator to point to next entry
501 it++;
502 }
503}
504
Jim Flynn6398a982020-05-27 17:05:21 +0100505void ProfilingService::NotifyProfilingServiceActive()
506{
507 { // only lock when we are updating the inference completed variable
508 std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
509 m_ServiceActive = true;
510 }
511 m_ServiceActiveConditionVariable.notify_one();
512}
513
514void ProfilingService::WaitForProfilingServiceActivation(unsigned int timeout)
515{
516 std::unique_lock<std::mutex> lck(m_ServiceActiveMutex);
517
518 auto start = std::chrono::high_resolution_clock::now();
519 // Here we we will go back to sleep after a spurious wake up if
520 // m_InferenceCompleted is not yet true.
521 if (!m_ServiceActiveConditionVariable.wait_for(lck,
522 std::chrono::milliseconds(timeout),
523 [&]{return m_ServiceActive == true;}))
524 {
525 if (m_ServiceActive == true)
526 {
527 return;
528 }
529 auto finish = std::chrono::high_resolution_clock::now();
530 std::chrono::duration<double, std::milli> elapsed = finish - start;
531 std::stringstream ss;
532 ss << "Timed out waiting on profiling service activation for " << elapsed.count() << " ms";
533 ARMNN_LOG(warning) << ss.str();
534 }
535 return;
536}
537
janeil01811ca552019-12-03 17:01:32 +0000538ProfilingService::~ProfilingService()
539{
540 Stop();
541}
Keith Davis02356de2019-08-26 18:28:17 +0100542} // namespace profiling
543
Matteo Martincigha84edee2019-10-02 12:50:57 +0100544} // namespace armnn