ArmNN  NotReleased
CounterDirectory Class Referencefinal

#include <CounterDirectory.hpp>

Inheritance diagram for CounterDirectory:
ICounterDirectory ICounterRegistry

Public Member Functions

 CounterDirectory ()=default
 
 ~CounterDirectory ()=default
 
const CategoryRegisterCategory (const std::string &categoryName, const Optional< uint16_t > &deviceUid=EmptyOptional(), const Optional< uint16_t > &counterSetUid=EmptyOptional()) override
 
const DeviceRegisterDevice (const std::string &deviceName, uint16_t cores=0, const Optional< std::string > &parentCategoryName=EmptyOptional()) override
 
const CounterSetRegisterCounterSet (const std::string &counterSetName, uint16_t count=0, const Optional< std::string > &parentCategoryName=EmptyOptional()) override
 
const CounterRegisterCounter (const BackendId &backendId, const uint16_t uid, const std::string &parentCategoryName, uint16_t counterClass, uint16_t interpolation, double multiplier, const std::string &name, const std::string &description, const Optional< std::string > &units=EmptyOptional(), const Optional< uint16_t > &numberOfCores=EmptyOptional(), const Optional< uint16_t > &deviceUid=EmptyOptional(), const Optional< uint16_t > &counterSetUid=EmptyOptional()) override
 
uint16_t GetCategoryCount () const override
 
uint16_t GetDeviceCount () const override
 
uint16_t GetCounterSetCount () const override
 
uint16_t GetCounterCount () const override
 
const CategoriesGetCategories () const override
 
const DevicesGetDevices () const override
 
const CounterSetsGetCounterSets () const override
 
const CountersGetCounters () const override
 
const CategoryGetCategory (const std::string &name) const override
 
const DeviceGetDevice (uint16_t uid) const override
 
const CounterSetGetCounterSet (uint16_t uid) const override
 
const CounterGetCounter (uint16_t uid) const override
 
bool IsCategoryRegistered (const std::string &categoryName) const
 
bool IsDeviceRegistered (uint16_t deviceUid) const
 
bool IsDeviceRegistered (const std::string &deviceName) const
 
bool IsCounterSetRegistered (uint16_t counterSetUid) const
 
bool IsCounterSetRegistered (const std::string &counterSetName) const
 
bool IsCounterRegistered (uint16_t counterUid) const
 
bool IsCounterRegistered (const std::string &counterName) const
 
void Clear ()
 
- Public Member Functions inherited from ICounterDirectory
virtual ~ICounterDirectory ()
 
- Public Member Functions inherited from ICounterRegistry
virtual ~ICounterRegistry ()
 

Detailed Description

Definition at line 23 of file CounterDirectory.hpp.

Constructor & Destructor Documentation

◆ CounterDirectory()

CounterDirectory ( )
default

◆ ~CounterDirectory()

~CounterDirectory ( )
default

Member Function Documentation

◆ Clear()

void Clear ( )

Definition at line 534 of file CounterDirectory.cpp.

References OptionalBase::has_value(), and OptionalReferenceSwitch< std::is_reference< T >::value, T >::value().

Referenced by CounterDirectory::GetCounters(), and ProfilingService::GetSendTimelinePacket().

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 }

◆ GetCategories()

const Categories& GetCategories ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 59 of file CounterDirectory.hpp.

59 { return m_Categories; }

◆ GetCategory()

const Category * GetCategory ( const std::string &  name) const
overridevirtual

Implements ICounterDirectory.

Definition at line 425 of file CounterDirectory.cpp.

Referenced by BOOST_AUTO_TEST_CASE(), and CounterDirectory::GetCounters().

426 {
427  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;
437 }

◆ GetCategoryCount()

uint16_t GetCategoryCount ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 53 of file CounterDirectory.hpp.

Referenced by BOOST_AUTO_TEST_CASE().

53 { return boost::numeric_cast<uint16_t>(m_Categories.size()); }

◆ GetCounter()

const Counter * GetCounter ( uint16_t  uid) const
overridevirtual

Implements ICounterDirectory.

Definition at line 469 of file CounterDirectory.cpp.

References Counter::m_MaxCounterUid, and Counter::m_Uid.

Referenced by BOOST_AUTO_TEST_CASE(), CounterDirectory::GetCounters(), and CounterDirectory::RegisterCounter().

470 {
471  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;
483 }

◆ GetCounterCount()

uint16_t GetCounterCount ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 56 of file CounterDirectory.hpp.

Referenced by BOOST_AUTO_TEST_CASE(), and ProfilingService::GetCounterCount().

56 { return boost::numeric_cast<uint16_t>(m_Counters.size()); }

◆ GetCounters()

◆ GetCounterSet()

const CounterSet * GetCounterSet ( uint16_t  uid) const
overridevirtual

Implements ICounterDirectory.

Definition at line 454 of file CounterDirectory.cpp.

References CounterSet::m_Uid.

Referenced by BOOST_AUTO_TEST_CASE(), and CounterDirectory::GetCounters().

455 {
456  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;
467 }

◆ GetCounterSetCount()

uint16_t GetCounterSetCount ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 55 of file CounterDirectory.hpp.

Referenced by BOOST_AUTO_TEST_CASE().

55 { return boost::numeric_cast<uint16_t>(m_CounterSets.size()); }

◆ GetCounterSets()

const CounterSets& GetCounterSets ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 61 of file CounterDirectory.hpp.

61 { return m_CounterSets; }

◆ GetDevice()

const Device * GetDevice ( uint16_t  uid) const
overridevirtual

Implements ICounterDirectory.

Definition at line 439 of file CounterDirectory.cpp.

References Device::m_Uid.

Referenced by BOOST_AUTO_TEST_CASE(), and CounterDirectory::GetCounters().

440 {
441  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;
452 }

◆ GetDeviceCount()

uint16_t GetDeviceCount ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 54 of file CounterDirectory.hpp.

Referenced by BOOST_AUTO_TEST_CASE().

54 { return boost::numeric_cast<uint16_t>(m_Devices.size()); }

◆ GetDevices()

const Devices& GetDevices ( ) const
inlineoverridevirtual

Implements ICounterDirectory.

Definition at line 60 of file CounterDirectory.hpp.

60 { return m_Devices; }

◆ IsCategoryRegistered()

bool IsCategoryRegistered ( const std::string &  categoryName) const

Definition at line 485 of file CounterDirectory.cpp.

Referenced by CounterDirectory::GetCounters(), ProfilingService::GetSendTimelinePacket(), and CounterDirectory::RegisterCategory().

486 {
487  auto it = FindCategory(categoryName);
488 
489  return it != m_Categories.end();
490 }

◆ IsCounterRegistered() [1/2]

bool IsCounterRegistered ( uint16_t  counterUid) const

Definition at line 520 of file CounterDirectory.cpp.

Referenced by CounterDirectory::GetCounters(), and ProfilingService::GetSendTimelinePacket().

521 {
522  auto it = FindCounter(counterUid);
523 
524  return it != m_Counters.end();
525 }

◆ IsCounterRegistered() [2/2]

bool IsCounterRegistered ( const std::string &  counterName) const

Definition at line 527 of file CounterDirectory.cpp.

528 {
529  auto it = FindCounter(counterName);
530 
531  return it != m_Counters.end();
532 }

◆ IsCounterSetRegistered() [1/2]

bool IsCounterSetRegistered ( uint16_t  counterSetUid) const

Definition at line 506 of file CounterDirectory.cpp.

Referenced by CounterDirectory::GetCounters(), CounterDirectory::RegisterCategory(), CounterDirectory::RegisterCounter(), and CounterDirectory::RegisterCounterSet().

507 {
508  auto it = FindCounterSet(counterSetUid);
509 
510  return it != m_CounterSets.end();
511 }

◆ IsCounterSetRegistered() [2/2]

bool IsCounterSetRegistered ( const std::string &  counterSetName) const

Definition at line 513 of file CounterDirectory.cpp.

514 {
515  auto it = FindCounterSet(counterSetName);
516 
517  return it != m_CounterSets.end();
518 }

◆ IsDeviceRegistered() [1/2]

bool IsDeviceRegistered ( uint16_t  deviceUid) const

Definition at line 492 of file CounterDirectory.cpp.

Referenced by CounterDirectory::GetCounters(), CounterDirectory::RegisterCategory(), and CounterDirectory::RegisterDevice().

493 {
494  auto it = FindDevice(deviceUid);
495 
496  return it != m_Devices.end();
497 }

◆ IsDeviceRegistered() [2/2]

bool IsDeviceRegistered ( const std::string &  deviceName) const

Definition at line 499 of file CounterDirectory.cpp.

500 {
501  auto it = FindDevice(deviceName);
502 
503  return it != m_Devices.end();
504 }

◆ RegisterCategory()

const Category * RegisterCategory ( const std::string &  categoryName,
const Optional< uint16_t > &  deviceUid = EmptyOptional(),
const Optional< uint16_t > &  counterSetUid = EmptyOptional() 
)
overridevirtual

Implements ICounterRegistry.

Definition at line 21 of file CounterDirectory.cpp.

References OptionalBase::has_value(), CounterDirectory::IsCategoryRegistered(), CounterDirectory::IsCounterSetRegistered(), CounterDirectory::IsDeviceRegistered(), and OptionalReferenceSwitch< std::is_reference< T >::value, T >::value().

Referenced by BOOST_AUTO_TEST_CASE(), and ProfilingService::GetSendTimelinePacket().

24 {
25  // Check that the given category name is valid
26  if (categoryName.empty() ||
27  !IsValidSwTraceString<SwTraceNameCharPolicy>(categoryName))
28  {
29  throw InvalidArgumentException("Trying to register a category with an invalid name");
30  }
31 
32  // Check that the given category is not already registered
33  if (IsCategoryRegistered(categoryName))
34  {
35  throw InvalidArgumentException(
36  boost::str(boost::format("Trying to register a category already registered (\"%1%\")")
37  % categoryName));
38  }
39 
40  // 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)
43  {
44  // Check that the (optional) device is already registered
45  if (!IsDeviceRegistered(deviceUidValue))
46  {
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  }
53  }
54 
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
60  if (!IsCounterSetRegistered(counterSetUidValue))
61  {
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;
82 }
bool IsCategoryRegistered(const std::string &categoryName) const
bool IsCounterSetRegistered(uint16_t counterSetUid) const
bool IsDeviceRegistered(uint16_t deviceUid) const
std::unique_ptr< Category > CategoryPtr

◆ RegisterCounter()

const Counter * RegisterCounter ( const BackendId backendId,
const uint16_t  uid,
const std::string &  parentCategoryName,
uint16_t  counterClass,
uint16_t  interpolation,
double  multiplier,
const std::string &  name,
const std::string &  description,
const Optional< std::string > &  units = EmptyOptional(),
const Optional< uint16_t > &  numberOfCores = EmptyOptional(),
const Optional< uint16_t > &  deviceUid = EmptyOptional(),
const Optional< uint16_t > &  counterSetUid = EmptyOptional() 
)
overridevirtual

Implements ICounterRegistry.

Definition at line 276 of file CounterDirectory.cpp.

References CounterDirectory::GetCounter(), armnn::profiling::GetNextCounterUids(), OptionalBase::has_value(), CounterDirectory::IsCounterSetRegistered(), Counter::m_Name, and OptionalReferenceSwitch< std::is_reference< T >::value, T >::value().

Referenced by BOOST_AUTO_TEST_CASE(), and ProfilingService::GetSendTimelinePacket().

288 {
289  boost::ignore_unused(backendId);
290 
291  // 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
373  if (!IsCounterSetRegistered(counterSetUidValue))
374  {
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
387  std::vector<uint16_t> counterUids = GetNextCounterUids(uid, deviceCores);
388  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
395  CounterPtr counter = std::make_shared<Counter>(armnn::profiling::BACKEND_ID,
396  counterUids.front(),
397  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;
423 }
bool IsCounterSetRegistered(uint16_t counterSetUid) const
const Counter * GetCounter(uint16_t uid) const override
std::vector< uint16_t > GetNextCounterUids(uint16_t firstUid, uint16_t cores)
std::shared_ptr< Counter > CounterPtr
std::unique_ptr< Category > CategoryPtr

◆ RegisterCounterSet()

const CounterSet * RegisterCounterSet ( const std::string &  counterSetName,
uint16_t  count = 0,
const Optional< std::string > &  parentCategoryName = EmptyOptional() 
)
overridevirtual

Implements ICounterRegistry.

Definition at line 180 of file CounterDirectory.cpp.

References armnn::profiling::GetNextUid(), OptionalBase::has_value(), CounterDirectory::IsCounterSetRegistered(), Category::m_CounterSetUid, and OptionalReferenceSwitch< std::is_reference< T >::value, T >::value().

Referenced by BOOST_AUTO_TEST_CASE().

183 {
184  // 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
192  if (IsCounterSetRegistered(counterSetName))
193  {
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;
274 }
std::unique_ptr< CounterSet > CounterSetPtr
uint16_t GetNextUid(bool peekOnly)
bool IsCounterSetRegistered(uint16_t counterSetUid) const
std::unique_ptr< Category > CategoryPtr

◆ RegisterDevice()

const Device * RegisterDevice ( const std::string &  deviceName,
uint16_t  cores = 0,
const Optional< std::string > &  parentCategoryName = EmptyOptional() 
)
overridevirtual

Implements ICounterRegistry.

Definition at line 84 of file CounterDirectory.cpp.

References armnn::profiling::GetNextUid(), OptionalBase::has_value(), CounterDirectory::IsDeviceRegistered(), Category::m_DeviceUid, and OptionalReferenceSwitch< std::is_reference< T >::value, T >::value().

Referenced by BOOST_AUTO_TEST_CASE().

87 {
88  // 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
96  if (IsDeviceRegistered(deviceName))
97  {
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;
178 }
uint16_t GetNextUid(bool peekOnly)
bool IsDeviceRegistered(uint16_t deviceUid) const
std::unique_ptr< Category > CategoryPtr
std::unique_ptr< Device > DevicePtr

The documentation for this class was generated from the following files: