blob: 87706996ad5a80209cab1f59c037c9d26c7d0e1c [file] [log] [blame]
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +01001//
Jim Flynnbbfe6032020-07-20 16:57:44 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "CounterDirectory.hpp"
Matteo Martincigh6db5f202019-09-05 12:02:04 +01007#include "ProfilingUtils.hpp"
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +01008
Cathal Corbett6f073722022-03-04 12:11:09 +00009#include <armnn/BackendId.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010010
Jim Flynn6730fe92022-03-10 22:57:47 +000011#include <common/include/Assert.hpp>
Jim Flynnbbfe6032020-07-20 16:57:44 +010012#include <common/include/SwTrace.hpp>
13
Jan Eilers156113c2020-09-09 19:11:16 +010014#include <fmt/format.h>
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010015
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000016namespace arm
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010017{
18
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000019namespace pipe
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010020{
21
Sadik Armagan4c998992020-02-25 12:44:44 +000022const Category* CounterDirectory::RegisterCategory(const std::string& categoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010023{
Matteo Martincigh6db5f202019-09-05 12:02:04 +010024 // Check that the given category name is valid
25 if (categoryName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +010026 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(categoryName))
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010027 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +000028 throw arm::pipe::InvalidArgumentException("Trying to register a category with an invalid name");
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010029 }
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010030
Matteo Martincigh6db5f202019-09-05 12:02:04 +010031 // Check that the given category is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010032 if (IsCategoryRegistered(categoryName))
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010033 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +000034 throw arm::pipe::InvalidArgumentException(fmt::format(
35 "Trying to register a category already registered (\"{}\")",
36 categoryName));
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010037 }
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010038
Matteo Martincigh6db5f202019-09-05 12:02:04 +010039 // Create the category
Sadik Armagan4c998992020-02-25 12:44:44 +000040 CategoryPtr category = std::make_unique<Category>(categoryName);
Jim Flynn6730fe92022-03-10 22:57:47 +000041 ARM_PIPE_ASSERT(category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +010042
43 // Get the raw category pointer
44 const Category* categoryPtr = category.get();
Jim Flynn6730fe92022-03-10 22:57:47 +000045 ARM_PIPE_ASSERT(categoryPtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +010046
47 // Register the category
48 m_Categories.insert(std::move(category));
49
50 return categoryPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010051}
52
Matteo Martincigh6db5f202019-09-05 12:02:04 +010053const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
54 uint16_t cores,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +000055 const armnn::Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010056{
Matteo Martincigh6db5f202019-09-05 12:02:04 +010057 // Check that the given device name is valid
58 if (deviceName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +010059 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(deviceName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010060 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +000061 throw arm::pipe::InvalidArgumentException("Trying to register a device with an invalid name");
Matteo Martincigh6db5f202019-09-05 12:02:04 +010062 }
63
64 // Check that a device with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010065 if (IsDeviceRegistered(deviceName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010066 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +000067 throw arm::pipe::InvalidArgumentException(fmt::format(
68 "Trying to register a device already registered (\"{}\")",
69 deviceName));
Matteo Martincigh6db5f202019-09-05 12:02:04 +010070 }
71
Matteo Martincigh6db5f202019-09-05 12:02:04 +010072 // Check that a category with the given (optional) parent category name is already registered
Matteo Martincigh6db5f202019-09-05 12:02:04 +010073 if (parentCategoryName.has_value())
74 {
75 // Get the (optional) parent category name
76 const std::string& parentCategoryNameValue = parentCategoryName.value();
77 if (parentCategoryNameValue.empty())
78 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +000079 throw arm::pipe::InvalidArgumentException(
80 fmt::format("Trying to connect a device (name: \"{}\") to an invalid "
81 "parent category (name: \"{}\")",
82 deviceName,
83 parentCategoryNameValue));
Matteo Martincigh6db5f202019-09-05 12:02:04 +010084 }
85
86 // Check that the given parent category is already registered
87 auto categoryIt = FindCategory(parentCategoryNameValue);
88 if (categoryIt == m_Categories.end())
89 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +000090 throw arm::pipe::InvalidArgumentException(
91 fmt::format("Trying to connect a device (name: \"{}\") to a parent category that "
92 "is not registered (name: \"{}\")",
93 deviceName,
94 parentCategoryNameValue));
Matteo Martincigh6db5f202019-09-05 12:02:04 +010095 }
Matteo Martincigh6db5f202019-09-05 12:02:04 +010096 }
97
98 // Get the device UID
99 uint16_t deviceUid = GetNextUid();
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100100
101 // Create the device
102 DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
Jim Flynn6730fe92022-03-10 22:57:47 +0000103 ARM_PIPE_ASSERT(device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100104
105 // Get the raw device pointer
106 const Device* devicePtr = device.get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000107 ARM_PIPE_ASSERT(devicePtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100108
109 // Register the device
110 m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
111
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100112 return devicePtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100113}
114
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100115const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
116 uint16_t count,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000117 const armnn::Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100118{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100119 // Check that the given counter set name is valid
120 if (counterSetName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100121 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(counterSetName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100122 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000123 throw arm::pipe::InvalidArgumentException("Trying to register a counter set with an invalid name");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100124 }
125
126 // Check that a counter set with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100127 if (IsCounterSetRegistered(counterSetName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100128 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000129 throw arm::pipe::InvalidArgumentException(
130 fmt::format("Trying to register a counter set already registered (\"{}\")", counterSetName));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100131 }
132
133 // Peek the next UID, do not get an actual valid UID just now as we don't want to waste a good UID in case
134 // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
135 uint16_t counterSetUidPeek = GetNextUid(true);
136
137 // Check that a category with the given (optional) parent category name is already registered
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100138 if (parentCategoryName.has_value())
139 {
140 // Get the (optional) parent category name
141 const std::string& parentCategoryNameValue = parentCategoryName.value();
142 if (parentCategoryNameValue.empty())
143 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000144 throw arm::pipe::InvalidArgumentException(
145 fmt::format("Trying to connect a counter set (UID: {}) to an invalid "
Jan Eilers156113c2020-09-09 19:11:16 +0100146 "parent category (name: \"{}\")",
147 counterSetUidPeek,
148 parentCategoryNameValue));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100149 }
150
151 // Check that the given parent category is already registered
152 auto it = FindCategory(parentCategoryNameValue);
153 if (it == m_Categories.end())
154 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000155 throw arm::pipe::InvalidArgumentException(
156 fmt::format("Trying to connect a counter set (UID: {}) to a parent category "
157 "that is not registered (name: \"{}\")",
158 counterSetUidPeek,
159 parentCategoryNameValue));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100160 }
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100161 }
162
163 // Get the counter set UID
164 uint16_t counterSetUid = GetNextUid();
Jim Flynn6730fe92022-03-10 22:57:47 +0000165 ARM_PIPE_ASSERT(counterSetUid == counterSetUidPeek);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100166
167 // Create the counter set
168 CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
Jim Flynn6730fe92022-03-10 22:57:47 +0000169 ARM_PIPE_ASSERT(counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100170
171 // Get the raw counter set pointer
172 const CounterSet* counterSetPtr = counterSet.get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000173 ARM_PIPE_ASSERT(counterSetPtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100174
175 // Register the counter set
176 m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
177
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100178 return counterSetPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100179}
180
Cathal Corbett6f073722022-03-04 12:11:09 +0000181const Counter* CounterDirectory::RegisterCounter(const std::string& /*backendId*/,
Keith Davise394bd92019-12-02 15:12:19 +0000182 const uint16_t uid,
183 const std::string& parentCategoryName,
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100184 uint16_t counterClass,
185 uint16_t interpolation,
186 double multiplier,
187 const std::string& name,
188 const std::string& description,
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000189 const armnn::Optional<std::string>& units,
190 const armnn::Optional<uint16_t>& numberOfCores,
191 const armnn::Optional<uint16_t>& deviceUid,
192 const armnn::Optional<uint16_t>& counterSetUid)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100193{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100194 // Check that the given parent category name is valid
195 if (parentCategoryName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100196 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(parentCategoryName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100197 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000198 throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid parent category name");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100199 }
200
201 // Check that the given class is valid
202 if (counterClass != 0 && counterClass != 1)
203 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000204 throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid class");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100205 }
206
207 // Check that the given interpolation is valid
208 if (interpolation != 0 && interpolation != 1)
209 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000210 throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid interpolation");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100211 }
212
213 // Check that the given multiplier is valid
214 if (multiplier == .0f)
215 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000216 throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid multiplier");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100217 }
218
219 // Check that the given name is valid
220 if (name.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100221 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(name))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100222 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000223 throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid name");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100224 }
225
226 // Check that the given description is valid
227 if (description.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100228 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(description))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100229 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000230 throw arm::pipe::InvalidArgumentException("Trying to register a counter with an invalid description");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100231 }
232
233 // Check that the given units are valid
234 if (units.has_value()
Jim Flynnbbfe6032020-07-20 16:57:44 +0100235 && !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(units.value()))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100236 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000237 throw arm::pipe::InvalidArgumentException("Trying to register a counter with a invalid units");
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100238 }
239
240 // Check that the given parent category is registered
241 auto categoryIt = FindCategory(parentCategoryName);
242 if (categoryIt == m_Categories.end())
243 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000244 throw arm::pipe::InvalidArgumentException(
245 fmt::format("Trying to connect a counter to a category that is not registered (name: \"{}\")",
246 parentCategoryName));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100247 }
248
249 // Get the parent category
250 const CategoryPtr& parentCategory = *categoryIt;
Jim Flynn6730fe92022-03-10 22:57:47 +0000251 ARM_PIPE_ASSERT(parentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100252
253 // Check that a counter with the given name is not already registered within the parent category
254 const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
255 for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
256 {
257 const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
Jim Flynn6730fe92022-03-10 22:57:47 +0000258 ARM_PIPE_ASSERT(parentCategoryCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100259
260 if (parentCategoryCounter->m_Name == name)
261 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000262 throw arm::pipe::InvalidArgumentException(
263 fmt::format("Trying to register a counter to category \"{}\" with a name that "
264 "is already used within that category (name: \"{}\")",
265 parentCategoryName,
266 name));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100267 }
268 }
269
270 // Check that a counter set with the given (optional) UID is already registered
271 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
272 if (counterSetUidValue > 0)
273 {
274 // Check that the (optional) counter set is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100275 if (!IsCounterSetRegistered(counterSetUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100276 {
277 throw InvalidArgumentException(
Jan Eilers156113c2020-09-09 19:11:16 +0100278 fmt::format("Trying to connect a counter to a counter set that is "
279 "not registered (counter set UID: {})",
280 counterSetUidValue));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100281 }
282 }
283
284 // Get the number of cores (this call may throw)
285 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
Sadik Armagan4c998992020-02-25 12:44:44 +0000286 uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100287
288 // Get the counter UIDs and calculate the max counter UID
Keith Davise394bd92019-12-02 15:12:19 +0000289 std::vector<uint16_t> counterUids = GetNextCounterUids(uid, deviceCores);
Jim Flynn6730fe92022-03-10 22:57:47 +0000290 ARM_PIPE_ASSERT(!counterUids.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100291 uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
292
293 // Get the counter units
294 const std::string unitsValue = units.has_value() ? units.value() : "";
295
296 // Create the counter
Keith Davise394bd92019-12-02 15:12:19 +0000297 CounterPtr counter = std::make_shared<Counter>(armnn::profiling::BACKEND_ID,
298 counterUids.front(),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100299 maxCounterUid,
300 counterClass,
301 interpolation,
302 multiplier,
303 name,
304 description,
305 unitsValue,
306 deviceUidValue,
307 counterSetUidValue);
Jim Flynn6730fe92022-03-10 22:57:47 +0000308 ARM_PIPE_ASSERT(counter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100309
310 // Get the raw counter pointer
311 const Counter* counterPtr = counter.get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000312 ARM_PIPE_ASSERT(counterPtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100313
314 // Process multiple counters if necessary
315 for (uint16_t counterUid : counterUids)
316 {
317 // Connect the counter to the parent category
318 parentCategory->m_Counters.push_back(counterUid);
319
320 // Register the counter
321 m_Counters.insert(std::make_pair(counterUid, counter));
322 }
323
324 return counterPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100325}
326
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100327const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100328{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100329 auto it = FindCategory(categoryName);
330 if (it == m_Categories.end())
331 {
332 return nullptr;
333 }
334
335 const Category* category = it->get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000336 ARM_PIPE_ASSERT(category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100337
338 return category;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100339}
340
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100341const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100342{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100343 auto it = FindDevice(deviceUid);
344 if (it == m_Devices.end())
345 {
346 return nullptr;
347 }
348
349 const Device* device = it->second.get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000350 ARM_PIPE_ASSERT(device);
351 ARM_PIPE_ASSERT(device->m_Uid == deviceUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100352
353 return device;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100354}
355
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100356const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100357{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100358 auto it = FindCounterSet(counterSetUid);
359 if (it == m_CounterSets.end())
360 {
361 return nullptr;
362 }
363
364 const CounterSet* counterSet = it->second.get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000365 ARM_PIPE_ASSERT(counterSet);
366 ARM_PIPE_ASSERT(counterSet->m_Uid == counterSetUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100367
368 return counterSet;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100369}
370
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100371const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100372{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100373 auto it = FindCounter(counterUid);
374 if (it == m_Counters.end())
375 {
376 return nullptr;
377 }
378
379 const Counter* counter = it->second.get();
Jim Flynn6730fe92022-03-10 22:57:47 +0000380 ARM_PIPE_ASSERT(counter);
381 ARM_PIPE_ASSERT(counter->m_Uid <= counterUid);
382 ARM_PIPE_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100383
384 return counter;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100385}
386
Matteo Martincigha84edee2019-10-02 12:50:57 +0100387bool CounterDirectory::IsCategoryRegistered(const std::string& categoryName) const
388{
389 auto it = FindCategory(categoryName);
390
391 return it != m_Categories.end();
392}
393
394bool CounterDirectory::IsDeviceRegistered(uint16_t deviceUid) const
395{
396 auto it = FindDevice(deviceUid);
397
398 return it != m_Devices.end();
399}
400
401bool CounterDirectory::IsDeviceRegistered(const std::string& deviceName) const
402{
403 auto it = FindDevice(deviceName);
404
405 return it != m_Devices.end();
406}
407
408bool CounterDirectory::IsCounterSetRegistered(uint16_t counterSetUid) const
409{
410 auto it = FindCounterSet(counterSetUid);
411
412 return it != m_CounterSets.end();
413}
414
415bool CounterDirectory::IsCounterSetRegistered(const std::string& counterSetName) const
416{
417 auto it = FindCounterSet(counterSetName);
418
419 return it != m_CounterSets.end();
420}
421
422bool CounterDirectory::IsCounterRegistered(uint16_t counterUid) const
423{
424 auto it = FindCounter(counterUid);
425
426 return it != m_Counters.end();
427}
428
429bool CounterDirectory::IsCounterRegistered(const std::string& counterName) const
430{
431 auto it = FindCounter(counterName);
432
433 return it != m_Counters.end();
434}
435
436void CounterDirectory::Clear()
437{
438 // Clear all the counter directory contents
439 m_Categories.clear();
440 m_Devices.clear();
441 m_CounterSets.clear();
442 m_Counters.clear();
443}
444
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100445CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100446{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100447 return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
448 {
Jim Flynn6730fe92022-03-10 22:57:47 +0000449 ARM_PIPE_ASSERT(category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100450
451 return category->m_Name == categoryName;
452 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100453}
454
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100455DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100456{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100457 return m_Devices.find(deviceUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100458}
459
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100460DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100461{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100462 return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
463 {
Jim Flynn6730fe92022-03-10 22:57:47 +0000464 ARM_PIPE_ASSERT(pair.second);
465 ARM_PIPE_ASSERT(pair.second->m_Uid == pair.first);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100466
467 return pair.second->m_Name == deviceName;
468 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100469}
470
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100471CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100472{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100473 return m_CounterSets.find(counterSetUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100474}
475
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100476CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100477{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100478 return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
479 {
Jim Flynn6730fe92022-03-10 22:57:47 +0000480 ARM_PIPE_ASSERT(pair.second);
481 ARM_PIPE_ASSERT(pair.second->m_Uid == pair.first);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100482
483 return pair.second->m_Name == counterSetName;
484 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100485}
486
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100487CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100488{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100489 return m_Counters.find(counterUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100490}
491
Matteo Martincigha84edee2019-10-02 12:50:57 +0100492CountersIt CounterDirectory::FindCounter(const std::string& counterName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100493{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100494 return std::find_if(m_Counters.begin(), m_Counters.end(), [&counterName](const auto& pair)
495 {
Jim Flynn6730fe92022-03-10 22:57:47 +0000496 ARM_PIPE_ASSERT(pair.second);
497 ARM_PIPE_ASSERT(pair.first >= pair.second->m_Uid && pair.first <= pair.second->m_MaxCounterUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100498
Matteo Martincigha84edee2019-10-02 12:50:57 +0100499 return pair.second->m_Name == counterName;
500 });
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100501}
502
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000503uint16_t CounterDirectory::GetNumberOfCores(const armnn::Optional<uint16_t>& numberOfCores,
Sadik Armagan4c998992020-02-25 12:44:44 +0000504 uint16_t deviceUid)
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100505{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100506 // To get the number of cores, apply the following rules:
507 //
508 // 1. If numberOfCores is set then take it as the deviceCores value
509 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
510 // if so then that devices number of cores is taken as the deviceCores value
Sadik Armagan4c998992020-02-25 12:44:44 +0000511 // 3. If none of the above holds then set deviceCores to zero
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100512
513 // 1. If numberOfCores is set then take it as the deviceCores value
514 if (numberOfCores.has_value())
515 {
516 // Get the number of cores
517 return numberOfCores.value();
518 }
519
520 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
521 // if so then that devices number of cores is taken as the deviceCores value
522 if (deviceUid > 0)
523 {
524 // Check that the (optional) device is already registered
525 auto deviceIt = FindDevice(deviceUid);
526 if (deviceIt == m_Devices.end())
527 {
Jim Flynnf9db3ef2022-03-08 21:23:44 +0000528 throw arm::pipe::InvalidArgumentException(
529 fmt::format("Trying to connect a counter to a device that is not registered (device UID {})",
530 deviceUid));
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100531 }
532
533 // Get the associated device
534 const DevicePtr& device = deviceIt->second;
Jim Flynn6730fe92022-03-10 22:57:47 +0000535 ARM_PIPE_ASSERT(device);
536
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100537
538 // Get the number of cores of the associated device
539 return device->m_Cores;
540 }
541
Sadik Armagan4c998992020-02-25 12:44:44 +0000542 // 3. If none of the above holds then set deviceCores to zero
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100543 return 0;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100544}
545
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000546} // namespace pipe
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100547
Cathal Corbett5aa9fd72022-02-25 15:33:28 +0000548} // namespace arm