blob: 6b2a945c9c1fe6e07b96cc873b237c48d702aac1 [file] [log] [blame]
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// 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>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010010#include <armnn/Conversion.hpp>
11
Derek Lambertif143fba2020-01-02 13:50:57 +000012#include <boost/core/ignore_unused.hpp>
Matteo Martincigh6db5f202019-09-05 12:02:04 +010013#include <boost/format.hpp>
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010014
15namespace armnn
16{
17
18namespace profiling
19{
20
Matteo Martincigh6db5f202019-09-05 12:02:04 +010021const Category* CounterDirectory::RegisterCategory(const std::string& categoryName,
22 const Optional<uint16_t>& deviceUid,
23 const Optional<uint16_t>& counterSetUid)
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() ||
27 !IsValidSwTraceString<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 // Check that a device with the given (optional) UID is already registered
41 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
42 if (deviceUidValue > 0)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010043 {
Matteo Martincigh6db5f202019-09-05 12:02:04 +010044 // Check that the (optional) device is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010045 if (!IsDeviceRegistered(deviceUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010046 {
47 throw InvalidArgumentException(
48 boost::str(boost::format("Trying to connect a category (\"%1%\") to a device that is "
49 "not registered (UID %2%)")
50 % categoryName
51 % deviceUidValue));
52 }
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010053 }
Matteo Martincigh6db5f202019-09-05 12:02:04 +010054
55 // Check that a counter set with the given (optional) UID is already registered
56 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
57 if (counterSetUidValue > 0)
58 {
59 // Check that the (optional) counter set is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010060 if (!IsCounterSetRegistered(counterSetUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010061 {
62 throw InvalidArgumentException(
63 boost::str(boost::format("Trying to connect a category (name: \"%1%\") to a counter set "
64 "that is not registered (UID: %2%)")
65 % categoryName
66 % counterSetUidValue));
67 }
68 }
69
70 // Create the category
71 CategoryPtr category = std::make_unique<Category>(categoryName, deviceUidValue, counterSetUidValue);
72 BOOST_ASSERT(category);
73
74 // Get the raw category pointer
75 const Category* categoryPtr = category.get();
76 BOOST_ASSERT(categoryPtr);
77
78 // Register the category
79 m_Categories.insert(std::move(category));
80
81 return categoryPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010082}
83
Matteo Martincigh6db5f202019-09-05 12:02:04 +010084const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
85 uint16_t cores,
86 const Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010087{
Matteo Martincigh6db5f202019-09-05 12:02:04 +010088 // Check that the given device name is valid
89 if (deviceName.empty() ||
90 !IsValidSwTraceString<SwTraceCharPolicy>(deviceName))
91 {
92 throw InvalidArgumentException("Trying to register a device with an invalid name");
93 }
94
95 // Check that a device with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010096 if (IsDeviceRegistered(deviceName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010097 {
98 throw InvalidArgumentException(
99 boost::str(boost::format("Trying to register a device already registered (\"%1%\")")
100 % deviceName));
101 }
102
103 // 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
104 // the registration fails. We'll get a proper one once we're sure that the device can be registered
105 uint16_t deviceUidPeek = GetNextUid(true);
106
107 // Check that a category with the given (optional) parent category name is already registered
108 Category* parentCategoryPtr = nullptr;
109 if (parentCategoryName.has_value())
110 {
111 // Get the (optional) parent category name
112 const std::string& parentCategoryNameValue = parentCategoryName.value();
113 if (parentCategoryNameValue.empty())
114 {
115 throw InvalidArgumentException(
116 boost::str(boost::format("Trying to connect a device (name: \"%1%\") to an invalid "
117 "parent category (name: \"%2%\")")
118 % deviceName
119 % parentCategoryNameValue));
120 }
121
122 // Check that the given parent category is already registered
123 auto categoryIt = FindCategory(parentCategoryNameValue);
124 if (categoryIt == m_Categories.end())
125 {
126 throw InvalidArgumentException(
127 boost::str(boost::format("Trying to connect a device (name: \"%1%\") to a parent category that "
128 "is not registered (name: \"%2%\")")
129 % deviceName
130 % parentCategoryNameValue));
131 }
132
133 // Get the parent category
134 const CategoryPtr& parentCategory = *categoryIt;
135 BOOST_ASSERT(parentCategory);
136
137 // Check that the given parent category is not already connected to another device
138 if (parentCategory->m_DeviceUid != 0 && parentCategory->m_DeviceUid != deviceUidPeek)
139 {
140 throw InvalidArgumentException(
141 boost::str(boost::format("Trying to connect a device (UID: %1%) to a parent category that is "
142 "already connected to a different device "
143 "(category \"%2%\" connected to device %3%)")
144 % deviceUidPeek
145 % parentCategoryNameValue
146 % parentCategory->m_DeviceUid));
147 }
148
149 // The parent category can be associated to the device that is about to be registered.
150 // Get the raw pointer to the parent category (to be used later when the device is actually been
151 // registered, to make sure that the category is associated to an existing device)
152 parentCategoryPtr = parentCategory.get();
153 }
154
155 // Get the device UID
156 uint16_t deviceUid = GetNextUid();
157 BOOST_ASSERT(deviceUid == deviceUidPeek);
158
159 // Create the device
160 DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
161 BOOST_ASSERT(device);
162
163 // Get the raw device pointer
164 const Device* devicePtr = device.get();
165 BOOST_ASSERT(devicePtr);
166
167 // Register the device
168 m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
169
170 // Connect the device to the parent category, if required
171 if (parentCategoryPtr)
172 {
173 // Set the device UID in the parent category
174 parentCategoryPtr->m_DeviceUid = deviceUid;
175 }
176
177 return devicePtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100178}
179
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100180const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
181 uint16_t count,
182 const Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100183{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100184 // Check that the given counter set name is valid
185 if (counterSetName.empty() ||
186 !IsValidSwTraceString<SwTraceNameCharPolicy>(counterSetName))
187 {
188 throw InvalidArgumentException("Trying to register a counter set with an invalid name");
189 }
190
191 // Check that a counter set with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100192 if (IsCounterSetRegistered(counterSetName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100193 {
194 throw InvalidArgumentException(
195 boost::str(boost::format("Trying to register a counter set already registered (\"%1%\")")
196 % counterSetName));
197 }
198
199 // 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
200 // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
201 uint16_t counterSetUidPeek = GetNextUid(true);
202
203 // Check that a category with the given (optional) parent category name is already registered
204 Category* parentCategoryPtr = nullptr;
205 if (parentCategoryName.has_value())
206 {
207 // Get the (optional) parent category name
208 const std::string& parentCategoryNameValue = parentCategoryName.value();
209 if (parentCategoryNameValue.empty())
210 {
211 throw InvalidArgumentException(
212 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to an invalid "
213 "parent category (name: \"%2%\")")
214 % counterSetUidPeek
215 % parentCategoryNameValue));
216 }
217
218 // Check that the given parent category is already registered
219 auto it = FindCategory(parentCategoryNameValue);
220 if (it == m_Categories.end())
221 {
222 throw InvalidArgumentException(
223 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
224 "that is not registered (name: \"%2%\")")
225 % counterSetUidPeek
226 % parentCategoryNameValue));
227 }
228
229 // Get the parent category
230 const CategoryPtr& parentCategory = *it;
231 BOOST_ASSERT(parentCategory);
232
233 // Check that the given parent category is not already connected to another counter set
234 if (parentCategory->m_CounterSetUid != 0 && parentCategory->m_CounterSetUid != counterSetUidPeek)
235 {
236 throw InvalidArgumentException(
237 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
238 "that is already connected to a different counter set "
239 "(category \"%2%\" connected to counter set %3%)")
240 % counterSetUidPeek
241 % parentCategoryNameValue
242 % parentCategory->m_CounterSetUid));
243 }
244
245 // The parent category can be associated to the counter set that is about to be registered.
246 // Get the raw pointer to the parent category (to be used later when the counter set is actually been
247 // registered, to make sure that the category is associated to an existing counter set)
248 parentCategoryPtr = parentCategory.get();
249 }
250
251 // Get the counter set UID
252 uint16_t counterSetUid = GetNextUid();
253 BOOST_ASSERT(counterSetUid == counterSetUidPeek);
254
255 // Create the counter set
256 CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
257 BOOST_ASSERT(counterSet);
258
259 // Get the raw counter set pointer
260 const CounterSet* counterSetPtr = counterSet.get();
261 BOOST_ASSERT(counterSetPtr);
262
263 // Register the counter set
264 m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
265
266 // Connect the counter set to the parent category, if required
267 if (parentCategoryPtr)
268 {
269 // Set the counter set UID in the parent category
270 parentCategoryPtr->m_CounterSetUid = counterSetUid;
271 }
272
273 return counterSetPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100274}
275
Keith Davise394bd92019-12-02 15:12:19 +0000276const Counter* CounterDirectory::RegisterCounter(const BackendId& backendId,
277 const uint16_t uid,
278 const std::string& parentCategoryName,
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100279 uint16_t counterClass,
280 uint16_t interpolation,
281 double multiplier,
282 const std::string& name,
283 const std::string& description,
284 const Optional<std::string>& units,
285 const Optional<uint16_t>& numberOfCores,
286 const Optional<uint16_t>& deviceUid,
287 const Optional<uint16_t>& counterSetUid)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100288{
Derek Lambertif143fba2020-01-02 13:50:57 +0000289 boost::ignore_unused(backendId);
290
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100291 // Check that the given parent category name is valid
292 if (parentCategoryName.empty() ||
293 !IsValidSwTraceString<SwTraceNameCharPolicy>(parentCategoryName))
294 {
295 throw InvalidArgumentException("Trying to register a counter with an invalid parent category name");
296 }
297
298 // Check that the given class is valid
299 if (counterClass != 0 && counterClass != 1)
300 {
301 throw InvalidArgumentException("Trying to register a counter with an invalid class");
302 }
303
304 // Check that the given interpolation is valid
305 if (interpolation != 0 && interpolation != 1)
306 {
307 throw InvalidArgumentException("Trying to register a counter with an invalid interpolation");
308 }
309
310 // Check that the given multiplier is valid
311 if (multiplier == .0f)
312 {
313 throw InvalidArgumentException("Trying to register a counter with an invalid multiplier");
314 }
315
316 // Check that the given name is valid
317 if (name.empty() ||
318 !IsValidSwTraceString<SwTraceCharPolicy>(name))
319 {
320 throw InvalidArgumentException("Trying to register a counter with an invalid name");
321 }
322
323 // Check that the given description is valid
324 if (description.empty() ||
325 !IsValidSwTraceString<SwTraceCharPolicy>(description))
326 {
327 throw InvalidArgumentException("Trying to register a counter with an invalid description");
328 }
329
330 // Check that the given units are valid
331 if (units.has_value()
332 && !IsValidSwTraceString<SwTraceNameCharPolicy>(units.value()))
333 {
334 throw InvalidArgumentException("Trying to register a counter with a invalid units");
335 }
336
337 // Check that the given parent category is registered
338 auto categoryIt = FindCategory(parentCategoryName);
339 if (categoryIt == m_Categories.end())
340 {
341 throw InvalidArgumentException(
342 boost::str(boost::format("Trying to connect a counter to a category "
343 "that is not registered (name: \"%1%\")")
344 % parentCategoryName));
345 }
346
347 // Get the parent category
348 const CategoryPtr& parentCategory = *categoryIt;
349 BOOST_ASSERT(parentCategory);
350
351 // Check that a counter with the given name is not already registered within the parent category
352 const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
353 for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
354 {
355 const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
356 BOOST_ASSERT(parentCategoryCounter);
357
358 if (parentCategoryCounter->m_Name == name)
359 {
360 throw InvalidArgumentException(
361 boost::str(boost::format("Trying to register a counter to category \"%1%\" with a name that "
362 "is already used within that category (name: \"%2%\")")
363 % parentCategoryName
364 % name));
365 }
366 }
367
368 // Check that a counter set with the given (optional) UID is already registered
369 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
370 if (counterSetUidValue > 0)
371 {
372 // Check that the (optional) counter set is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100373 if (!IsCounterSetRegistered(counterSetUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100374 {
375 throw InvalidArgumentException(
376 boost::str(boost::format("Trying to connect a counter to a counter set that is "
377 "not registered (counter set UID: %1%)")
378 % counterSetUidValue));
379 }
380 }
381
382 // Get the number of cores (this call may throw)
383 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
384 uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue, parentCategory);
385
386 // Get the counter UIDs and calculate the max counter UID
Keith Davise394bd92019-12-02 15:12:19 +0000387 std::vector<uint16_t> counterUids = GetNextCounterUids(uid, deviceCores);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100388 BOOST_ASSERT(!counterUids.empty());
389 uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
390
391 // Get the counter units
392 const std::string unitsValue = units.has_value() ? units.value() : "";
393
394 // Create the counter
Keith Davise394bd92019-12-02 15:12:19 +0000395 CounterPtr counter = std::make_shared<Counter>(armnn::profiling::BACKEND_ID,
396 counterUids.front(),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100397 maxCounterUid,
398 counterClass,
399 interpolation,
400 multiplier,
401 name,
402 description,
403 unitsValue,
404 deviceUidValue,
405 counterSetUidValue);
406 BOOST_ASSERT(counter);
407
408 // Get the raw counter pointer
409 const Counter* counterPtr = counter.get();
410 BOOST_ASSERT(counterPtr);
411
412 // Process multiple counters if necessary
413 for (uint16_t counterUid : counterUids)
414 {
415 // Connect the counter to the parent category
416 parentCategory->m_Counters.push_back(counterUid);
417
418 // Register the counter
419 m_Counters.insert(std::make_pair(counterUid, counter));
420 }
421
422 return counterPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100423}
424
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100425const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100426{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100427 auto it = FindCategory(categoryName);
428 if (it == m_Categories.end())
429 {
430 return nullptr;
431 }
432
433 const Category* category = it->get();
434 BOOST_ASSERT(category);
435
436 return category;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100437}
438
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100439const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100440{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100441 auto it = FindDevice(deviceUid);
442 if (it == m_Devices.end())
443 {
444 return nullptr;
445 }
446
447 const Device* device = it->second.get();
448 BOOST_ASSERT(device);
449 BOOST_ASSERT(device->m_Uid == deviceUid);
450
451 return device;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100452}
453
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100454const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100455{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100456 auto it = FindCounterSet(counterSetUid);
457 if (it == m_CounterSets.end())
458 {
459 return nullptr;
460 }
461
462 const CounterSet* counterSet = it->second.get();
463 BOOST_ASSERT(counterSet);
464 BOOST_ASSERT(counterSet->m_Uid == counterSetUid);
465
466 return counterSet;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100467}
468
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100469const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100470{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100471 auto it = FindCounter(counterUid);
472 if (it == m_Counters.end())
473 {
474 return nullptr;
475 }
476
477 const Counter* counter = it->second.get();
478 BOOST_ASSERT(counter);
479 BOOST_ASSERT(counter->m_Uid <= counterUid);
480 BOOST_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
481
482 return counter;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100483}
484
Matteo Martincigha84edee2019-10-02 12:50:57 +0100485bool CounterDirectory::IsCategoryRegistered(const std::string& categoryName) const
486{
487 auto it = FindCategory(categoryName);
488
489 return it != m_Categories.end();
490}
491
492bool CounterDirectory::IsDeviceRegistered(uint16_t deviceUid) const
493{
494 auto it = FindDevice(deviceUid);
495
496 return it != m_Devices.end();
497}
498
499bool CounterDirectory::IsDeviceRegistered(const std::string& deviceName) const
500{
501 auto it = FindDevice(deviceName);
502
503 return it != m_Devices.end();
504}
505
506bool CounterDirectory::IsCounterSetRegistered(uint16_t counterSetUid) const
507{
508 auto it = FindCounterSet(counterSetUid);
509
510 return it != m_CounterSets.end();
511}
512
513bool CounterDirectory::IsCounterSetRegistered(const std::string& counterSetName) const
514{
515 auto it = FindCounterSet(counterSetName);
516
517 return it != m_CounterSets.end();
518}
519
520bool CounterDirectory::IsCounterRegistered(uint16_t counterUid) const
521{
522 auto it = FindCounter(counterUid);
523
524 return it != m_Counters.end();
525}
526
527bool CounterDirectory::IsCounterRegistered(const std::string& counterName) const
528{
529 auto it = FindCounter(counterName);
530
531 return it != m_Counters.end();
532}
533
534void CounterDirectory::Clear()
535{
536 // Clear all the counter directory contents
537 m_Categories.clear();
538 m_Devices.clear();
539 m_CounterSets.clear();
540 m_Counters.clear();
541}
542
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100543CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100544{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100545 return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
546 {
547 BOOST_ASSERT(category);
548
549 return category->m_Name == categoryName;
550 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100551}
552
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100553DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100554{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100555 return m_Devices.find(deviceUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100556}
557
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100558DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100559{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100560 return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
561 {
562 BOOST_ASSERT(pair.second);
563 BOOST_ASSERT(pair.second->m_Uid == pair.first);
564
565 return pair.second->m_Name == deviceName;
566 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100567}
568
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100569CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100570{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100571 return m_CounterSets.find(counterSetUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100572}
573
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100574CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100575{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100576 return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
577 {
578 BOOST_ASSERT(pair.second);
579 BOOST_ASSERT(pair.second->m_Uid == pair.first);
580
581 return pair.second->m_Name == counterSetName;
582 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100583}
584
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100585CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100586{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100587 return m_Counters.find(counterUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100588}
589
Matteo Martincigha84edee2019-10-02 12:50:57 +0100590CountersIt CounterDirectory::FindCounter(const std::string& counterName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100591{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100592 return std::find_if(m_Counters.begin(), m_Counters.end(), [&counterName](const auto& pair)
593 {
594 BOOST_ASSERT(pair.second);
595 BOOST_ASSERT(pair.second->m_Uid == pair.first);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100596
Matteo Martincigha84edee2019-10-02 12:50:57 +0100597 return pair.second->m_Name == counterName;
598 });
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100599}
600
601uint16_t CounterDirectory::GetNumberOfCores(const Optional<uint16_t>& numberOfCores,
602 uint16_t deviceUid,
603 const CategoryPtr& parentCategory)
604{
605 BOOST_ASSERT(parentCategory);
606
607 // To get the number of cores, apply the following rules:
608 //
609 // 1. If numberOfCores is set then take it as the deviceCores value
610 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
611 // if so then that devices number of cores is taken as the deviceCores value
612 // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
613 // if it does then take that device's numberOfCores as the deviceCores value
614 // 4. If none of the above holds then set deviceCores to zero
615
616 // 1. If numberOfCores is set then take it as the deviceCores value
617 if (numberOfCores.has_value())
618 {
619 // Get the number of cores
620 return numberOfCores.value();
621 }
622
623 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
624 // if so then that devices number of cores is taken as the deviceCores value
625 if (deviceUid > 0)
626 {
627 // Check that the (optional) device is already registered
628 auto deviceIt = FindDevice(deviceUid);
629 if (deviceIt == m_Devices.end())
630 {
631 throw InvalidArgumentException(
632 boost::str(boost::format("Trying to connect a counter to a device that is "
633 "not registered (device UID %1%)")
634 % deviceUid));
635 }
636
637 // Get the associated device
638 const DevicePtr& device = deviceIt->second;
639 BOOST_ASSERT(device);
640
641 // Get the number of cores of the associated device
642 return device->m_Cores;
643 }
644
645 // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
646 // if it does then take that device's numberOfCores as the deviceCores value
647 uint16_t parentCategoryDeviceUid = parentCategory->m_DeviceUid;
648 if (parentCategoryDeviceUid > 0)
649 {
650 // Check that the device associated to the parent category is already registered
651 auto deviceIt = FindDevice(parentCategoryDeviceUid);
652 if (deviceIt == m_Devices.end())
653 {
654 throw InvalidArgumentException(
655 boost::str(boost::format("Trying to get the number of cores from a device that is "
656 "not registered (device UID %1%)")
657 % parentCategoryDeviceUid));
658 }
659
660 // Get the associated device
661 const DevicePtr& device = deviceIt->second;
662 BOOST_ASSERT(device);
663
664 // Get the number of cores of the device associated to the parent category
665 return device->m_Cores;
666 }
667
668 // 4. If none of the above holds then set deviceCores to zero
669 return 0;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100670}
671
672} // namespace profiling
673
674} // namespace armnn