blob: e6356b82bd7048a6e938b08fbfb59a2c205014ed [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
9#include <armnn/Exceptions.hpp>
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010010#include <armnn/utility/Assert.hpp>
Jan Eilers8eb25602020-03-09 12:13:48 +000011#include <armnn/utility/IgnoreUnused.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010012
Jim Flynnbbfe6032020-07-20 16:57:44 +010013#include <common/include/SwTrace.hpp>
14
Matteo Martincigh6db5f202019-09-05 12:02:04 +010015#include <boost/format.hpp>
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010016
17namespace armnn
18{
19
20namespace profiling
21{
22
Sadik Armagan4c998992020-02-25 12:44:44 +000023const Category* CounterDirectory::RegisterCategory(const std::string& categoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010024{
Matteo Martincigh6db5f202019-09-05 12:02:04 +010025 // Check that the given category name is valid
26 if (categoryName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +010027 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(categoryName))
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010028 {
Matteo Martincigh6db5f202019-09-05 12:02:04 +010029 throw InvalidArgumentException("Trying to register a category with an invalid name");
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010030 }
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010031
Matteo Martincigh6db5f202019-09-05 12:02:04 +010032 // Check that the given category is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010033 if (IsCategoryRegistered(categoryName))
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010034 {
Matteo Martincigh6db5f202019-09-05 12:02:04 +010035 throw InvalidArgumentException(
36 boost::str(boost::format("Trying to register a category already registered (\"%1%\")")
37 % categoryName));
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010038 }
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010039
Matteo Martincigh6db5f202019-09-05 12:02:04 +010040 // Create the category
Sadik Armagan4c998992020-02-25 12:44:44 +000041 CategoryPtr category = std::make_unique<Category>(categoryName);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010042 ARMNN_ASSERT(category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +010043
44 // Get the raw category pointer
45 const Category* categoryPtr = category.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010046 ARMNN_ASSERT(categoryPtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +010047
48 // Register the category
49 m_Categories.insert(std::move(category));
50
51 return categoryPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010052}
53
Matteo Martincigh6db5f202019-09-05 12:02:04 +010054const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
55 uint16_t cores,
56 const Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010057{
Matteo Martincigh6db5f202019-09-05 12:02:04 +010058 // Check that the given device name is valid
59 if (deviceName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +010060 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(deviceName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010061 {
62 throw InvalidArgumentException("Trying to register a device with an invalid name");
63 }
64
65 // Check that a device with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010066 if (IsDeviceRegistered(deviceName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010067 {
68 throw InvalidArgumentException(
69 boost::str(boost::format("Trying to register a device already registered (\"%1%\")")
70 % deviceName));
71 }
72
Matteo Martincigh6db5f202019-09-05 12:02:04 +010073 // Check that a category with the given (optional) parent category name is already registered
Matteo Martincigh6db5f202019-09-05 12:02:04 +010074 if (parentCategoryName.has_value())
75 {
76 // Get the (optional) parent category name
77 const std::string& parentCategoryNameValue = parentCategoryName.value();
78 if (parentCategoryNameValue.empty())
79 {
80 throw InvalidArgumentException(
81 boost::str(boost::format("Trying to connect a device (name: \"%1%\") to an invalid "
82 "parent category (name: \"%2%\")")
83 % deviceName
84 % parentCategoryNameValue));
85 }
86
87 // Check that the given parent category is already registered
88 auto categoryIt = FindCategory(parentCategoryNameValue);
89 if (categoryIt == m_Categories.end())
90 {
91 throw InvalidArgumentException(
92 boost::str(boost::format("Trying to connect a device (name: \"%1%\") to a parent category that "
93 "is not registered (name: \"%2%\")")
94 % deviceName
95 % parentCategoryNameValue));
96 }
Matteo Martincigh6db5f202019-09-05 12:02:04 +010097 }
98
99 // Get the device UID
100 uint16_t deviceUid = GetNextUid();
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100101
102 // Create the device
103 DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100104 ARMNN_ASSERT(device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100105
106 // Get the raw device pointer
107 const Device* devicePtr = device.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100108 ARMNN_ASSERT(devicePtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100109
110 // Register the device
111 m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
112
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100113 return devicePtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100114}
115
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100116const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
117 uint16_t count,
118 const Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100119{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100120 // Check that the given counter set name is valid
121 if (counterSetName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100122 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(counterSetName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100123 {
124 throw InvalidArgumentException("Trying to register a counter set with an invalid name");
125 }
126
127 // Check that a counter set with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100128 if (IsCounterSetRegistered(counterSetName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100129 {
130 throw InvalidArgumentException(
131 boost::str(boost::format("Trying to register a counter set already registered (\"%1%\")")
132 % counterSetName));
133 }
134
135 // 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
136 // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
137 uint16_t counterSetUidPeek = GetNextUid(true);
138
139 // Check that a category with the given (optional) parent category name is already registered
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100140 if (parentCategoryName.has_value())
141 {
142 // Get the (optional) parent category name
143 const std::string& parentCategoryNameValue = parentCategoryName.value();
144 if (parentCategoryNameValue.empty())
145 {
146 throw InvalidArgumentException(
147 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to an invalid "
148 "parent category (name: \"%2%\")")
149 % counterSetUidPeek
150 % parentCategoryNameValue));
151 }
152
153 // Check that the given parent category is already registered
154 auto it = FindCategory(parentCategoryNameValue);
155 if (it == m_Categories.end())
156 {
157 throw InvalidArgumentException(
158 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
159 "that is not registered (name: \"%2%\")")
160 % counterSetUidPeek
161 % parentCategoryNameValue));
162 }
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100163 }
164
165 // Get the counter set UID
166 uint16_t counterSetUid = GetNextUid();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100167 ARMNN_ASSERT(counterSetUid == counterSetUidPeek);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100168
169 // Create the counter set
170 CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100171 ARMNN_ASSERT(counterSet);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100172
173 // Get the raw counter set pointer
174 const CounterSet* counterSetPtr = counterSet.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100175 ARMNN_ASSERT(counterSetPtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100176
177 // Register the counter set
178 m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
179
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100180 return counterSetPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100181}
182
Keith Davise394bd92019-12-02 15:12:19 +0000183const Counter* CounterDirectory::RegisterCounter(const BackendId& backendId,
184 const uint16_t uid,
185 const std::string& parentCategoryName,
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100186 uint16_t counterClass,
187 uint16_t interpolation,
188 double multiplier,
189 const std::string& name,
190 const std::string& description,
191 const Optional<std::string>& units,
192 const Optional<uint16_t>& numberOfCores,
193 const Optional<uint16_t>& deviceUid,
194 const Optional<uint16_t>& counterSetUid)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100195{
Jan Eilers8eb25602020-03-09 12:13:48 +0000196 IgnoreUnused(backendId);
Derek Lambertif143fba2020-01-02 13:50:57 +0000197
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100198 // Check that the given parent category name is valid
199 if (parentCategoryName.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100200 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(parentCategoryName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100201 {
202 throw InvalidArgumentException("Trying to register a counter with an invalid parent category name");
203 }
204
205 // Check that the given class is valid
206 if (counterClass != 0 && counterClass != 1)
207 {
208 throw InvalidArgumentException("Trying to register a counter with an invalid class");
209 }
210
211 // Check that the given interpolation is valid
212 if (interpolation != 0 && interpolation != 1)
213 {
214 throw InvalidArgumentException("Trying to register a counter with an invalid interpolation");
215 }
216
217 // Check that the given multiplier is valid
218 if (multiplier == .0f)
219 {
220 throw InvalidArgumentException("Trying to register a counter with an invalid multiplier");
221 }
222
223 // Check that the given name is valid
224 if (name.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100225 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(name))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100226 {
227 throw InvalidArgumentException("Trying to register a counter with an invalid name");
228 }
229
230 // Check that the given description is valid
231 if (description.empty() ||
Jim Flynnbbfe6032020-07-20 16:57:44 +0100232 !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceCharPolicy>(description))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100233 {
234 throw InvalidArgumentException("Trying to register a counter with an invalid description");
235 }
236
237 // Check that the given units are valid
238 if (units.has_value()
Jim Flynnbbfe6032020-07-20 16:57:44 +0100239 && !arm::pipe::IsValidSwTraceString<arm::pipe::SwTraceNameCharPolicy>(units.value()))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100240 {
241 throw InvalidArgumentException("Trying to register a counter with a invalid units");
242 }
243
244 // Check that the given parent category is registered
245 auto categoryIt = FindCategory(parentCategoryName);
246 if (categoryIt == m_Categories.end())
247 {
248 throw InvalidArgumentException(
249 boost::str(boost::format("Trying to connect a counter to a category "
250 "that is not registered (name: \"%1%\")")
251 % parentCategoryName));
252 }
253
254 // Get the parent category
255 const CategoryPtr& parentCategory = *categoryIt;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100256 ARMNN_ASSERT(parentCategory);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100257
258 // Check that a counter with the given name is not already registered within the parent category
259 const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
260 for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
261 {
262 const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100263 ARMNN_ASSERT(parentCategoryCounter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100264
265 if (parentCategoryCounter->m_Name == name)
266 {
267 throw InvalidArgumentException(
268 boost::str(boost::format("Trying to register a counter to category \"%1%\" with a name that "
269 "is already used within that category (name: \"%2%\")")
270 % parentCategoryName
271 % name));
272 }
273 }
274
275 // Check that a counter set with the given (optional) UID is already registered
276 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
277 if (counterSetUidValue > 0)
278 {
279 // Check that the (optional) counter set is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100280 if (!IsCounterSetRegistered(counterSetUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100281 {
282 throw InvalidArgumentException(
283 boost::str(boost::format("Trying to connect a counter to a counter set that is "
284 "not registered (counter set UID: %1%)")
285 % counterSetUidValue));
286 }
287 }
288
289 // Get the number of cores (this call may throw)
290 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
Sadik Armagan4c998992020-02-25 12:44:44 +0000291 uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100292
293 // Get the counter UIDs and calculate the max counter UID
Keith Davise394bd92019-12-02 15:12:19 +0000294 std::vector<uint16_t> counterUids = GetNextCounterUids(uid, deviceCores);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100295 ARMNN_ASSERT(!counterUids.empty());
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100296 uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
297
298 // Get the counter units
299 const std::string unitsValue = units.has_value() ? units.value() : "";
300
301 // Create the counter
Keith Davise394bd92019-12-02 15:12:19 +0000302 CounterPtr counter = std::make_shared<Counter>(armnn::profiling::BACKEND_ID,
303 counterUids.front(),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100304 maxCounterUid,
305 counterClass,
306 interpolation,
307 multiplier,
308 name,
309 description,
310 unitsValue,
311 deviceUidValue,
312 counterSetUidValue);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100313 ARMNN_ASSERT(counter);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100314
315 // Get the raw counter pointer
316 const Counter* counterPtr = counter.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100317 ARMNN_ASSERT(counterPtr);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100318
319 // Process multiple counters if necessary
320 for (uint16_t counterUid : counterUids)
321 {
322 // Connect the counter to the parent category
323 parentCategory->m_Counters.push_back(counterUid);
324
325 // Register the counter
326 m_Counters.insert(std::make_pair(counterUid, counter));
327 }
328
329 return counterPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100330}
331
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100332const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100333{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100334 auto it = FindCategory(categoryName);
335 if (it == m_Categories.end())
336 {
337 return nullptr;
338 }
339
340 const Category* category = it->get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100341 ARMNN_ASSERT(category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100342
343 return category;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100344}
345
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100346const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100347{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100348 auto it = FindDevice(deviceUid);
349 if (it == m_Devices.end())
350 {
351 return nullptr;
352 }
353
354 const Device* device = it->second.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100355 ARMNN_ASSERT(device);
356 ARMNN_ASSERT(device->m_Uid == deviceUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100357
358 return device;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100359}
360
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100361const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100362{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100363 auto it = FindCounterSet(counterSetUid);
364 if (it == m_CounterSets.end())
365 {
366 return nullptr;
367 }
368
369 const CounterSet* counterSet = it->second.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100370 ARMNN_ASSERT(counterSet);
371 ARMNN_ASSERT(counterSet->m_Uid == counterSetUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100372
373 return counterSet;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100374}
375
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100376const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100377{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100378 auto it = FindCounter(counterUid);
379 if (it == m_Counters.end())
380 {
381 return nullptr;
382 }
383
384 const Counter* counter = it->second.get();
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100385 ARMNN_ASSERT(counter);
386 ARMNN_ASSERT(counter->m_Uid <= counterUid);
387 ARMNN_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100388
389 return counter;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100390}
391
Matteo Martincigha84edee2019-10-02 12:50:57 +0100392bool CounterDirectory::IsCategoryRegistered(const std::string& categoryName) const
393{
394 auto it = FindCategory(categoryName);
395
396 return it != m_Categories.end();
397}
398
399bool CounterDirectory::IsDeviceRegistered(uint16_t deviceUid) const
400{
401 auto it = FindDevice(deviceUid);
402
403 return it != m_Devices.end();
404}
405
406bool CounterDirectory::IsDeviceRegistered(const std::string& deviceName) const
407{
408 auto it = FindDevice(deviceName);
409
410 return it != m_Devices.end();
411}
412
413bool CounterDirectory::IsCounterSetRegistered(uint16_t counterSetUid) const
414{
415 auto it = FindCounterSet(counterSetUid);
416
417 return it != m_CounterSets.end();
418}
419
420bool CounterDirectory::IsCounterSetRegistered(const std::string& counterSetName) const
421{
422 auto it = FindCounterSet(counterSetName);
423
424 return it != m_CounterSets.end();
425}
426
427bool CounterDirectory::IsCounterRegistered(uint16_t counterUid) const
428{
429 auto it = FindCounter(counterUid);
430
431 return it != m_Counters.end();
432}
433
434bool CounterDirectory::IsCounterRegistered(const std::string& counterName) const
435{
436 auto it = FindCounter(counterName);
437
438 return it != m_Counters.end();
439}
440
441void CounterDirectory::Clear()
442{
443 // Clear all the counter directory contents
444 m_Categories.clear();
445 m_Devices.clear();
446 m_CounterSets.clear();
447 m_Counters.clear();
448}
449
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100450CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100451{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100452 return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
453 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100454 ARMNN_ASSERT(category);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100455
456 return category->m_Name == categoryName;
457 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100458}
459
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100460DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100461{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100462 return m_Devices.find(deviceUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100463}
464
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100465DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100466{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100467 return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
468 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100469 ARMNN_ASSERT(pair.second);
470 ARMNN_ASSERT(pair.second->m_Uid == pair.first);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100471
472 return pair.second->m_Name == deviceName;
473 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100474}
475
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100476CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100477{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100478 return m_CounterSets.find(counterSetUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100479}
480
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100481CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100482{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100483 return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
484 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100485 ARMNN_ASSERT(pair.second);
486 ARMNN_ASSERT(pair.second->m_Uid == pair.first);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100487
488 return pair.second->m_Name == counterSetName;
489 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100490}
491
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100492CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100493{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100494 return m_Counters.find(counterUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100495}
496
Matteo Martincigha84edee2019-10-02 12:50:57 +0100497CountersIt CounterDirectory::FindCounter(const std::string& counterName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100498{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100499 return std::find_if(m_Counters.begin(), m_Counters.end(), [&counterName](const auto& pair)
500 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100501 ARMNN_ASSERT(pair.second);
Finn Williamsfe5a24b2020-04-09 16:05:28 +0100502 ARMNN_ASSERT(pair.first >= pair.second->m_Uid && pair.first <= pair.second->m_MaxCounterUid);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100503
Matteo Martincigha84edee2019-10-02 12:50:57 +0100504 return pair.second->m_Name == counterName;
505 });
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100506}
507
508uint16_t CounterDirectory::GetNumberOfCores(const Optional<uint16_t>& numberOfCores,
Sadik Armagan4c998992020-02-25 12:44:44 +0000509 uint16_t deviceUid)
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100510{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100511 // To get the number of cores, apply the following rules:
512 //
513 // 1. If numberOfCores is set then take it as the deviceCores value
514 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
515 // if so then that devices number of cores is taken as the deviceCores value
Sadik Armagan4c998992020-02-25 12:44:44 +0000516 // 3. If none of the above holds then set deviceCores to zero
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100517
518 // 1. If numberOfCores is set then take it as the deviceCores value
519 if (numberOfCores.has_value())
520 {
521 // Get the number of cores
522 return numberOfCores.value();
523 }
524
525 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
526 // if so then that devices number of cores is taken as the deviceCores value
527 if (deviceUid > 0)
528 {
529 // Check that the (optional) device is already registered
530 auto deviceIt = FindDevice(deviceUid);
531 if (deviceIt == m_Devices.end())
532 {
533 throw InvalidArgumentException(
534 boost::str(boost::format("Trying to connect a counter to a device that is "
535 "not registered (device UID %1%)")
536 % deviceUid));
537 }
538
539 // Get the associated device
540 const DevicePtr& device = deviceIt->second;
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100541 ARMNN_ASSERT(device);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100542
543 // Get the number of cores of the associated device
544 return device->m_Cores;
545 }
546
Sadik Armagan4c998992020-02-25 12:44:44 +0000547 // 3. If none of the above holds then set deviceCores to zero
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100548 return 0;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100549}
550
551} // namespace profiling
552
553} // namespace armnn