blob: 19cf9cb58eceae8ccc3af3626b2fbbff6bf35ec2 [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#include "ProfilingService.hpp"
7
Matteo Martincigha84edee2019-10-02 12:50:57 +01008#include <boost/log/trivial.hpp>
9#include <boost/format.hpp>
10
Keith Davis02356de2019-08-26 18:28:17 +010011namespace armnn
12{
13
14namespace profiling
15{
16
Matteo Martincigha84edee2019-10-02 12:50:57 +010017void ProfilingService::ResetExternalProfilingOptions(const ExternalProfilingOptions& options,
18 bool resetProfilingService)
Keith Davis02356de2019-08-26 18:28:17 +010019{
Matteo Martincigha84edee2019-10-02 12:50:57 +010020 // Update the profiling options
21 m_Options = options;
Keith Davis02356de2019-08-26 18:28:17 +010022
Matteo Martincigh54fb9572019-10-02 12:50:57 +010023 // Check if the profiling service needs to be reset
Matteo Martincigha84edee2019-10-02 12:50:57 +010024 if (resetProfilingService)
Keith Davis02356de2019-08-26 18:28:17 +010025 {
Matteo Martincigha84edee2019-10-02 12:50:57 +010026 // Reset the profiling service
Matteo Martincigh54fb9572019-10-02 12:50:57 +010027 Reset();
Keith Davis02356de2019-08-26 18:28:17 +010028 }
29}
30
Matteo Martincigh54fb9572019-10-02 12:50:57 +010031void ProfilingService::Update()
Keith Davis02356de2019-08-26 18:28:17 +010032{
Matteo Martincigh54fb9572019-10-02 12:50:57 +010033 if (!m_Options.m_EnableProfiling)
Matteo Martincigha84edee2019-10-02 12:50:57 +010034 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +010035 // Don't run if profiling is disabled
36 return;
Matteo Martincigha84edee2019-10-02 12:50:57 +010037 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +010038
39 ProfilingState currentState = m_StateMachine.GetCurrentState();
40 switch (currentState)
Keith Davis02356de2019-08-26 18:28:17 +010041 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +010042 case ProfilingState::Uninitialised:
43 // Initialize the profiling service
44 Initialize();
45
46 // Move to the next state
47 m_StateMachine.TransitionToState(ProfilingState::NotConnected);
48 break;
49 case ProfilingState::NotConnected:
50 BOOST_ASSERT(m_ProfilingConnectionFactory);
51
52 // Reset any existing profiling connection
53 m_ProfilingConnection.reset();
54
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010055 try
Keith Davis02356de2019-08-26 18:28:17 +010056 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +010057 // Setup the profiling connection
58 //m_ProfilingConnection = m_ProfilingConnectionFactory.GetProfilingConnection(m_Options);
59 m_ProfilingConnection = m_ProfilingConnectionFactory->GetProfilingConnection(m_Options);
Keith Davis02356de2019-08-26 18:28:17 +010060 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +010061 catch (const Exception& e)
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010062 {
Matteo Martincigh54fb9572019-10-02 12:50:57 +010063 BOOST_LOG_TRIVIAL(warning) << "An error has occurred when creating the profiling connection: "
64 << e.what();
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010065 }
Matteo Martincigh54fb9572019-10-02 12:50:57 +010066
67 // Move to the next state
68 m_StateMachine.TransitionToState(m_ProfilingConnection
69 ? ProfilingState::WaitingForAck // Profiling connection obtained, wait for ack
70 : ProfilingState::NotConnected); // Profiling connection failed, stay in the
71 // "NotConnected" state
72 break;
73 case ProfilingState::WaitingForAck:
74 BOOST_ASSERT(m_ProfilingConnection);
75
76 // Start the command thread
77 m_CommandHandler.Start(*m_ProfilingConnection);
78
79 // Start the send thread, while in "WaitingForAck" state it'll send out a "Stream MetaData" packet waiting for
80 // a valid "Connection Acknowledged" packet confirming the connection
81 m_SendCounterPacket.Start(*m_ProfilingConnection);
82
83 // The connection acknowledged command handler will automatically transition the state to "Active" once a
84 // valid "Connection Acknowledged" packet has been received
85
86 break;
87 case ProfilingState::Active:
88
89 break;
90 default:
91 throw RuntimeException(boost::str(boost::format("Unknown profiling service state: %1")
92 % static_cast<int>(currentState)));
Sadik Armaganbd9e2c52019-09-26 23:13:31 +010093 }
Keith Davis02356de2019-08-26 18:28:17 +010094}
95
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +010096const ICounterDirectory& ProfilingService::GetCounterDirectory() const
97{
98 return m_CounterDirectory;
99}
100
Matteo Martincigha84edee2019-10-02 12:50:57 +0100101ProfilingState ProfilingService::GetCurrentState() const
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100102{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100103 return m_StateMachine.GetCurrentState();
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100104}
105
106uint16_t ProfilingService::GetCounterCount() const
107{
108 return m_CounterDirectory.GetCounterCount();
109}
110
Matteo Martincigha84edee2019-10-02 12:50:57 +0100111uint32_t ProfilingService::GetCounterValue(uint16_t counterUid) const
Keith Davis02356de2019-08-26 18:28:17 +0100112{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100113 BOOST_ASSERT(counterUid < m_CounterIndex.size());
114 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
115 BOOST_ASSERT(counterValuePtr);
116 return counterValuePtr->load(std::memory_order::memory_order_relaxed);
Keith Davis02356de2019-08-26 18:28:17 +0100117}
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100118
Matteo Martincigha84edee2019-10-02 12:50:57 +0100119void ProfilingService::SetCounterValue(uint16_t counterUid, uint32_t value)
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100120{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100121 BOOST_ASSERT(counterUid < m_CounterIndex.size());
122 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
123 BOOST_ASSERT(counterValuePtr);
124 counterValuePtr->store(value, std::memory_order::memory_order_relaxed);
125}
126
127uint32_t ProfilingService::AddCounterValue(uint16_t counterUid, uint32_t value)
128{
129 BOOST_ASSERT(counterUid < m_CounterIndex.size());
130 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
131 BOOST_ASSERT(counterValuePtr);
132 return counterValuePtr->fetch_add(value, std::memory_order::memory_order_relaxed);
133}
134
135uint32_t ProfilingService::SubtractCounterValue(uint16_t counterUid, uint32_t value)
136{
137 BOOST_ASSERT(counterUid < m_CounterIndex.size());
138 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
139 BOOST_ASSERT(counterValuePtr);
140 return counterValuePtr->fetch_sub(value, std::memory_order::memory_order_relaxed);
141}
142
143uint32_t ProfilingService::IncrementCounterValue(uint16_t counterUid)
144{
145 BOOST_ASSERT(counterUid < m_CounterIndex.size());
146 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
147 BOOST_ASSERT(counterValuePtr);
148 return counterValuePtr->operator++(std::memory_order::memory_order_relaxed);
149}
150
151uint32_t ProfilingService::DecrementCounterValue(uint16_t counterUid)
152{
153 BOOST_ASSERT(counterUid < m_CounterIndex.size());
154 std::atomic<uint32_t>* counterValuePtr = m_CounterIndex.at(counterUid);
155 BOOST_ASSERT(counterValuePtr);
156 return counterValuePtr->operator--(std::memory_order::memory_order_relaxed);
157}
158
159void ProfilingService::Initialize()
160{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100161 // Register a category for the basic runtime counters
162 if (!m_CounterDirectory.IsCategoryRegistered("ArmNN_Runtime"))
163 {
164 m_CounterDirectory.RegisterCategory("ArmNN_Runtime");
165 }
166
167 // Register a counter for the number of loaded networks
168 if (!m_CounterDirectory.IsCounterRegistered("Loaded networks"))
169 {
170 const Counter* loadedNetworksCounter =
171 m_CounterDirectory.RegisterCounter("ArmNN_Runtime",
172 0,
173 0,
174 1.f,
175 "Loaded networks",
176 "The number of networks loaded at runtime",
177 std::string("networks"));
178 BOOST_ASSERT(loadedNetworksCounter);
179 InitializeCounterValue(loadedNetworksCounter->m_Uid);
180 }
181
182 // Register a counter for the number of registered backends
183 if (!m_CounterDirectory.IsCounterRegistered("Registered backends"))
184 {
185 const Counter* registeredBackendsCounter =
186 m_CounterDirectory.RegisterCounter("ArmNN_Runtime",
187 0,
188 0,
189 1.f,
190 "Registered backends",
191 "The number of registered backends",
192 std::string("backends"));
193 BOOST_ASSERT(registeredBackendsCounter);
194 InitializeCounterValue(registeredBackendsCounter->m_Uid);
195 }
196
197 // Register a counter for the number of inferences run
198 if (!m_CounterDirectory.IsCounterRegistered("Inferences run"))
199 {
200 const Counter* inferencesRunCounter =
201 m_CounterDirectory.RegisterCounter("ArmNN_Runtime",
202 0,
203 0,
204 1.f,
205 "Inferences run",
206 "The number of inferences run",
207 std::string("inferences"));
208 BOOST_ASSERT(inferencesRunCounter);
209 InitializeCounterValue(inferencesRunCounter->m_Uid);
210 }
FinnWilliamsArmce2d9d12019-09-18 10:28:16 +0100211}
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100212
Matteo Martincigha84edee2019-10-02 12:50:57 +0100213void ProfilingService::InitializeCounterValue(uint16_t counterUid)
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100214{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100215 // Increase the size of the counter index if necessary
216 if (counterUid >= m_CounterIndex.size())
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100217 {
Matteo Martincigha84edee2019-10-02 12:50:57 +0100218 m_CounterIndex.resize(boost::numeric_cast<size_t>(counterUid) + 1);
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100219 }
Matteo Martincigha84edee2019-10-02 12:50:57 +0100220
221 // Create a new atomic counter and add it to the list
222 m_CounterValues.emplace_back(0);
223
224 // Register the new counter to the counter index for quick access
225 std::atomic<uint32_t>* counterValuePtr = &(m_CounterValues.back());
226 m_CounterIndex.at(counterUid) = counterValuePtr;
FinnWilliamsArmf6e534a2019-09-16 15:45:42 +0100227}
228
Matteo Martincigh54fb9572019-10-02 12:50:57 +0100229void ProfilingService::Reset()
230{
231 // Reset the profiling service
232 m_CounterDirectory.Clear();
233 m_ProfilingConnection.reset();
234 m_StateMachine.Reset();
235 m_CounterIndex.clear();
236 m_CounterValues.clear();
237 m_CommandHandler.Stop();
238 m_SendCounterPacket.Stop(false);
239}
240
Keith Davis02356de2019-08-26 18:28:17 +0100241} // namespace profiling
242
Matteo Martincigha84edee2019-10-02 12:50:57 +0100243} // namespace armnn