blob: 5a69e1c8022c441396298252be4e4336cae2d431 [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
12#include <boost/format.hpp>
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010013
14namespace armnn
15{
16
17namespace profiling
18{
19
Matteo Martincigh6db5f202019-09-05 12:02:04 +010020const Category* CounterDirectory::RegisterCategory(const std::string& categoryName,
21 const Optional<uint16_t>& deviceUid,
22 const Optional<uint16_t>& counterSetUid)
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() ||
26 !IsValidSwTraceString<SwTraceNameCharPolicy>(categoryName))
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010027 {
Matteo Martincigh6db5f202019-09-05 12:02:04 +010028 throw 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 {
Matteo Martincigh6db5f202019-09-05 12:02:04 +010034 throw InvalidArgumentException(
35 boost::str(boost::format("Trying to register a category already registered (\"%1%\")")
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 // Check that a device with the given (optional) UID is already registered
40 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
41 if (deviceUidValue > 0)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010042 {
Matteo Martincigh6db5f202019-09-05 12:02:04 +010043 // Check that the (optional) device is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010044 if (!IsDeviceRegistered(deviceUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010045 {
46 throw InvalidArgumentException(
47 boost::str(boost::format("Trying to connect a category (\"%1%\") to a device that is "
48 "not registered (UID %2%)")
49 % categoryName
50 % deviceUidValue));
51 }
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010052 }
Matteo Martincigh6db5f202019-09-05 12:02:04 +010053
54 // Check that a counter set with the given (optional) UID is already registered
55 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
56 if (counterSetUidValue > 0)
57 {
58 // Check that the (optional) counter set is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010059 if (!IsCounterSetRegistered(counterSetUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010060 {
61 throw InvalidArgumentException(
62 boost::str(boost::format("Trying to connect a category (name: \"%1%\") to a counter set "
63 "that is not registered (UID: %2%)")
64 % categoryName
65 % counterSetUidValue));
66 }
67 }
68
69 // Create the category
70 CategoryPtr category = std::make_unique<Category>(categoryName, deviceUidValue, counterSetUidValue);
71 BOOST_ASSERT(category);
72
73 // Get the raw category pointer
74 const Category* categoryPtr = category.get();
75 BOOST_ASSERT(categoryPtr);
76
77 // Register the category
78 m_Categories.insert(std::move(category));
79
80 return categoryPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010081}
82
Matteo Martincigh6db5f202019-09-05 12:02:04 +010083const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
84 uint16_t cores,
85 const Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +010086{
Matteo Martincigh6db5f202019-09-05 12:02:04 +010087 // Check that the given device name is valid
88 if (deviceName.empty() ||
89 !IsValidSwTraceString<SwTraceCharPolicy>(deviceName))
90 {
91 throw InvalidArgumentException("Trying to register a device with an invalid name");
92 }
93
94 // Check that a device with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +010095 if (IsDeviceRegistered(deviceName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +010096 {
97 throw InvalidArgumentException(
98 boost::str(boost::format("Trying to register a device already registered (\"%1%\")")
99 % deviceName));
100 }
101
102 // 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
103 // the registration fails. We'll get a proper one once we're sure that the device can be registered
104 uint16_t deviceUidPeek = GetNextUid(true);
105
106 // Check that a category with the given (optional) parent category name is already registered
107 Category* parentCategoryPtr = nullptr;
108 if (parentCategoryName.has_value())
109 {
110 // Get the (optional) parent category name
111 const std::string& parentCategoryNameValue = parentCategoryName.value();
112 if (parentCategoryNameValue.empty())
113 {
114 throw InvalidArgumentException(
115 boost::str(boost::format("Trying to connect a device (name: \"%1%\") to an invalid "
116 "parent category (name: \"%2%\")")
117 % deviceName
118 % parentCategoryNameValue));
119 }
120
121 // Check that the given parent category is already registered
122 auto categoryIt = FindCategory(parentCategoryNameValue);
123 if (categoryIt == m_Categories.end())
124 {
125 throw InvalidArgumentException(
126 boost::str(boost::format("Trying to connect a device (name: \"%1%\") to a parent category that "
127 "is not registered (name: \"%2%\")")
128 % deviceName
129 % parentCategoryNameValue));
130 }
131
132 // Get the parent category
133 const CategoryPtr& parentCategory = *categoryIt;
134 BOOST_ASSERT(parentCategory);
135
136 // Check that the given parent category is not already connected to another device
137 if (parentCategory->m_DeviceUid != 0 && parentCategory->m_DeviceUid != deviceUidPeek)
138 {
139 throw InvalidArgumentException(
140 boost::str(boost::format("Trying to connect a device (UID: %1%) to a parent category that is "
141 "already connected to a different device "
142 "(category \"%2%\" connected to device %3%)")
143 % deviceUidPeek
144 % parentCategoryNameValue
145 % parentCategory->m_DeviceUid));
146 }
147
148 // The parent category can be associated to the device that is about to be registered.
149 // Get the raw pointer to the parent category (to be used later when the device is actually been
150 // registered, to make sure that the category is associated to an existing device)
151 parentCategoryPtr = parentCategory.get();
152 }
153
154 // Get the device UID
155 uint16_t deviceUid = GetNextUid();
156 BOOST_ASSERT(deviceUid == deviceUidPeek);
157
158 // Create the device
159 DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
160 BOOST_ASSERT(device);
161
162 // Get the raw device pointer
163 const Device* devicePtr = device.get();
164 BOOST_ASSERT(devicePtr);
165
166 // Register the device
167 m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
168
169 // Connect the device to the parent category, if required
170 if (parentCategoryPtr)
171 {
172 // Set the device UID in the parent category
173 parentCategoryPtr->m_DeviceUid = deviceUid;
174 }
175
176 return devicePtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100177}
178
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100179const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
180 uint16_t count,
181 const Optional<std::string>& parentCategoryName)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100182{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100183 // Check that the given counter set name is valid
184 if (counterSetName.empty() ||
185 !IsValidSwTraceString<SwTraceNameCharPolicy>(counterSetName))
186 {
187 throw InvalidArgumentException("Trying to register a counter set with an invalid name");
188 }
189
190 // Check that a counter set with the given name is not already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100191 if (IsCounterSetRegistered(counterSetName))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100192 {
193 throw InvalidArgumentException(
194 boost::str(boost::format("Trying to register a counter set already registered (\"%1%\")")
195 % counterSetName));
196 }
197
198 // 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
199 // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
200 uint16_t counterSetUidPeek = GetNextUid(true);
201
202 // Check that a category with the given (optional) parent category name is already registered
203 Category* parentCategoryPtr = nullptr;
204 if (parentCategoryName.has_value())
205 {
206 // Get the (optional) parent category name
207 const std::string& parentCategoryNameValue = parentCategoryName.value();
208 if (parentCategoryNameValue.empty())
209 {
210 throw InvalidArgumentException(
211 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to an invalid "
212 "parent category (name: \"%2%\")")
213 % counterSetUidPeek
214 % parentCategoryNameValue));
215 }
216
217 // Check that the given parent category is already registered
218 auto it = FindCategory(parentCategoryNameValue);
219 if (it == m_Categories.end())
220 {
221 throw InvalidArgumentException(
222 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
223 "that is not registered (name: \"%2%\")")
224 % counterSetUidPeek
225 % parentCategoryNameValue));
226 }
227
228 // Get the parent category
229 const CategoryPtr& parentCategory = *it;
230 BOOST_ASSERT(parentCategory);
231
232 // Check that the given parent category is not already connected to another counter set
233 if (parentCategory->m_CounterSetUid != 0 && parentCategory->m_CounterSetUid != counterSetUidPeek)
234 {
235 throw InvalidArgumentException(
236 boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
237 "that is already connected to a different counter set "
238 "(category \"%2%\" connected to counter set %3%)")
239 % counterSetUidPeek
240 % parentCategoryNameValue
241 % parentCategory->m_CounterSetUid));
242 }
243
244 // The parent category can be associated to the counter set that is about to be registered.
245 // Get the raw pointer to the parent category (to be used later when the counter set is actually been
246 // registered, to make sure that the category is associated to an existing counter set)
247 parentCategoryPtr = parentCategory.get();
248 }
249
250 // Get the counter set UID
251 uint16_t counterSetUid = GetNextUid();
252 BOOST_ASSERT(counterSetUid == counterSetUidPeek);
253
254 // Create the counter set
255 CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
256 BOOST_ASSERT(counterSet);
257
258 // Get the raw counter set pointer
259 const CounterSet* counterSetPtr = counterSet.get();
260 BOOST_ASSERT(counterSetPtr);
261
262 // Register the counter set
263 m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
264
265 // Connect the counter set to the parent category, if required
266 if (parentCategoryPtr)
267 {
268 // Set the counter set UID in the parent category
269 parentCategoryPtr->m_CounterSetUid = counterSetUid;
270 }
271
272 return counterSetPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100273}
274
Keith Davise394bd92019-12-02 15:12:19 +0000275const Counter* CounterDirectory::RegisterCounter(const BackendId& backendId,
276 const uint16_t uid,
277 const std::string& parentCategoryName,
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100278 uint16_t counterClass,
279 uint16_t interpolation,
280 double multiplier,
281 const std::string& name,
282 const std::string& description,
283 const Optional<std::string>& units,
284 const Optional<uint16_t>& numberOfCores,
285 const Optional<uint16_t>& deviceUid,
286 const Optional<uint16_t>& counterSetUid)
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100287{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100288 // Check that the given parent category name is valid
289 if (parentCategoryName.empty() ||
290 !IsValidSwTraceString<SwTraceNameCharPolicy>(parentCategoryName))
291 {
292 throw InvalidArgumentException("Trying to register a counter with an invalid parent category name");
293 }
294
295 // Check that the given class is valid
296 if (counterClass != 0 && counterClass != 1)
297 {
298 throw InvalidArgumentException("Trying to register a counter with an invalid class");
299 }
300
301 // Check that the given interpolation is valid
302 if (interpolation != 0 && interpolation != 1)
303 {
304 throw InvalidArgumentException("Trying to register a counter with an invalid interpolation");
305 }
306
307 // Check that the given multiplier is valid
308 if (multiplier == .0f)
309 {
310 throw InvalidArgumentException("Trying to register a counter with an invalid multiplier");
311 }
312
313 // Check that the given name is valid
314 if (name.empty() ||
315 !IsValidSwTraceString<SwTraceCharPolicy>(name))
316 {
317 throw InvalidArgumentException("Trying to register a counter with an invalid name");
318 }
319
320 // Check that the given description is valid
321 if (description.empty() ||
322 !IsValidSwTraceString<SwTraceCharPolicy>(description))
323 {
324 throw InvalidArgumentException("Trying to register a counter with an invalid description");
325 }
326
327 // Check that the given units are valid
328 if (units.has_value()
329 && !IsValidSwTraceString<SwTraceNameCharPolicy>(units.value()))
330 {
331 throw InvalidArgumentException("Trying to register a counter with a invalid units");
332 }
333
334 // Check that the given parent category is registered
335 auto categoryIt = FindCategory(parentCategoryName);
336 if (categoryIt == m_Categories.end())
337 {
338 throw InvalidArgumentException(
339 boost::str(boost::format("Trying to connect a counter to a category "
340 "that is not registered (name: \"%1%\")")
341 % parentCategoryName));
342 }
343
344 // Get the parent category
345 const CategoryPtr& parentCategory = *categoryIt;
346 BOOST_ASSERT(parentCategory);
347
348 // Check that a counter with the given name is not already registered within the parent category
349 const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
350 for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
351 {
352 const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
353 BOOST_ASSERT(parentCategoryCounter);
354
355 if (parentCategoryCounter->m_Name == name)
356 {
357 throw InvalidArgumentException(
358 boost::str(boost::format("Trying to register a counter to category \"%1%\" with a name that "
359 "is already used within that category (name: \"%2%\")")
360 % parentCategoryName
361 % name));
362 }
363 }
364
365 // Check that a counter set with the given (optional) UID is already registered
366 uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
367 if (counterSetUidValue > 0)
368 {
369 // Check that the (optional) counter set is already registered
Matteo Martincigha84edee2019-10-02 12:50:57 +0100370 if (!IsCounterSetRegistered(counterSetUidValue))
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100371 {
372 throw InvalidArgumentException(
373 boost::str(boost::format("Trying to connect a counter to a counter set that is "
374 "not registered (counter set UID: %1%)")
375 % counterSetUidValue));
376 }
377 }
378
379 // Get the number of cores (this call may throw)
380 uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
381 uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue, parentCategory);
382
383 // Get the counter UIDs and calculate the max counter UID
Keith Davise394bd92019-12-02 15:12:19 +0000384 std::vector<uint16_t> counterUids = GetNextCounterUids(uid, deviceCores);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100385 BOOST_ASSERT(!counterUids.empty());
386 uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
387
388 // Get the counter units
389 const std::string unitsValue = units.has_value() ? units.value() : "";
390
391 // Create the counter
Keith Davise394bd92019-12-02 15:12:19 +0000392 CounterPtr counter = std::make_shared<Counter>(armnn::profiling::BACKEND_ID,
393 counterUids.front(),
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100394 maxCounterUid,
395 counterClass,
396 interpolation,
397 multiplier,
398 name,
399 description,
400 unitsValue,
401 deviceUidValue,
402 counterSetUidValue);
403 BOOST_ASSERT(counter);
404
405 // Get the raw counter pointer
406 const Counter* counterPtr = counter.get();
407 BOOST_ASSERT(counterPtr);
408
409 // Process multiple counters if necessary
410 for (uint16_t counterUid : counterUids)
411 {
412 // Connect the counter to the parent category
413 parentCategory->m_Counters.push_back(counterUid);
414
415 // Register the counter
416 m_Counters.insert(std::make_pair(counterUid, counter));
417 }
418
419 return counterPtr;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100420}
421
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100422const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100423{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100424 auto it = FindCategory(categoryName);
425 if (it == m_Categories.end())
426 {
427 return nullptr;
428 }
429
430 const Category* category = it->get();
431 BOOST_ASSERT(category);
432
433 return category;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100434}
435
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100436const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100437{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100438 auto it = FindDevice(deviceUid);
439 if (it == m_Devices.end())
440 {
441 return nullptr;
442 }
443
444 const Device* device = it->second.get();
445 BOOST_ASSERT(device);
446 BOOST_ASSERT(device->m_Uid == deviceUid);
447
448 return device;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100449}
450
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100451const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100452{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100453 auto it = FindCounterSet(counterSetUid);
454 if (it == m_CounterSets.end())
455 {
456 return nullptr;
457 }
458
459 const CounterSet* counterSet = it->second.get();
460 BOOST_ASSERT(counterSet);
461 BOOST_ASSERT(counterSet->m_Uid == counterSetUid);
462
463 return counterSet;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100464}
465
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100466const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100467{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100468 auto it = FindCounter(counterUid);
469 if (it == m_Counters.end())
470 {
471 return nullptr;
472 }
473
474 const Counter* counter = it->second.get();
475 BOOST_ASSERT(counter);
476 BOOST_ASSERT(counter->m_Uid <= counterUid);
477 BOOST_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
478
479 return counter;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100480}
481
Matteo Martincigha84edee2019-10-02 12:50:57 +0100482bool CounterDirectory::IsCategoryRegistered(const std::string& categoryName) const
483{
484 auto it = FindCategory(categoryName);
485
486 return it != m_Categories.end();
487}
488
489bool CounterDirectory::IsDeviceRegistered(uint16_t deviceUid) const
490{
491 auto it = FindDevice(deviceUid);
492
493 return it != m_Devices.end();
494}
495
496bool CounterDirectory::IsDeviceRegistered(const std::string& deviceName) const
497{
498 auto it = FindDevice(deviceName);
499
500 return it != m_Devices.end();
501}
502
503bool CounterDirectory::IsCounterSetRegistered(uint16_t counterSetUid) const
504{
505 auto it = FindCounterSet(counterSetUid);
506
507 return it != m_CounterSets.end();
508}
509
510bool CounterDirectory::IsCounterSetRegistered(const std::string& counterSetName) const
511{
512 auto it = FindCounterSet(counterSetName);
513
514 return it != m_CounterSets.end();
515}
516
517bool CounterDirectory::IsCounterRegistered(uint16_t counterUid) const
518{
519 auto it = FindCounter(counterUid);
520
521 return it != m_Counters.end();
522}
523
524bool CounterDirectory::IsCounterRegistered(const std::string& counterName) const
525{
526 auto it = FindCounter(counterName);
527
528 return it != m_Counters.end();
529}
530
531void CounterDirectory::Clear()
532{
533 // Clear all the counter directory contents
534 m_Categories.clear();
535 m_Devices.clear();
536 m_CounterSets.clear();
537 m_Counters.clear();
538}
539
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100540CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100541{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100542 return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
543 {
544 BOOST_ASSERT(category);
545
546 return category->m_Name == categoryName;
547 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100548}
549
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100550DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100551{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100552 return m_Devices.find(deviceUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100553}
554
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100555DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100556{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100557 return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
558 {
559 BOOST_ASSERT(pair.second);
560 BOOST_ASSERT(pair.second->m_Uid == pair.first);
561
562 return pair.second->m_Name == deviceName;
563 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100564}
565
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100566CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100567{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100568 return m_CounterSets.find(counterSetUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100569}
570
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100571CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100572{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100573 return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
574 {
575 BOOST_ASSERT(pair.second);
576 BOOST_ASSERT(pair.second->m_Uid == pair.first);
577
578 return pair.second->m_Name == counterSetName;
579 });
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100580}
581
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100582CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100583{
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100584 return m_Counters.find(counterUid);
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100585}
586
Matteo Martincigha84edee2019-10-02 12:50:57 +0100587CountersIt CounterDirectory::FindCounter(const std::string& counterName) const
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100588{
Matteo Martincigha84edee2019-10-02 12:50:57 +0100589 return std::find_if(m_Counters.begin(), m_Counters.end(), [&counterName](const auto& pair)
590 {
591 BOOST_ASSERT(pair.second);
592 BOOST_ASSERT(pair.second->m_Uid == pair.first);
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100593
Matteo Martincigha84edee2019-10-02 12:50:57 +0100594 return pair.second->m_Name == counterName;
595 });
Matteo Martincigh6db5f202019-09-05 12:02:04 +0100596}
597
598uint16_t CounterDirectory::GetNumberOfCores(const Optional<uint16_t>& numberOfCores,
599 uint16_t deviceUid,
600 const CategoryPtr& parentCategory)
601{
602 BOOST_ASSERT(parentCategory);
603
604 // To get the number of cores, apply the following rules:
605 //
606 // 1. If numberOfCores is set then take it as the deviceCores value
607 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
608 // if so then that devices number of cores is taken as the deviceCores value
609 // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
610 // if it does then take that device's numberOfCores as the deviceCores value
611 // 4. If none of the above holds then set deviceCores to zero
612
613 // 1. If numberOfCores is set then take it as the deviceCores value
614 if (numberOfCores.has_value())
615 {
616 // Get the number of cores
617 return numberOfCores.value();
618 }
619
620 // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
621 // if so then that devices number of cores is taken as the deviceCores value
622 if (deviceUid > 0)
623 {
624 // Check that the (optional) device is already registered
625 auto deviceIt = FindDevice(deviceUid);
626 if (deviceIt == m_Devices.end())
627 {
628 throw InvalidArgumentException(
629 boost::str(boost::format("Trying to connect a counter to a device that is "
630 "not registered (device UID %1%)")
631 % deviceUid));
632 }
633
634 // Get the associated device
635 const DevicePtr& device = deviceIt->second;
636 BOOST_ASSERT(device);
637
638 // Get the number of cores of the associated device
639 return device->m_Cores;
640 }
641
642 // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
643 // if it does then take that device's numberOfCores as the deviceCores value
644 uint16_t parentCategoryDeviceUid = parentCategory->m_DeviceUid;
645 if (parentCategoryDeviceUid > 0)
646 {
647 // Check that the device associated to the parent category is already registered
648 auto deviceIt = FindDevice(parentCategoryDeviceUid);
649 if (deviceIt == m_Devices.end())
650 {
651 throw InvalidArgumentException(
652 boost::str(boost::format("Trying to get the number of cores from a device that is "
653 "not registered (device UID %1%)")
654 % parentCategoryDeviceUid));
655 }
656
657 // Get the associated device
658 const DevicePtr& device = deviceIt->second;
659 BOOST_ASSERT(device);
660
661 // Get the number of cores of the device associated to the parent category
662 return device->m_Cores;
663 }
664
665 // 4. If none of the above holds then set deviceCores to zero
666 return 0;
Aron Virginas-Tar4e5fc1f2019-08-22 18:10:52 +0100667}
668
669} // namespace profiling
670
671} // namespace armnn