aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Martincigh <matteo.martincigh@arm.com>2019-09-05 12:02:04 +0100
committerJim Flynn Arm <jim.flynn@arm.com>2019-09-17 15:48:37 +0000
commit6db5f20ade72896ebf0f6513a4832b8f2e917aa0 (patch)
tree654e0502a35d6fa11c51be31edf60a6106a15a54
parent10e0786f15bdb60e1d632c9a368fce2737852ae4 (diff)
downloadarmnn-6db5f20ade72896ebf0f6513a4832b8f2e917aa0.tar.gz
IVGCVSW-3691 Rework the CounterDirectory class to take into consideration
the connections between components * Added constructors and connections to the profiling classes * Used hash table to keep track of the profiling objects by UID * Added register methods * Added find/check helper methods * Updated the makefile to include the profiling directory * Added unit tests for the CounterDirectory class * Added ICounterDirectory interface class for read-only use * Added custom macro to locally disable conversion warnings Change-Id: I3f53a68663ee77b8d03ac0ef7dc01e90c6893511 Signed-off-by: Matteo Martincigh <matteo.martincigh@arm.com>
-rw-r--r--CMakeLists.txt30
-rw-r--r--include/armnn/Conversion.hpp40
-rw-r--r--src/profiling/CounterDirectory.cpp629
-rw-r--r--src/profiling/CounterDirectory.hpp155
-rw-r--r--src/profiling/ICounterDirectory.hpp164
-rw-r--r--src/profiling/ProfilingUtils.cpp73
-rw-r--r--src/profiling/ProfilingUtils.hpp66
-rw-r--r--src/profiling/test/ProfilingTests.cpp942
-rw-r--r--src/profiling/test/SendCounterPacketTests.cpp9
9 files changed, 1881 insertions, 227 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a04f30baf2..0c66eef9d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -205,7 +205,10 @@ endif()
list(APPEND armnn_sources
include/armnn/ArmNN.hpp
+ include/armnn/BackendHelper.hpp
include/armnn/BackendId.hpp
+ include/armnn/Conversion.hpp
+ include/armnn/Deprecated.hpp
include/armnn/Descriptors.hpp
include/armnn/DescriptorsFwd.hpp
include/armnn/Exceptions.hpp
@@ -428,28 +431,29 @@ list(APPEND armnn_sources
src/profiling/EncodeVersion.hpp
src/profiling/Holder.cpp
src/profiling/Holder.hpp
+ src/profiling/IBufferWrapper.hpp
+ src/profiling/ICounterDirectory.hpp
+ src/profiling/ISendCounterPacket.hpp
+ src/profiling/IPeriodicCounterCapture.hpp
src/profiling/IProfilingConnection.hpp
src/profiling/Packet.cpp
src/profiling/Packet.hpp
src/profiling/PacketVersionResolver.cpp
src/profiling/PacketVersionResolver.hpp
+ src/profiling/PeriodicCounterSelectionCommandHandler.cpp
+ src/profiling/PeriodicCounterSelectionCommandHandler.hpp
src/profiling/ProfilingConnectionFactory.cpp
src/profiling/ProfilingConnectionFactory.hpp
- src/profiling/IBufferWrapper.hpp
- src/profiling/IPeriodicCounterCapture.hpp
- src/profiling/ISendCounterPacket.hpp
- src/profiling/SendCounterPacket.hpp
+ src/profiling/ProfilingService.cpp
+ src/profiling/ProfilingService.hpp
+ src/profiling/ProfilingStateMachine.cpp
+ src/profiling/ProfilingStateMachine.hpp
+ src/profiling/ProfilingUtils.cpp
+ src/profiling/ProfilingUtils.hpp
src/profiling/SendCounterPacket.cpp
+ src/profiling/SendCounterPacket.hpp
src/profiling/SocketProfilingConnection.cpp
src/profiling/SocketProfilingConnection.hpp
- src/profiling/ProfilingUtils.hpp
- src/profiling/ProfilingUtils.cpp
- src/profiling/ProfilingStateMachine.cpp
- src/profiling/ProfilingStateMachine.hpp
- src/profiling/ProfilingService.cpp
- src/profiling/ProfilingService.hpp
- src/profiling/PeriodicCounterSelectionCommandHandler.cpp
- src/profiling/PeriodicCounterSelectionCommandHandler.hpp
third-party/half/half.hpp
)
@@ -473,6 +477,7 @@ add_library_ex(armnn SHARED ${armnn_sources})
target_include_directories(armnn PRIVATE src/armnn)
target_include_directories(armnn PRIVATE src/armnnUtils)
target_include_directories(armnn PRIVATE src/backends)
+target_include_directories(armnn PRIVATE src/profiling)
target_link_libraries(armnn armnnUtils)
@@ -745,6 +750,7 @@ if(BUILD_UNIT_TESTS)
target_include_directories(UnitTests PRIVATE src/armnn)
target_include_directories(UnitTests PRIVATE src/armnnUtils)
target_include_directories(UnitTests PRIVATE src/backends)
+ target_include_directories(UnitTests PRIVATE src/profiling)
if(VALGRIND_FOUND)
if(HEAP_PROFILING OR LEAK_CHECKING)
diff --git a/include/armnn/Conversion.hpp b/include/armnn/Conversion.hpp
new file mode 100644
index 0000000000..37338eded7
--- /dev/null
+++ b/include/armnn/Conversion.hpp
@@ -0,0 +1,40 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#if __GNUC__
+# define ARMNN_NO_CONVERSION_WARN_BEGIN \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wconversion\"")
+
+# define ARMNN_NO_CONVERSION_WARN_END \
+ _Pragma("GCC diagnostic pop")
+
+#elif __clang__
+# define ARMNN_NO_CONVERSION_WARN_BEGIN \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wconversion\"")
+
+# define ARMNN_NO_CONVERSION_WARN_END \
+ _Pragma("clang diagnostic pop")
+
+#elif defined (_MSC_VER)
+# define ARMNN_NO_CONVERSION_WARN_BEGIN \
+ __pragma(warning( push )) \
+ __pragma(warning(disable : 4101))
+
+# define ARMNN_NO_CONVERSION_WARN_END \
+ __pragma(warning( pop ))
+
+#else
+# define ARMNN_NO_CONVERSION_WARN_BEGIN
+# define ARMNN_NO_CONVERSION_WARN_END
+#endif
+
+#define ARMNN_SUPRESS_CONVERSION_WARNING(func) \
+ARMNN_NO_CONVERSION_WARN_BEGIN \
+func; \
+ARMNN_NO_CONVERSION_WARN_END
diff --git a/src/profiling/CounterDirectory.cpp b/src/profiling/CounterDirectory.cpp
index a84897995d..cef3d6a76d 100644
--- a/src/profiling/CounterDirectory.cpp
+++ b/src/profiling/CounterDirectory.cpp
@@ -4,8 +4,12 @@
//
#include "CounterDirectory.hpp"
+#include "ProfilingUtils.hpp"
#include <armnn/Exceptions.hpp>
+#include <armnn/Conversion.hpp>
+
+#include <boost/format.hpp>
namespace armnn
{
@@ -13,149 +17,616 @@ namespace armnn
namespace profiling
{
-CounterDirectory::CounterDirectory(uint16_t uid,
- const std::string& name,
- uint16_t deviceCount,
- uint16_t counterCount,
- uint16_t categoryCount)
- : m_Uid(uid)
- , m_Name(name)
- , m_DeviceCount(deviceCount)
- , m_CounterCount(counterCount)
- , m_CategoryCount(categoryCount)
- , m_DeviceIds(deviceCount)
- , m_CounterIds(counterCount)
- , m_CategoryIds(categoryCount)
- , m_DeviceObjects(deviceCount)
- , m_CounterObjects(counterCount)
- , m_CategoryObjects(categoryCount)
-{}
-
-// Helper methods
-void CounterDirectory::CheckDeviceIndex(uint16_t index) const
+const Category* CounterDirectory::RegisterCategory(const std::string& categoryName,
+ const Optional<uint16_t>& deviceUid,
+ const Optional<uint16_t>& counterSetUid)
{
- if (index >= m_DeviceCount)
+ // Check that the given category name is valid
+ if (categoryName.empty() ||
+ !IsValidSwTraceString<SwTraceNameCharPolicy>(categoryName))
+ {
+ throw InvalidArgumentException("Trying to register a category with an invalid name");
+ }
+
+ // Check that the given category is not already registered
+ if (CheckIfCategoryIsRegistered(categoryName))
{
- throw InvalidArgumentException("Invalid device index");
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to register a category already registered (\"%1%\")")
+ % categoryName));
}
+
+ // Check that a device with the given (optional) UID is already registered
+ uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
+ if (deviceUidValue > 0)
+ {
+ // Check that the (optional) device is already registered
+ if (!CheckIfDeviceIsRegistered(deviceUidValue))
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a category (\"%1%\") to a device that is "
+ "not registered (UID %2%)")
+ % categoryName
+ % deviceUidValue));
+ }
+ }
+
+ // Check that a counter set with the given (optional) UID is already registered
+ uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
+ if (counterSetUidValue > 0)
+ {
+ // Check that the (optional) counter set is already registered
+ if (!CheckIfCounterSetIsRegistered(counterSetUidValue))
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a category (name: \"%1%\") to a counter set "
+ "that is not registered (UID: %2%)")
+ % categoryName
+ % counterSetUidValue));
+ }
+ }
+
+ // Create the category
+ CategoryPtr category = std::make_unique<Category>(categoryName, deviceUidValue, counterSetUidValue);
+ BOOST_ASSERT(category);
+
+ // Get the raw category pointer
+ const Category* categoryPtr = category.get();
+ BOOST_ASSERT(categoryPtr);
+
+ // Register the category
+ m_Categories.insert(std::move(category));
+
+ return categoryPtr;
}
-void CounterDirectory::CheckCounterIndex(uint16_t index) const
+const Device* CounterDirectory::RegisterDevice(const std::string& deviceName,
+ uint16_t cores,
+ const Optional<std::string>& parentCategoryName)
{
- if (index >= m_CounterCount)
+ // Check that the given device name is valid
+ if (deviceName.empty() ||
+ !IsValidSwTraceString<SwTraceCharPolicy>(deviceName))
+ {
+ throw InvalidArgumentException("Trying to register a device with an invalid name");
+ }
+
+ // Check that a device with the given name is not already registered
+ if (CheckIfDeviceIsRegistered(deviceName))
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to register a device already registered (\"%1%\")")
+ % deviceName));
+ }
+
+ // 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
+ // the registration fails. We'll get a proper one once we're sure that the device can be registered
+ uint16_t deviceUidPeek = GetNextUid(true);
+
+ // Check that a category with the given (optional) parent category name is already registered
+ Category* parentCategoryPtr = nullptr;
+ if (parentCategoryName.has_value())
{
- throw InvalidArgumentException("Invalid counter index");
+ // Get the (optional) parent category name
+ const std::string& parentCategoryNameValue = parentCategoryName.value();
+ if (parentCategoryNameValue.empty())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a device (name: \"%1%\") to an invalid "
+ "parent category (name: \"%2%\")")
+ % deviceName
+ % parentCategoryNameValue));
+ }
+
+ // Check that the given parent category is already registered
+ auto categoryIt = FindCategory(parentCategoryNameValue);
+ if (categoryIt == m_Categories.end())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a device (name: \"%1%\") to a parent category that "
+ "is not registered (name: \"%2%\")")
+ % deviceName
+ % parentCategoryNameValue));
+ }
+
+ // Get the parent category
+ const CategoryPtr& parentCategory = *categoryIt;
+ BOOST_ASSERT(parentCategory);
+
+ // Check that the given parent category is not already connected to another device
+ if (parentCategory->m_DeviceUid != 0 && parentCategory->m_DeviceUid != deviceUidPeek)
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a device (UID: %1%) to a parent category that is "
+ "already connected to a different device "
+ "(category \"%2%\" connected to device %3%)")
+ % deviceUidPeek
+ % parentCategoryNameValue
+ % parentCategory->m_DeviceUid));
+ }
+
+ // The parent category can be associated to the device that is about to be registered.
+ // Get the raw pointer to the parent category (to be used later when the device is actually been
+ // registered, to make sure that the category is associated to an existing device)
+ parentCategoryPtr = parentCategory.get();
}
+
+ // Get the device UID
+ uint16_t deviceUid = GetNextUid();
+ BOOST_ASSERT(deviceUid == deviceUidPeek);
+
+ // Create the device
+ DevicePtr device = std::make_unique<Device>(deviceUid, deviceName, cores);
+ BOOST_ASSERT(device);
+
+ // Get the raw device pointer
+ const Device* devicePtr = device.get();
+ BOOST_ASSERT(devicePtr);
+
+ // Register the device
+ m_Devices.insert(std::make_pair(deviceUid, std::move(device)));
+
+ // Connect the device to the parent category, if required
+ if (parentCategoryPtr)
+ {
+ // Set the device UID in the parent category
+ parentCategoryPtr->m_DeviceUid = deviceUid;
+ }
+
+ return devicePtr;
}
-void CounterDirectory::CheckCategoryIndex(uint16_t index) const
+const CounterSet* CounterDirectory::RegisterCounterSet(const std::string& counterSetName,
+ uint16_t count,
+ const Optional<std::string>& parentCategoryName)
{
- if (index >= m_CategoryCount)
+ // Check that the given counter set name is valid
+ if (counterSetName.empty() ||
+ !IsValidSwTraceString<SwTraceNameCharPolicy>(counterSetName))
{
- throw InvalidArgumentException("Invalid category index");
+ throw InvalidArgumentException("Trying to register a counter set with an invalid name");
}
+
+ // Check that a counter set with the given name is not already registered
+ if (CheckIfCounterSetIsRegistered(counterSetName))
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to register a counter set already registered (\"%1%\")")
+ % counterSetName));
+ }
+
+ // 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
+ // the registration fails. We'll get a proper one once we're sure that the counter set can be registered
+ uint16_t counterSetUidPeek = GetNextUid(true);
+
+ // Check that a category with the given (optional) parent category name is already registered
+ Category* parentCategoryPtr = nullptr;
+ if (parentCategoryName.has_value())
+ {
+ // Get the (optional) parent category name
+ const std::string& parentCategoryNameValue = parentCategoryName.value();
+ if (parentCategoryNameValue.empty())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a counter set (UID: %1%) to an invalid "
+ "parent category (name: \"%2%\")")
+ % counterSetUidPeek
+ % parentCategoryNameValue));
+ }
+
+ // Check that the given parent category is already registered
+ auto it = FindCategory(parentCategoryNameValue);
+ if (it == m_Categories.end())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
+ "that is not registered (name: \"%2%\")")
+ % counterSetUidPeek
+ % parentCategoryNameValue));
+ }
+
+ // Get the parent category
+ const CategoryPtr& parentCategory = *it;
+ BOOST_ASSERT(parentCategory);
+
+ // Check that the given parent category is not already connected to another counter set
+ if (parentCategory->m_CounterSetUid != 0 && parentCategory->m_CounterSetUid != counterSetUidPeek)
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a counter set (UID: %1%) to a parent category "
+ "that is already connected to a different counter set "
+ "(category \"%2%\" connected to counter set %3%)")
+ % counterSetUidPeek
+ % parentCategoryNameValue
+ % parentCategory->m_CounterSetUid));
+ }
+
+ // The parent category can be associated to the counter set that is about to be registered.
+ // Get the raw pointer to the parent category (to be used later when the counter set is actually been
+ // registered, to make sure that the category is associated to an existing counter set)
+ parentCategoryPtr = parentCategory.get();
+ }
+
+ // Get the counter set UID
+ uint16_t counterSetUid = GetNextUid();
+ BOOST_ASSERT(counterSetUid == counterSetUidPeek);
+
+ // Create the counter set
+ CounterSetPtr counterSet = std::make_unique<CounterSet>(counterSetUid, counterSetName, count);
+ BOOST_ASSERT(counterSet);
+
+ // Get the raw counter set pointer
+ const CounterSet* counterSetPtr = counterSet.get();
+ BOOST_ASSERT(counterSetPtr);
+
+ // Register the counter set
+ m_CounterSets.insert(std::make_pair(counterSetUid, std::move(counterSet)));
+
+ // Connect the counter set to the parent category, if required
+ if (parentCategoryPtr)
+ {
+ // Set the counter set UID in the parent category
+ parentCategoryPtr->m_CounterSetUid = counterSetUid;
+ }
+
+ return counterSetPtr;
}
-// Getters for basic attributes
-uint16_t CounterDirectory::GetUid() const
+const Counter* CounterDirectory::RegisterCounter(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,
+ const Optional<uint16_t>& numberOfCores,
+ const Optional<uint16_t>& deviceUid,
+ const Optional<uint16_t>& counterSetUid)
{
- return m_Uid;
+ // Check that the given parent category name is valid
+ if (parentCategoryName.empty() ||
+ !IsValidSwTraceString<SwTraceNameCharPolicy>(parentCategoryName))
+ {
+ throw InvalidArgumentException("Trying to register a counter with an invalid parent category name");
+ }
+
+ // Check that the given class is valid
+ if (counterClass != 0 && counterClass != 1)
+ {
+ throw InvalidArgumentException("Trying to register a counter with an invalid class");
+ }
+
+ // Check that the given interpolation is valid
+ if (interpolation != 0 && interpolation != 1)
+ {
+ throw InvalidArgumentException("Trying to register a counter with an invalid interpolation");
+ }
+
+ // Check that the given multiplier is valid
+ if (multiplier == .0f)
+ {
+ throw InvalidArgumentException("Trying to register a counter with an invalid multiplier");
+ }
+
+ // Check that the given name is valid
+ if (name.empty() ||
+ !IsValidSwTraceString<SwTraceCharPolicy>(name))
+ {
+ throw InvalidArgumentException("Trying to register a counter with an invalid name");
+ }
+
+ // Check that the given description is valid
+ if (description.empty() ||
+ !IsValidSwTraceString<SwTraceCharPolicy>(description))
+ {
+ throw InvalidArgumentException("Trying to register a counter with an invalid description");
+ }
+
+ // Check that the given units are valid
+ if (units.has_value()
+ && !IsValidSwTraceString<SwTraceNameCharPolicy>(units.value()))
+ {
+ throw InvalidArgumentException("Trying to register a counter with a invalid units");
+ }
+
+ // Check that the given parent category is registered
+ auto categoryIt = FindCategory(parentCategoryName);
+ if (categoryIt == m_Categories.end())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a counter to a category "
+ "that is not registered (name: \"%1%\")")
+ % parentCategoryName));
+ }
+
+ // Get the parent category
+ const CategoryPtr& parentCategory = *categoryIt;
+ BOOST_ASSERT(parentCategory);
+
+ // Check that a counter with the given name is not already registered within the parent category
+ const std::vector<uint16_t>& parentCategoryCounters = parentCategory->m_Counters;
+ for (uint16_t parentCategoryCounterUid : parentCategoryCounters)
+ {
+ const Counter* parentCategoryCounter = GetCounter(parentCategoryCounterUid);
+ BOOST_ASSERT(parentCategoryCounter);
+
+ if (parentCategoryCounter->m_Name == name)
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to register a counter to category \"%1%\" with a name that "
+ "is already used within that category (name: \"%2%\")")
+ % parentCategoryName
+ % name));
+ }
+ }
+
+ // Check that a counter set with the given (optional) UID is already registered
+ uint16_t counterSetUidValue = counterSetUid.has_value() ? counterSetUid.value() : 0;
+ if (counterSetUidValue > 0)
+ {
+ // Check that the (optional) counter set is already registered
+ if (!CheckIfCounterSetIsRegistered(counterSetUidValue))
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a counter to a counter set that is "
+ "not registered (counter set UID: %1%)")
+ % counterSetUidValue));
+ }
+ }
+
+ // Get the number of cores (this call may throw)
+ uint16_t deviceUidValue = deviceUid.has_value() ? deviceUid.value() : 0;
+ uint16_t deviceCores = GetNumberOfCores(numberOfCores, deviceUidValue, parentCategory);
+
+ // Get the counter UIDs and calculate the max counter UID
+ std::vector<uint16_t> counterUids = GetNextCounterUids(deviceCores);
+ BOOST_ASSERT(!counterUids.empty());
+ uint16_t maxCounterUid = deviceCores <= 1 ? counterUids.front() : counterUids.back();
+
+ // Get the counter units
+ const std::string unitsValue = units.has_value() ? units.value() : "";
+
+ // Create the counter
+ CounterPtr counter = std::make_shared<Counter>(counterUids.front(),
+ maxCounterUid,
+ counterClass,
+ interpolation,
+ multiplier,
+ name,
+ description,
+ unitsValue,
+ deviceUidValue,
+ counterSetUidValue);
+ BOOST_ASSERT(counter);
+
+ // Get the raw counter pointer
+ const Counter* counterPtr = counter.get();
+ BOOST_ASSERT(counterPtr);
+
+ // Process multiple counters if necessary
+ for (uint16_t counterUid : counterUids)
+ {
+ // Connect the counter to the parent category
+ parentCategory->m_Counters.push_back(counterUid);
+
+ // Register the counter
+ m_Counters.insert(std::make_pair(counterUid, counter));
+ }
+
+ return counterPtr;
}
-const std::string& CounterDirectory::GetName() const
+const Category* CounterDirectory::GetCategory(const std::string& categoryName) const
{
- return m_Name;
+ auto it = FindCategory(categoryName);
+ if (it == m_Categories.end())
+ {
+ return nullptr;
+ }
+
+ const Category* category = it->get();
+ BOOST_ASSERT(category);
+
+ return category;
}
-// Getters for counts
-uint16_t CounterDirectory::GetDeviceCount() const
+const Device* CounterDirectory::GetDevice(uint16_t deviceUid) const
{
- return m_DeviceCount;
+ auto it = FindDevice(deviceUid);
+ if (it == m_Devices.end())
+ {
+ return nullptr;
+ }
+
+ const Device* device = it->second.get();
+ BOOST_ASSERT(device);
+ BOOST_ASSERT(device->m_Uid == deviceUid);
+
+ return device;
}
-uint16_t CounterDirectory::GetCounterCount() const
+const CounterSet* CounterDirectory::GetCounterSet(uint16_t counterSetUid) const
{
- return m_CounterCount;
+ auto it = FindCounterSet(counterSetUid);
+ if (it == m_CounterSets.end())
+ {
+ return nullptr;
+ }
+
+ const CounterSet* counterSet = it->second.get();
+ BOOST_ASSERT(counterSet);
+ BOOST_ASSERT(counterSet->m_Uid == counterSetUid);
+
+ return counterSet;
}
-uint16_t CounterDirectory::GetCategoryCount() const
+const Counter* CounterDirectory::GetCounter(uint16_t counterUid) const
{
- return m_CategoryCount;
+ auto it = FindCounter(counterUid);
+ if (it == m_Counters.end())
+ {
+ return nullptr;
+ }
+
+ const Counter* counter = it->second.get();
+ BOOST_ASSERT(counter);
+ BOOST_ASSERT(counter->m_Uid <= counterUid);
+ BOOST_ASSERT(counter->m_Uid <= counter->m_MaxCounterUid);
+
+ return counter;
}
-// Getters and setters for devices
-void CounterDirectory::GetDeviceValue(uint16_t index, uint32_t& value) const
+CategoriesIt CounterDirectory::FindCategory(const std::string& categoryName) const
{
- CheckDeviceIndex(index);
- value = m_DeviceIds[index].load();
+ return std::find_if(m_Categories.begin(), m_Categories.end(), [&categoryName](const CategoryPtr& category)
+ {
+ BOOST_ASSERT(category);
+
+ return category->m_Name == categoryName;
+ });
}
-void CounterDirectory::SetDeviceValue(uint16_t index, uint32_t value)
+DevicesIt CounterDirectory::FindDevice(uint16_t deviceUid) const
{
- CheckDeviceIndex(index);
- m_DeviceIds[index].store(value);
+ return m_Devices.find(deviceUid);
}
-void CounterDirectory::GetDeviceObject(uint16_t index, Device* device) const
+DevicesIt CounterDirectory::FindDevice(const std::string& deviceName) const
{
- CheckDeviceIndex(index);
- device = m_DeviceObjects[index].load();
+ return std::find_if(m_Devices.begin(), m_Devices.end(), [&deviceName](const auto& pair)
+ {
+ BOOST_ASSERT(pair.second);
+ BOOST_ASSERT(pair.second->m_Uid == pair.first);
+
+ return pair.second->m_Name == deviceName;
+ });
}
-void CounterDirectory::SetDeviceObject(uint16_t index, Device* device)
+CounterSetsIt CounterDirectory::FindCounterSet(uint16_t counterSetUid) const
{
- CheckDeviceIndex(index);
- m_DeviceObjects[index].store(device);
+ return m_CounterSets.find(counterSetUid);
}
-// Getters and setters for counters
-void CounterDirectory::GetCounterValue(uint16_t index, uint32_t& value) const
+CounterSetsIt CounterDirectory::FindCounterSet(const std::string& counterSetName) const
{
- CheckCounterIndex(index);
- value = m_CounterIds[index].load();
+ return std::find_if(m_CounterSets.begin(), m_CounterSets.end(), [&counterSetName](const auto& pair)
+ {
+ BOOST_ASSERT(pair.second);
+ BOOST_ASSERT(pair.second->m_Uid == pair.first);
+
+ return pair.second->m_Name == counterSetName;
+ });
}
-void CounterDirectory::SetCounterValue(uint16_t index, uint32_t value)
+CountersIt CounterDirectory::FindCounter(uint16_t counterUid) const
{
- CheckCounterIndex(index);
- m_CounterIds[index].store(value);
+ return m_Counters.find(counterUid);
}
-void CounterDirectory::GetCounterObject(uint16_t index, Counter* counter) const
+bool CounterDirectory::CheckIfCategoryIsRegistered(const std::string& categoryName) const
{
- CheckCounterIndex(index);
- counter = m_CounterObjects[index].load();
+ auto it = FindCategory(categoryName);
+
+ return it != m_Categories.end();
}
-void CounterDirectory::SetCounterObject(uint16_t index, Counter* counter)
+bool CounterDirectory::CheckIfDeviceIsRegistered(uint16_t deviceUid) const
{
- CheckCounterIndex(index);
- m_CounterObjects[index].store(counter);
+ auto it = FindDevice(deviceUid);
+
+ return it != m_Devices.end();
}
-// Getters and setters for categories
-void CounterDirectory::GetCategoryValue(uint16_t index, uint32_t& value) const
+bool CounterDirectory::CheckIfDeviceIsRegistered(const std::string& deviceName) const
{
- CheckCategoryIndex(index);
- value = m_CategoryIds[index].load();
+ auto it = FindDevice(deviceName);
+
+ return it != m_Devices.end();
}
-void CounterDirectory::SetCategoryValue(uint16_t index, uint32_t value)
+bool CounterDirectory::CheckIfCounterSetIsRegistered(uint16_t counterSetUid) const
{
- CheckCategoryIndex(index);
- m_CategoryIds[index].store(value);
+ auto it = FindCounterSet(counterSetUid);
+
+ return it != m_CounterSets.end();
}
-void CounterDirectory::GetCategoryObject(uint16_t index, Category* category) const
+bool CounterDirectory::CheckIfCounterSetIsRegistered(const std::string& counterSetName) const
{
- CheckCategoryIndex(index);
- category = m_CategoryObjects[index].load();
+ auto it = FindCounterSet(counterSetName);
+
+ return it != m_CounterSets.end();
}
-void CounterDirectory::SetCategoryObject(uint16_t index, Category* category)
+uint16_t CounterDirectory::GetNumberOfCores(const Optional<uint16_t>& numberOfCores,
+ uint16_t deviceUid,
+ const CategoryPtr& parentCategory)
{
- CheckCategoryIndex(index);
- m_CategoryObjects[index].store(category);
+ BOOST_ASSERT(parentCategory);
+
+ // To get the number of cores, apply the following rules:
+ //
+ // 1. If numberOfCores is set then take it as the deviceCores value
+ // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
+ // if so then that devices number of cores is taken as the deviceCores value
+ // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
+ // if it does then take that device's numberOfCores as the deviceCores value
+ // 4. If none of the above holds then set deviceCores to zero
+
+ // 1. If numberOfCores is set then take it as the deviceCores value
+ if (numberOfCores.has_value())
+ {
+ // Get the number of cores
+ return numberOfCores.value();
+ }
+
+ // 2. If numberOfCores is not set then check to see if this counter is directly associated with a device,
+ // if so then that devices number of cores is taken as the deviceCores value
+ if (deviceUid > 0)
+ {
+ // Check that the (optional) device is already registered
+ auto deviceIt = FindDevice(deviceUid);
+ if (deviceIt == m_Devices.end())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to connect a counter to a device that is "
+ "not registered (device UID %1%)")
+ % deviceUid));
+ }
+
+ // Get the associated device
+ const DevicePtr& device = deviceIt->second;
+ BOOST_ASSERT(device);
+
+ // Get the number of cores of the associated device
+ return device->m_Cores;
+ }
+
+ // 3. If neither of the above is set then look at the category to see if it has a device associated with it,
+ // if it does then take that device's numberOfCores as the deviceCores value
+ uint16_t parentCategoryDeviceUid = parentCategory->m_DeviceUid;
+ if (parentCategoryDeviceUid > 0)
+ {
+ // Check that the device associated to the parent category is already registered
+ auto deviceIt = FindDevice(parentCategoryDeviceUid);
+ if (deviceIt == m_Devices.end())
+ {
+ throw InvalidArgumentException(
+ boost::str(boost::format("Trying to get the number of cores from a device that is "
+ "not registered (device UID %1%)")
+ % parentCategoryDeviceUid));
+ }
+
+ // Get the associated device
+ const DevicePtr& device = deviceIt->second;
+ BOOST_ASSERT(device);
+
+ // Get the number of cores of the device associated to the parent category
+ return device->m_Cores;
+ }
+
+ // 4. If none of the above holds then set deviceCores to zero
+ return 0;
}
} // namespace profiling
diff --git a/src/profiling/CounterDirectory.hpp b/src/profiling/CounterDirectory.hpp
index ec1ac273bc..a756a9a7bd 100644
--- a/src/profiling/CounterDirectory.hpp
+++ b/src/profiling/CounterDirectory.hpp
@@ -5,106 +5,89 @@
#pragma once
-#include <atomic>
-#include <string>
-#include <vector>
-
-namespace armnn
-{
+#include "ICounterDirectory.hpp"
-namespace profiling
-{
+#include <armnn/Optional.hpp>
-class Category
-{
-public:
- std::string m_Name;
-};
+#include <string>
+#include <unordered_set>
+#include <unordered_map>
-class Device
-{
-public:
- uint16_t m_Uid;
- std::string m_Name;
- uint16_t m_Cores;
-};
+#include <boost/numeric/conversion/cast.hpp>
-class Counter
+namespace armnn
{
-public:
- uint16_t m_Uid;
- uint16_t m_MaxCounterUid;
- uint16_t m_Class;
- uint16_t m_Interpolation;
- float m_Multiplier;
- std::string m_Name;
- std::string m_Description;
- std::string m_Units;
-};
-class CounterSet
+namespace profiling
{
-public:
- uint16_t m_Uid;
- std::string m_Name;
- uint16_t m_Count;
-};
-class CounterDirectory final
+class CounterDirectory final : public ICounterDirectory
{
public:
- CounterDirectory(uint16_t uid,
- const std::string& name,
- uint16_t deviceCount,
- uint16_t counterCount,
- uint16_t categoryCount);
-
+ CounterDirectory() = default;
~CounterDirectory() = default;
- uint16_t GetUid() const;
- const std::string& GetName() const;
-
- uint16_t GetDeviceCount() const;
- uint16_t GetCounterCount() const;
- uint16_t GetCategoryCount() const;
-
- void GetDeviceValue(uint16_t index, uint32_t& value) const;
- void SetDeviceValue(uint16_t index, uint32_t value);
-
- void GetDeviceObject(uint16_t index, Device* counter) const;
- void SetDeviceObject(uint16_t index, Device* counter);
-
- void GetCounterValue(uint16_t index, uint32_t& value) const;
- void SetCounterValue(uint16_t index, uint32_t value);
-
- void GetCounterObject(uint16_t index, Counter* counter) const;
- void SetCounterObject(uint16_t index, Counter* counter);
-
- void GetCategoryValue(uint16_t index, uint32_t& value) const;
- void SetCategoryValue(uint16_t index, uint32_t value);
-
- void GetCategoryObject(uint16_t index, Category* counter) const;
- void SetCategoryObject(uint16_t index, Category* counter);
+ // Register profiling objects
+ const Category* RegisterCategory (const std::string& categoryName,
+ const Optional<uint16_t>& deviceUid = EmptyOptional(),
+ const Optional<uint16_t>& counterSetUid = EmptyOptional());
+ const Device* RegisterDevice (const std::string& deviceName,
+ uint16_t cores = 0,
+ const Optional<std::string>& parentCategoryName = EmptyOptional());
+ const CounterSet* RegisterCounterSet(const std::string& counterSetName,
+ uint16_t count = 0,
+ const Optional<std::string>& parentCategoryName = EmptyOptional());
+ const Counter* RegisterCounter (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());
+
+ // Getters for counts
+ uint16_t GetCategoryCount() const override { return boost::numeric_cast<uint16_t>(m_Categories.size()); }
+ uint16_t GetDeviceCount() const override { return boost::numeric_cast<uint16_t>(m_Devices.size()); }
+ uint16_t GetCounterSetCount() const override { return boost::numeric_cast<uint16_t>(m_CounterSets.size()); }
+ uint16_t GetCounterCount() const override { return boost::numeric_cast<uint16_t>(m_Counters.size()); }
+
+ // Getters for collections
+ const Categories& GetCategories() const override { return m_Categories; }
+ const Devices& GetDevices() const override { return m_Devices; }
+ const CounterSets& GetCounterSets() const override { return m_CounterSets; }
+ const Counters& GetCounters() const override { return m_Counters; }
+
+ // Getters for profiling objects
+ const Category* GetCategory(const std::string& name) const override;
+ const Device* GetDevice(uint16_t uid) const override;
+ const CounterSet* GetCounterSet(uint16_t uid) const override;
+ const Counter* GetCounter(uint16_t uid) const override;
private:
- uint16_t m_Uid;
- std::string m_Name;
-
- uint16_t m_DeviceCount;
- uint16_t m_CounterCount;
- uint16_t m_CategoryCount;
-
- std::vector<std::atomic<uint32_t>> m_DeviceIds;
- std::vector<std::atomic<uint32_t>> m_CounterIds;
- std::vector<std::atomic<uint32_t>> m_CategoryIds;
-
- std::vector<std::atomic<Device*>> m_DeviceObjects;
- std::vector<std::atomic<Counter*>> m_CounterObjects;
- std::vector<std::atomic<Category*>> m_CategoryObjects;
-
- void CheckDeviceIndex(uint16_t index) const;
- void CheckCounterIndex(uint16_t index) const;
- void CheckCategoryIndex(uint16_t index) const;
+ // The profiling collections owned by the counter directory
+ Categories m_Categories;
+ Devices m_Devices;
+ CounterSets m_CounterSets;
+ Counters m_Counters;
+
+ // Helper functions
+ CategoriesIt FindCategory(const std::string& categoryName) const;
+ DevicesIt FindDevice(uint16_t deviceUid) const;
+ DevicesIt FindDevice(const std::string& deviceName) const;
+ CounterSetsIt FindCounterSet(uint16_t counterSetUid) const;
+ CounterSetsIt FindCounterSet(const std::string& counterSetName) const;
+ CountersIt FindCounter(uint16_t counterUid) const;
+ bool CheckIfCategoryIsRegistered(const std::string& categoryName) const;
+ bool CheckIfDeviceIsRegistered(uint16_t deviceUid) const;
+ bool CheckIfDeviceIsRegistered(const std::string& deviceName) const;
+ bool CheckIfCounterSetIsRegistered(uint16_t counterSetUid) const;
+ bool CheckIfCounterSetIsRegistered(const std::string& counterSetName) const;
+ uint16_t GetNumberOfCores(const Optional<uint16_t>& numberOfCores,
+ uint16_t deviceUid,
+ const CategoryPtr& parentCategory);
};
} // namespace profiling
diff --git a/src/profiling/ICounterDirectory.hpp b/src/profiling/ICounterDirectory.hpp
new file mode 100644
index 0000000000..c7259ab041
--- /dev/null
+++ b/src/profiling/ICounterDirectory.hpp
@@ -0,0 +1,164 @@
+//
+// Copyright © 2019 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <unordered_set>
+#include <unordered_map>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace armnn
+{
+
+namespace profiling
+{
+
+// Forward declarations
+class Category;
+class Device;
+class CounterSet;
+class Counter;
+
+// Profiling objects smart pointer types
+using CategoryPtr = std::unique_ptr<Category>;
+using DevicePtr = std::unique_ptr<Device>;
+using CounterSetPtr = std::unique_ptr<CounterSet>;
+using CounterPtr = std::shared_ptr<Counter>;
+
+// Profiling objects collection types
+using Categories = std::unordered_set<CategoryPtr>;
+using Devices = std::unordered_map<uint16_t, DevicePtr>;
+using CounterSets = std::unordered_map<uint16_t, CounterSetPtr>;
+using Counters = std::unordered_map<uint16_t, CounterPtr>;
+
+// Profiling objects collection iterator types
+using CategoriesIt = Categories::const_iterator;
+using DevicesIt = Devices::const_iterator;
+using CounterSetsIt = CounterSets::const_iterator;
+using CountersIt = Counters::const_iterator;
+
+class Category final
+{
+public:
+ // Constructors
+ Category(const std::string& name, uint16_t deviceUid, uint16_t counterSetUid)
+ : m_Name(name)
+ , m_DeviceUid(deviceUid)
+ , m_CounterSetUid(counterSetUid)
+ {}
+
+ // Fields
+ std::string m_Name;
+
+ // Connections
+ std::vector<uint16_t> m_Counters; // The UIDs of the counters associated with this category
+ uint16_t m_DeviceUid; // Optional, set to zero if the counter is not associated with a device
+ uint16_t m_CounterSetUid; // Optional, set to zero if the counter is not associated with a counter set
+};
+
+class Device final
+{
+public:
+ // Constructors
+ Device(uint16_t deviceUid, const std::string& name, uint16_t cores)
+ : m_Uid(deviceUid)
+ , m_Name(name)
+ , m_Cores(cores)
+ {}
+
+ // Fields
+ uint16_t m_Uid;
+ std::string m_Name;
+ uint16_t m_Cores;
+};
+
+class CounterSet final
+{
+public:
+ // Constructors
+ CounterSet(uint16_t counterSetUid, const std::string& name, uint16_t count)
+ : m_Uid(counterSetUid)
+ , m_Name(name)
+ , m_Count(count)
+ {}
+
+ // Fields
+ uint16_t m_Uid;
+ std::string m_Name;
+ uint16_t m_Count;
+};
+
+class Counter final
+{
+public:
+ // Constructors
+ Counter(uint16_t counterUid,
+ uint16_t maxCounterUid,
+ uint16_t counterClass,
+ uint16_t interpolation,
+ double multiplier,
+ const std::string& name,
+ const std::string& description,
+ const std::string& units,
+ uint16_t deviceUid,
+ uint16_t counterSetUid)
+ : m_Uid(counterUid)
+ , m_MaxCounterUid(maxCounterUid)
+ , m_Class(counterClass)
+ , m_Interpolation(interpolation)
+ , m_Multiplier(multiplier)
+ , m_Name(name)
+ , m_Description(description)
+ , m_Units(units)
+ , m_DeviceUid(deviceUid)
+ , m_CounterSetUid(counterSetUid)
+ {}
+
+ // Fields
+ uint16_t m_Uid;
+ uint16_t m_MaxCounterUid;
+ uint16_t m_Class;
+ uint16_t m_Interpolation;
+ double m_Multiplier;
+ std::string m_Name;
+ std::string m_Description;
+ std::string m_Units; // Optional, leave empty if the counter does not need units
+
+ // Connections
+ uint16_t m_DeviceUid; // Optional, set to zero if the counter is not associated with a device
+ uint16_t m_CounterSetUid; // Optional, set to zero if the counter is not associated with a counter set
+};
+
+class ICounterDirectory
+{
+public:
+ virtual ~ICounterDirectory() {}
+
+ // Getters for counts
+ virtual uint16_t GetCategoryCount() const = 0;
+ virtual uint16_t GetDeviceCount() const = 0;
+ virtual uint16_t GetCounterSetCount() const = 0;
+ virtual uint16_t GetCounterCount() const = 0;
+
+ // Getters for collections
+ virtual const Categories& GetCategories() const = 0;
+ virtual const Devices& GetDevices() const = 0;
+ virtual const CounterSets& GetCounterSets() const = 0;
+ virtual const Counters& GetCounters() const = 0;
+
+ // Getters for profiling objects
+ virtual const Category* GetCategory(const std::string& name) const = 0;
+ virtual const Device* GetDevice(uint16_t uid) const = 0;
+ virtual const CounterSet* GetCounterSet(uint16_t uid) const = 0;
+ virtual const Counter* GetCounter(uint16_t uid) const = 0;
+};
+
+} // namespace profiling
+
+} // namespace armnn
diff --git a/src/profiling/ProfilingUtils.cpp b/src/profiling/ProfilingUtils.cpp
index ef67f0324c..e356ed739e 100644
--- a/src/profiling/ProfilingUtils.cpp
+++ b/src/profiling/ProfilingUtils.cpp
@@ -6,12 +6,12 @@
#include "ProfilingUtils.hpp"
#include <armnn/Version.hpp>
+#include <armnn/Conversion.hpp>
#include <boost/assert.hpp>
#include <fstream>
#include <limits>
-#include <mutex>
namespace armnn
{
@@ -19,25 +19,72 @@ namespace armnn
namespace profiling
{
-uint16_t GetNextUid()
+namespace
{
- // Static mutex for reading and modifying the global UID a single thread at the time
- static std::mutex mutex;
- std::unique_lock<std::mutex> lock(mutex);
+void ThrowIfCantGenerateNextUid(uint16_t uid, uint16_t cores = 0)
+{
+ // Check that it is possible to generate the next UID without causing an overflow
+ switch (cores)
+ {
+ case 0:
+ case 1:
+ // Number of cores not specified or set to 1 (a value of zero indicates the device is not capable of
+ // running multiple parallel workloads and will not provide multiple streams of data for each event)
+ if (uid == std::numeric_limits<uint16_t>::max())
+ {
+ throw RuntimeException("Generating the next UID for profiling would result in an overflow");
+ }
+ break;
+ default: // cores > 1
+ // Multiple cores available, as max_counter_uid has to be set to: counter_uid + cores - 1, the maximum
+ // allowed value for a counter UID is consequently: uint16_t_max - cores + 1
+ if (uid >= std::numeric_limits<uint16_t>::max() - cores + 1)
+ {
+ throw RuntimeException("Generating the next UID for profiling would result in an overflow");
+ }
+ break;
+ }
+}
+
+} // Anonymous namespace
+
+uint16_t GetNextUid(bool peekOnly)
+{
// The UID used for profiling objects and events. The first valid UID is 1, as 0 is a reserved value
- // (it is used to indicate that a record is not associated with any device)
- static uint16_t uid{ 0 };
+ static uint16_t uid = 1;
- // Check that it is possible to generate the next UID without causing an overflow
- if (uid == std::numeric_limits<uint16_t>::max())
+ // Check that it is possible to generate the next UID without causing an overflow (throws in case of error)
+ ThrowIfCantGenerateNextUid(uid);
+
+ if (peekOnly)
+ {
+ // Peek only
+ return uid;
+ }
+ else
{
- throw RuntimeException("Generating the next UID for profiling would result in an overflow");
+ // Get the next UID
+ return uid++;
}
+}
- // Thread safe increment, the value that is incremented is the value checked for overflow,
- // as this whole function is mutexed
- return ++uid;
+std::vector<uint16_t> GetNextCounterUids(uint16_t cores)
+{
+ // The UID used for counters only. The first valid UID is 0
+ static uint16_t counterUid = 0;
+
+ // Check that it is possible to generate the next counter UID without causing an overflow (throws in case of error)
+ ThrowIfCantGenerateNextUid(counterUid, cores);
+
+ // Get the next counter UIDs
+ size_t counterUidsSize = cores == 0 ? 1 : cores;
+ std::vector<uint16_t> counterUids(counterUidsSize, 0);
+ for (size_t i = 0; i < counterUidsSize; i++)
+ {
+ counterUids[i] = counterUid++;
+ }
+ return counterUids;
}
void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value)
diff --git a/src/profiling/ProfilingUtils.hpp b/src/profiling/ProfilingUtils.hpp
index 0e94e612d9..793f94d91b 100644
--- a/src/profiling/ProfilingUtils.hpp
+++ b/src/profiling/ProfilingUtils.hpp
@@ -7,8 +7,12 @@
#include <armnn/Exceptions.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
#include <string>
-#include <stdint.h>
+#include <vector>
+#include <algorithm>
+#include <cstring>
namespace armnn
{
@@ -16,7 +20,65 @@ namespace armnn
namespace profiling
{
-uint16_t GetNextUid();
+struct SwTraceCharPolicy
+{
+ static bool IsValidChar(unsigned char c)
+ {
+ // Check that the given character has ASCII 7-bit encoding
+ return c < 128;
+ }
+};
+
+struct SwTraceNameCharPolicy
+{
+ static bool IsValidChar(unsigned char c)
+ {
+ // Check that the given character has ASCII 7-bit encoding, alpha-numeric and underscore only
+ return c < 128 && (std::isalnum(c) || c == '_');
+ }
+};
+
+template <typename SwTracePolicy>
+bool IsValidSwTraceString(const std::string& s)
+{
+ // Check that all the characters in the given string conform to the given policy
+ return std::all_of(s.begin(), s.end(), [](unsigned char c)
+ {
+ return SwTracePolicy::IsValidChar(c);
+ });
+}
+
+template <typename SwTracePolicy>
+bool StringToSwTraceString(const std::string& s, std::vector<uint32_t>& outputBuffer)
+{
+ // Converts the given string to an SWTrace "string" (i.e. a string of "chars"), and writes it into
+ // the given buffer including the null-terminator. It also pads it to the next uint32_t if necessary
+
+ // Clear the output buffer
+ outputBuffer.clear();
+
+ // Check that the given string is a valid SWTrace "string" (i.e. a string of "chars")
+ if (!IsValidSwTraceString<SwTracePolicy>(s))
+ {
+ return false;
+ }
+
+ // Prepare the output buffer
+ size_t s_size = s.size() + 1; // The size of the string (in chars) plus the null-terminator
+ size_t uint32_t_size = sizeof(uint32_t);
+ size_t outBufferSize = 1 + s_size / uint32_t_size + (s_size % uint32_t_size != 0 ? 1 : 0);
+ outputBuffer.resize(outBufferSize, '\0');
+
+ // Write the SWTrace string to the output buffer
+ outputBuffer[0] = boost::numeric_cast<uint32_t>(s_size);
+ std::memcpy(outputBuffer.data() + 1, s.data(), s_size);
+
+ return true;
+}
+
+uint16_t GetNextUid(bool peekOnly = false);
+
+std::vector<uint16_t> GetNextCounterUids(uint16_t cores);
void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value);
diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp
index 55524a4dfe..d16479a46c 100644
--- a/src/profiling/test/ProfilingTests.cpp
+++ b/src/profiling/test/ProfilingTests.cpp
@@ -3,23 +3,24 @@
// SPDX-License-Identifier: MIT
//
-#include "../CommandHandlerKey.hpp"
-#include "../CommandHandlerFunctor.hpp"
-#include "../CommandHandlerRegistry.hpp"
-#include "../EncodeVersion.hpp"
-#include "../Holder.hpp"
-#include "../Packet.hpp"
-#include "../PacketVersionResolver.hpp"
-#include "../ProfilingService.hpp"
-#include "../ProfilingStateMachine.hpp"
-#include "../PeriodicCounterSelectionCommandHandler.hpp"
-#include "../ProfilingUtils.hpp"
-#include "../SocketProfilingConnection.hpp"
-#include "../IPeriodicCounterCapture.hpp"
#include "SendCounterPacketTests.hpp"
+#include <CommandHandlerKey.hpp>
+#include <CommandHandlerFunctor.hpp>
+#include <CommandHandlerRegistry.hpp>
+#include <CounterDirectory.hpp>
+#include <EncodeVersion.hpp>
+#include <Holder.hpp>
+#include <Packet.hpp>
+#include <PacketVersionResolver.hpp>
+#include <PeriodicCounterSelectionCommandHandler.hpp>
+#include <ProfilingStateMachine.hpp>
+#include <ProfilingService.hpp>
+#include <ProfilingUtils.hpp>
#include <Runtime.hpp>
+#include <SocketProfilingConnection.hpp>
+#include <armnn/Conversion.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/numeric/conversion/cast.hpp>
@@ -538,30 +539,909 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime)
BOOST_CHECK(service.GetCurrentState() == ProfilingState::WaitingForAck);
}
-void GetNextUidTestImpl(uint16_t& outUid)
+BOOST_AUTO_TEST_CASE(CheckProfilingObjectUids)
{
- outUid = GetNextUid();
+ uint16_t uid = 0;
+ BOOST_CHECK_NO_THROW(uid = GetNextUid());
+ BOOST_CHECK(uid >= 1);
+
+ uint16_t nextUid = 0;
+ BOOST_CHECK_NO_THROW(nextUid = GetNextUid());
+ BOOST_CHECK(nextUid > uid);
+
+ std::vector<uint16_t> counterUids;
+ BOOST_CHECK_NO_THROW(counterUids = GetNextCounterUids(0));
+ BOOST_CHECK(counterUids.size() == 1);
+ BOOST_CHECK(counterUids[0] >= 0);
+
+ std::vector<uint16_t> nextCounterUids;
+ BOOST_CHECK_NO_THROW(nextCounterUids = GetNextCounterUids(1));
+ BOOST_CHECK(nextCounterUids.size() == 1);
+ BOOST_CHECK(nextCounterUids[0] > counterUids[0]);
+
+ std::vector<uint16_t> counterUidsMultiCore;
+ uint16_t numberOfCores = 13;
+ BOOST_CHECK_NO_THROW(counterUidsMultiCore = GetNextCounterUids(numberOfCores));
+ BOOST_CHECK(counterUidsMultiCore.size() == numberOfCores);
+ BOOST_CHECK(counterUidsMultiCore.front() >= nextCounterUids[0]);
+ for (size_t i = 1; i < numberOfCores; i ++)
+ {
+ BOOST_CHECK(counterUidsMultiCore[i] == counterUidsMultiCore[i - 1] + 1);
+ }
+ BOOST_CHECK(counterUidsMultiCore.back() == counterUidsMultiCore.front() + numberOfCores - 1);
}
-BOOST_AUTO_TEST_CASE(GetNextUidTest)
+BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCategory)
{
- uint16_t uid0 = 0;
- uint16_t uid1 = 0;
- uint16_t uid2 = 0;
+ CounterDirectory counterDirectory;
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+
+ // Register a category with an invalid name
+ const Category* noCategory = nullptr;
+ BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory(""), armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
+ BOOST_CHECK(!noCategory);
+
+ // Register a category with an invalid name
+ BOOST_CHECK_THROW(noCategory = counterDirectory.RegisterCategory("invalid category"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
+ BOOST_CHECK(!noCategory);
+
+ // Register a new category
+ const std::string categoryName = "some_category";
+ const Category* category = nullptr;
+ BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(category);
+ BOOST_CHECK(category->m_Name == categoryName);
+ BOOST_CHECK(category->m_Counters.empty());
+ BOOST_CHECK(category->m_DeviceUid == 0);
+ BOOST_CHECK(category->m_CounterSetUid == 0);
+
+ // Get the registered category
+ const Category* registeredCategory = counterDirectory.GetCategory(categoryName);
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(registeredCategory);
+ BOOST_CHECK(registeredCategory == category);
+
+ // Try to get a category not registered
+ const Category* notRegisteredCategory = counterDirectory.GetCategory("not_registered_category");
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(!notRegisteredCategory);
+
+ // Register a category already registered
+ const Category* anotherCategory = nullptr;
+ BOOST_CHECK_THROW(anotherCategory = counterDirectory.RegisterCategory(categoryName),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(!anotherCategory);
+
+ // Register a device for testing
+ const std::string deviceName = "some_device";
+ const Device* device = nullptr;
+ BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
+ BOOST_CHECK(device);
+ BOOST_CHECK(device->m_Uid >= 1);
+ BOOST_CHECK(device->m_Name == deviceName);
+ BOOST_CHECK(device->m_Cores == 0);
+
+ // Register a new category not associated to any device
+ const std::string categoryWoDeviceName = "some_category_without_device";
+ const Category* categoryWoDevice = nullptr;
+ BOOST_CHECK_NO_THROW(categoryWoDevice = counterDirectory.RegisterCategory(categoryWoDeviceName, 0));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
+ BOOST_CHECK(categoryWoDevice);
+ BOOST_CHECK(categoryWoDevice->m_Name == categoryWoDeviceName);
+ BOOST_CHECK(categoryWoDevice->m_Counters.empty());
+ BOOST_CHECK(categoryWoDevice->m_DeviceUid == 0);
+ BOOST_CHECK(categoryWoDevice->m_CounterSetUid == 0);
+
+ // Register a new category associated to an invalid device
+ const std::string categoryWInvalidDeviceName = "some_category_with_invalid_device";
+
+ ARMNN_NO_CONVERSION_WARN_BEGIN
+ uint16_t invalidDeviceUid = device->m_Uid + 10;
+ ARMNN_NO_CONVERSION_WARN_END
+
+ const Category* categoryWInvalidDevice = nullptr;
+ BOOST_CHECK_THROW(categoryWInvalidDevice
+ = counterDirectory.RegisterCategory(categoryWInvalidDeviceName,
+ invalidDeviceUid),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
+ BOOST_CHECK(!categoryWInvalidDevice);
+
+ // Register a new category associated to a valid device
+ const std::string categoryWValidDeviceName = "some_category_with_valid_device";
+ const Category* categoryWValidDevice = nullptr;
+ BOOST_CHECK_NO_THROW(categoryWValidDevice
+ = counterDirectory.RegisterCategory(categoryWValidDeviceName,
+ device->m_Uid));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 3);
+ BOOST_CHECK(categoryWValidDevice);
+ BOOST_CHECK(categoryWValidDevice != category);
+ BOOST_CHECK(categoryWValidDevice->m_Name == categoryWValidDeviceName);
+ BOOST_CHECK(categoryWValidDevice->m_DeviceUid == device->m_Uid);
+ BOOST_CHECK(categoryWValidDevice->m_CounterSetUid == 0);
+
+ // Register a counter set for testing
+ const std::string counterSetName = "some_counter_set";
+ const CounterSet* counterSet = nullptr;
+ BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
+ BOOST_CHECK(counterSet);
+ BOOST_CHECK(counterSet->m_Uid >= 1);
+ BOOST_CHECK(counterSet->m_Name == counterSetName);
+ BOOST_CHECK(counterSet->m_Count == 0);
+
+ // Register a new category not associated to any counter set
+ const std::string categoryWoCounterSetName = "some_category_without_counter_set";
+ const Category* categoryWoCounterSet = nullptr;
+ BOOST_CHECK_NO_THROW(categoryWoCounterSet
+ = counterDirectory.RegisterCategory(categoryWoCounterSetName,
+ armnn::EmptyOptional(),
+ 0));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
+ BOOST_CHECK(categoryWoCounterSet);
+ BOOST_CHECK(categoryWoCounterSet->m_Name == categoryWoCounterSetName);
+ BOOST_CHECK(categoryWoCounterSet->m_DeviceUid == 0);
+ BOOST_CHECK(categoryWoCounterSet->m_CounterSetUid == 0);
+
+ // Register a new category associated to an invalid counter set
+ const std::string categoryWInvalidCounterSetName = "some_category_with_invalid_counter_set";
+
+ ARMNN_NO_CONVERSION_WARN_BEGIN
+ uint16_t invalidCunterSetUid = counterSet->m_Uid + 10;
+ ARMNN_NO_CONVERSION_WARN_END
+
+ const Category* categoryWInvalidCounterSet = nullptr;
+ BOOST_CHECK_THROW(categoryWInvalidCounterSet
+ = counterDirectory.RegisterCategory(categoryWInvalidCounterSetName,
+ armnn::EmptyOptional(),
+ invalidCunterSetUid),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 4);
+ BOOST_CHECK(!categoryWInvalidCounterSet);
+
+ // Register a new category associated to a valid counter set
+ const std::string categoryWValidCounterSetName = "some_category_with_valid_counter_set";
+ const Category* categoryWValidCounterSet = nullptr;
+ BOOST_CHECK_NO_THROW(categoryWValidCounterSet
+ = counterDirectory.RegisterCategory(categoryWValidCounterSetName,
+ armnn::EmptyOptional(),
+ counterSet->m_Uid));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 5);
+ BOOST_CHECK(categoryWValidCounterSet);
+ BOOST_CHECK(categoryWValidCounterSet != category);
+ BOOST_CHECK(categoryWValidCounterSet->m_Name == categoryWValidCounterSetName);
+ BOOST_CHECK(categoryWValidCounterSet->m_DeviceUid == 0);
+ BOOST_CHECK(categoryWValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
+
+ // Register a new category associated to a valid device and counter set
+ const std::string categoryWValidDeviceAndValidCounterSetName = "some_category_with_valid_device_and_counter_set";
+ const Category* categoryWValidDeviceAndValidCounterSet = nullptr;
+ BOOST_CHECK_NO_THROW(categoryWValidDeviceAndValidCounterSet
+ = counterDirectory.RegisterCategory(categoryWValidDeviceAndValidCounterSetName,
+ device->m_Uid,
+ counterSet->m_Uid));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 6);
+ BOOST_CHECK(categoryWValidDeviceAndValidCounterSet);
+ BOOST_CHECK(categoryWValidDeviceAndValidCounterSet != category);
+ BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_Name == categoryWValidDeviceAndValidCounterSetName);
+ BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_DeviceUid == device->m_Uid);
+ BOOST_CHECK(categoryWValidDeviceAndValidCounterSet->m_CounterSetUid == counterSet->m_Uid);
+}
- std::thread thread1(GetNextUidTestImpl, std::ref(uid0));
- std::thread thread2(GetNextUidTestImpl, std::ref(uid1));
- std::thread thread3(GetNextUidTestImpl, std::ref(uid2));
- thread1.join();
- thread2.join();
- thread3.join();
+BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterDevice)
+{
+ CounterDirectory counterDirectory;
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+
+ // Register a device with an invalid name
+ const Device* noDevice = nullptr;
+ BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice(""), armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
+ BOOST_CHECK(!noDevice);
+
+ // Register a device with an invalid name
+ BOOST_CHECK_THROW(noDevice = counterDirectory.RegisterDevice("inv@lid nam€"), armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
+ BOOST_CHECK(!noDevice);
+
+ // Register a new device with no cores or parent category
+ const std::string deviceName = "some_device";
+ const Device* device = nullptr;
+ BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
+ BOOST_CHECK(device);
+ BOOST_CHECK(device->m_Name == deviceName);
+ BOOST_CHECK(device->m_Uid >= 1);
+ BOOST_CHECK(device->m_Cores == 0);
+
+ // Get the registered device
+ const Device* registeredDevice = counterDirectory.GetDevice(device->m_Uid);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
+ BOOST_CHECK(registeredDevice);
+ BOOST_CHECK(registeredDevice == device);
+
+ // Register a new device with cores and no parent category
+ const std::string deviceWCoresName = "some_device_with_cores";
+ const Device* deviceWCores = nullptr;
+ BOOST_CHECK_NO_THROW(deviceWCores = counterDirectory.RegisterDevice(deviceWCoresName, 2));
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
+ BOOST_CHECK(deviceWCores);
+ BOOST_CHECK(deviceWCores->m_Name == deviceWCoresName);
+ BOOST_CHECK(deviceWCores->m_Uid >= 1);
+ BOOST_CHECK(deviceWCores->m_Uid > device->m_Uid);
+ BOOST_CHECK(deviceWCores->m_Cores == 2);
+
+ // Get the registered device
+ const Device* registeredDeviceWCores = counterDirectory.GetDevice(deviceWCores->m_Uid);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
+ BOOST_CHECK(registeredDeviceWCores);
+ BOOST_CHECK(registeredDeviceWCores == deviceWCores);
+ BOOST_CHECK(registeredDeviceWCores != device);
+
+ // Register a new device with cores and invalid parent category
+ const std::string deviceWCoresWInvalidParentCategoryName = "some_device_with_cores_with_invalid_parent_category";
+ const Device* deviceWCoresWInvalidParentCategory = nullptr;
+ BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory
+ = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName,
+ 3,
+ std::string("")),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
+ BOOST_CHECK(!deviceWCoresWInvalidParentCategory);
+
+ // Register a new device with cores and invalid parent category
+ const std::string deviceWCoresWInvalidParentCategoryName2 = "some_device_with_cores_with_invalid_parent_category2";
+ const Device* deviceWCoresWInvalidParentCategory2 = nullptr;
+ BOOST_CHECK_THROW(deviceWCoresWInvalidParentCategory2
+ = counterDirectory.RegisterDevice(deviceWCoresWInvalidParentCategoryName2,
+ 3,
+ std::string("invalid_parent_category")),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
+ BOOST_CHECK(!deviceWCoresWInvalidParentCategory2);
+
+ // Register a category for testing
+ const std::string categoryName = "some_category";
+ const Category* category = nullptr;
+ BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(category);
+ BOOST_CHECK(category->m_Name == categoryName);
+ BOOST_CHECK(category->m_Counters.empty());
+ BOOST_CHECK(category->m_DeviceUid == 0);
+ BOOST_CHECK(category->m_CounterSetUid == 0);
+
+ // Register a new device with cores and valid parent category
+ const std::string deviceWCoresWValidParentCategoryName = "some_device_with_cores_with_valid_parent_category";
+ const Device* deviceWCoresWValidParentCategory = nullptr;
+ BOOST_CHECK_NO_THROW(deviceWCoresWValidParentCategory
+ = counterDirectory.RegisterDevice(deviceWCoresWValidParentCategoryName,
+ 4,
+ categoryName));
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 3);
+ BOOST_CHECK(deviceWCoresWValidParentCategory);
+ BOOST_CHECK(deviceWCoresWValidParentCategory->m_Name == deviceWCoresWValidParentCategoryName);
+ BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid >= 1);
+ BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > device->m_Uid);
+ BOOST_CHECK(deviceWCoresWValidParentCategory->m_Uid > deviceWCores->m_Uid);
+ BOOST_CHECK(deviceWCoresWValidParentCategory->m_Cores == 4);
+ BOOST_CHECK(category->m_DeviceUid == deviceWCoresWValidParentCategory->m_Uid);
+}
+
+BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounterSet)
+{
+ CounterDirectory counterDirectory;
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+
+ // Register a counter set with an invalid name
+ const CounterSet* noCounterSet = nullptr;
+ BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet(""), armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
+ BOOST_CHECK(!noCounterSet);
+
+ // Register a counter set with an invalid name
+ BOOST_CHECK_THROW(noCounterSet = counterDirectory.RegisterCounterSet("invalid name"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
+ BOOST_CHECK(!noCounterSet);
+
+ // Register a new counter set with no count or parent category
+ const std::string counterSetName = "some_counter_set";
+ const CounterSet* counterSet = nullptr;
+ BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
+ BOOST_CHECK(counterSet);
+ BOOST_CHECK(counterSet->m_Name == counterSetName);
+ BOOST_CHECK(counterSet->m_Uid >= 1);
+ BOOST_CHECK(counterSet->m_Count == 0);
+
+ // Get the registered counter set
+ const CounterSet* registeredCounterSet = counterDirectory.GetCounterSet(counterSet->m_Uid);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
+ BOOST_CHECK(registeredCounterSet);
+ BOOST_CHECK(registeredCounterSet == counterSet);
+
+ // Register a new counter set with count and no parent category
+ const std::string counterSetWCountName = "some_counter_set_with_count";
+ const CounterSet* counterSetWCount = nullptr;
+ BOOST_CHECK_NO_THROW(counterSetWCount = counterDirectory.RegisterCounterSet(counterSetWCountName, 37));
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
+ BOOST_CHECK(counterSetWCount);
+ BOOST_CHECK(counterSetWCount->m_Name == counterSetWCountName);
+ BOOST_CHECK(counterSetWCount->m_Uid >= 1);
+ BOOST_CHECK(counterSetWCount->m_Uid > counterSet->m_Uid);
+ BOOST_CHECK(counterSetWCount->m_Count == 37);
+
+ // Get the registered counter set
+ const CounterSet* registeredCounterSetWCount = counterDirectory.GetCounterSet(counterSetWCount->m_Uid);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
+ BOOST_CHECK(registeredCounterSetWCount);
+ BOOST_CHECK(registeredCounterSetWCount == counterSetWCount);
+ BOOST_CHECK(registeredCounterSetWCount != counterSet);
+
+ // Register a new counter set with count and invalid parent category
+ const std::string counterSetWCountWInvalidParentCategoryName = "some_counter_set_with_count_"
+ "with_invalid_parent_category";
+ const CounterSet* counterSetWCountWInvalidParentCategory = nullptr;
+ BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory
+ = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName,
+ 42,
+ std::string("")),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
+ BOOST_CHECK(!counterSetWCountWInvalidParentCategory);
+
+ // Register a new counter set with count and invalid parent category
+ const std::string counterSetWCountWInvalidParentCategoryName2 = "some_counter_set_with_count_"
+ "with_invalid_parent_category2";
+ const CounterSet* counterSetWCountWInvalidParentCategory2 = nullptr;
+ BOOST_CHECK_THROW(counterSetWCountWInvalidParentCategory2
+ = counterDirectory.RegisterCounterSet(counterSetWCountWInvalidParentCategoryName2,
+ 42,
+ std::string("invalid_parent_category")),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 2);
+ BOOST_CHECK(!counterSetWCountWInvalidParentCategory2);
+
+ // Register a category for testing
+ const std::string categoryName = "some_category";
+ const Category* category = nullptr;
+ BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(category);
+ BOOST_CHECK(category->m_Name == categoryName);
+ BOOST_CHECK(category->m_Counters.empty());
+ BOOST_CHECK(category->m_DeviceUid == 0);
+ BOOST_CHECK(category->m_CounterSetUid == 0);
+
+ // Register a new counter set with count and valid parent category
+ const std::string counterSetWCountWValidParentCategoryName = "some_counter_set_with_count_"
+ "with_valid_parent_category";
+ const CounterSet* counterSetWCountWValidParentCategory = nullptr;
+ BOOST_CHECK_NO_THROW(counterSetWCountWValidParentCategory
+ = counterDirectory.RegisterCounterSet(counterSetWCountWValidParentCategoryName,
+ 42,
+ std::string(categoryName)));
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 3);
+ BOOST_CHECK(counterSetWCountWValidParentCategory);
+ BOOST_CHECK(counterSetWCountWValidParentCategory->m_Name == counterSetWCountWValidParentCategoryName);
+ BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid >= 1);
+ BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSet->m_Uid);
+ BOOST_CHECK(counterSetWCountWValidParentCategory->m_Uid > counterSetWCount->m_Uid);
+ BOOST_CHECK(counterSetWCountWValidParentCategory->m_Count == 42);
+ BOOST_CHECK(category->m_CounterSetUid == counterSetWCountWValidParentCategory->m_Uid);
+}
+
+BOOST_AUTO_TEST_CASE(CheckCounterDirectoryRegisterCounter)
+{
+ CounterDirectory counterDirectory;
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 0);
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 0);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+
+ // Register a counter with an invalid parent category name
+ const Counter* noCounter = nullptr;
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("",
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid parent category name
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid parent category",
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid class
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 2,
+ 1,
+ 123.45f,
+ "valid name",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid interpolation
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 3,
+ 123.45f,
+ "valid name",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid multiplier
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 1,
+ .0f,
+ "valid name",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid name
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 1,
+ 123.45f,
+ "",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid name
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 1,
+ 123.45f,
+ "invalid nam€",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid description
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ ""),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid description
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ "inv@lid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with an invalid unit2
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("valid_parent_category",
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ "valid description",
+ std::string("Mb/s2")),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with a non-existing parent category name
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter("invalid_parent_category",
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ "valid description"),
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 0);
+ BOOST_CHECK(!noCounter);
+
+ // Register a category for testing
+ const std::string categoryName = "some_category";
+ const Category* category = nullptr;
+ BOOST_CHECK_NO_THROW(category = counterDirectory.RegisterCategory(categoryName));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 1);
+ BOOST_CHECK(category);
+ BOOST_CHECK(category->m_Name == categoryName);
+ BOOST_CHECK(category->m_Counters.empty());
+ BOOST_CHECK(category->m_DeviceUid == 0);
+ BOOST_CHECK(category->m_CounterSetUid == 0);
+
+ // Register a counter with a valid parent category name
+ const Counter* counter = nullptr;
+ BOOST_CHECK_NO_THROW(counter = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name",
+ "valid description"));
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 1);
+ BOOST_CHECK(counter);
+ BOOST_CHECK(counter->m_Uid >= 0);
+ BOOST_CHECK(counter->m_MaxCounterUid == counter->m_Uid);
+ BOOST_CHECK(counter->m_Class == 0);
+ BOOST_CHECK(counter->m_Interpolation == 1);
+ BOOST_CHECK(counter->m_Multiplier == 123.45f);
+ BOOST_CHECK(counter->m_Name == "valid name");
+ BOOST_CHECK(counter->m_Description == "valid description");
+ BOOST_CHECK(counter->m_Units == "");
+ BOOST_CHECK(counter->m_DeviceUid == 0);
+ BOOST_CHECK(counter->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 1);
+ BOOST_CHECK(category->m_Counters.back() == counter->m_Uid);
+
+ // Register a counter with a valid parent category name and units
+ const Counter* counterWUnits = nullptr;
+ BOOST_CHECK_NO_THROW(counterWUnits = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 2",
+ "valid description",
+ std::string("Mnnsq2"))); // Units
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 2);
+ BOOST_CHECK(counterWUnits);
+ BOOST_CHECK(counterWUnits->m_Uid >= 0);
+ BOOST_CHECK(counterWUnits->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWUnits->m_MaxCounterUid == counterWUnits->m_Uid);
+ BOOST_CHECK(counterWUnits->m_Class == 0);
+ BOOST_CHECK(counterWUnits->m_Interpolation == 1);
+ BOOST_CHECK(counterWUnits->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWUnits->m_Name == "valid name 2");
+ BOOST_CHECK(counterWUnits->m_Description == "valid description");
+ BOOST_CHECK(counterWUnits->m_Units == "Mnnsq2");
+ BOOST_CHECK(counterWUnits->m_DeviceUid == 0);
+ BOOST_CHECK(counterWUnits->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 2);
+ BOOST_CHECK(category->m_Counters.back() == counterWUnits->m_Uid);
+
+ // Register a counter with a valid parent category name and not associated with a device
+ const Counter* counterWoDevice = nullptr;
+ BOOST_CHECK_NO_THROW(counterWoDevice = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 3",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ 0)); // Device UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
+ BOOST_CHECK(counterWoDevice);
+ BOOST_CHECK(counterWoDevice->m_Uid >= 0);
+ BOOST_CHECK(counterWoDevice->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWoDevice->m_MaxCounterUid == counterWoDevice->m_Uid);
+ BOOST_CHECK(counterWoDevice->m_Class == 0);
+ BOOST_CHECK(counterWoDevice->m_Interpolation == 1);
+ BOOST_CHECK(counterWoDevice->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWoDevice->m_Name == "valid name 3");
+ BOOST_CHECK(counterWoDevice->m_Description == "valid description");
+ BOOST_CHECK(counterWoDevice->m_Units == "");
+ BOOST_CHECK(counterWoDevice->m_DeviceUid == 0);
+ BOOST_CHECK(counterWoDevice->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 3);
+ BOOST_CHECK(category->m_Counters.back() == counterWoDevice->m_Uid);
+
+ // Register a counter with a valid parent category name and associated to an invalid device
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 4",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ 100), // Device UID
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 3);
+ BOOST_CHECK(!noCounter);
+
+ // Register a device for testing
+ const std::string deviceName = "some_device";
+ const Device* device = nullptr;
+ BOOST_CHECK_NO_THROW(device = counterDirectory.RegisterDevice(deviceName));
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 1);
+ BOOST_CHECK(device);
+ BOOST_CHECK(device->m_Name == deviceName);
+ BOOST_CHECK(device->m_Uid >= 1);
+ BOOST_CHECK(device->m_Cores == 0);
+
+ // Register a counter with a valid parent category name and associated to a device
+ const Counter* counterWDevice = nullptr;
+ BOOST_CHECK_NO_THROW(counterWDevice = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 5",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ device->m_Uid)); // Device UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 4);
+ BOOST_CHECK(counterWDevice);
+ BOOST_CHECK(counterWDevice->m_Uid >= 0);
+ BOOST_CHECK(counterWDevice->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWDevice->m_MaxCounterUid == counterWDevice->m_Uid);
+ BOOST_CHECK(counterWDevice->m_Class == 0);
+ BOOST_CHECK(counterWDevice->m_Interpolation == 1);
+ BOOST_CHECK(counterWDevice->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWDevice->m_Name == "valid name 5");
+ BOOST_CHECK(counterWDevice->m_Description == "valid description");
+ BOOST_CHECK(counterWDevice->m_Units == "");
+ BOOST_CHECK(counterWDevice->m_DeviceUid == device->m_Uid);
+ BOOST_CHECK(counterWDevice->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 4);
+ BOOST_CHECK(category->m_Counters.back() == counterWDevice->m_Uid);
+
+ // Register a counter with a valid parent category name and not associated with a counter set
+ const Counter* counterWoCounterSet = nullptr;
+ BOOST_CHECK_NO_THROW(counterWoCounterSet
+ = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 6",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ armnn::EmptyOptional(), // Device UID
+ 0)); // Counter set UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
+ BOOST_CHECK(counterWoCounterSet);
+ BOOST_CHECK(counterWoCounterSet->m_Uid >= 0);
+ BOOST_CHECK(counterWoCounterSet->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWoCounterSet->m_MaxCounterUid == counterWoCounterSet->m_Uid);
+ BOOST_CHECK(counterWoCounterSet->m_Class == 0);
+ BOOST_CHECK(counterWoCounterSet->m_Interpolation == 1);
+ BOOST_CHECK(counterWoCounterSet->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWoCounterSet->m_Name == "valid name 6");
+ BOOST_CHECK(counterWoCounterSet->m_Description == "valid description");
+ BOOST_CHECK(counterWoCounterSet->m_Units == "");
+ BOOST_CHECK(counterWoCounterSet->m_DeviceUid == 0);
+ BOOST_CHECK(counterWoCounterSet->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 5);
+ BOOST_CHECK(category->m_Counters.back() == counterWoCounterSet->m_Uid);
+
+ // Register a counter with a valid parent category name and associated to an invalid counter set
+ BOOST_CHECK_THROW(noCounter = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 7",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ armnn::EmptyOptional(), // Device UID
+ 100), // Counter set UID
+ armnn::InvalidArgumentException);
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 5);
+ BOOST_CHECK(!noCounter);
+
+ // Register a counter with a valid parent category name and with a given number of cores
+ const Counter* counterWNumberOfCores = nullptr;
+ uint16_t numberOfCores = 15;
+ BOOST_CHECK_NO_THROW(counterWNumberOfCores
+ = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 8",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ numberOfCores, // Number of cores
+ armnn::EmptyOptional(), // Device UID
+ armnn::EmptyOptional())); // Counter set UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 20);
+ BOOST_CHECK(counterWNumberOfCores);
+ BOOST_CHECK(counterWNumberOfCores->m_Uid >= 0);
+ BOOST_CHECK(counterWNumberOfCores->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWNumberOfCores->m_MaxCounterUid == counterWNumberOfCores->m_Uid + numberOfCores - 1);
+ BOOST_CHECK(counterWNumberOfCores->m_Class == 0);
+ BOOST_CHECK(counterWNumberOfCores->m_Interpolation == 1);
+ BOOST_CHECK(counterWNumberOfCores->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWNumberOfCores->m_Name == "valid name 8");
+ BOOST_CHECK(counterWNumberOfCores->m_Description == "valid description");
+ BOOST_CHECK(counterWNumberOfCores->m_Units == "");
+ BOOST_CHECK(counterWNumberOfCores->m_DeviceUid == 0);
+ BOOST_CHECK(counterWNumberOfCores->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 20);
+ for (size_t i = 0; i < numberOfCores; i ++)
+ {
+ BOOST_CHECK(category->m_Counters[category->m_Counters.size() - numberOfCores + i] ==
+ counterWNumberOfCores->m_Uid + i);
+ }
+
+ // Register a multi-core device for testing
+ const std::string multiCoreDeviceName = "some_multi_core_device";
+ const Device* multiCoreDevice = nullptr;
+ BOOST_CHECK_NO_THROW(multiCoreDevice = counterDirectory.RegisterDevice(multiCoreDeviceName, 4));
+ BOOST_CHECK(counterDirectory.GetDeviceCount() == 2);
+ BOOST_CHECK(multiCoreDevice);
+ BOOST_CHECK(multiCoreDevice->m_Name == multiCoreDeviceName);
+ BOOST_CHECK(multiCoreDevice->m_Uid >= 1);
+ BOOST_CHECK(multiCoreDevice->m_Cores == 4);
+
+ // Register a counter with a valid parent category name and associated to the multi-core device
+ const Counter* counterWMultiCoreDevice = nullptr;
+ BOOST_CHECK_NO_THROW(counterWMultiCoreDevice
+ = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 9",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ multiCoreDevice->m_Uid, // Device UID
+ armnn::EmptyOptional())); // Counter set UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 24);
+ BOOST_CHECK(counterWMultiCoreDevice);
+ BOOST_CHECK(counterWMultiCoreDevice->m_Uid >= 0);
+ BOOST_CHECK(counterWMultiCoreDevice->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWMultiCoreDevice->m_MaxCounterUid ==
+ counterWMultiCoreDevice->m_Uid + multiCoreDevice->m_Cores - 1);
+ BOOST_CHECK(counterWMultiCoreDevice->m_Class == 0);
+ BOOST_CHECK(counterWMultiCoreDevice->m_Interpolation == 1);
+ BOOST_CHECK(counterWMultiCoreDevice->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWMultiCoreDevice->m_Name == "valid name 9");
+ BOOST_CHECK(counterWMultiCoreDevice->m_Description == "valid description");
+ BOOST_CHECK(counterWMultiCoreDevice->m_Units == "");
+ BOOST_CHECK(counterWMultiCoreDevice->m_DeviceUid == multiCoreDevice->m_Uid);
+ BOOST_CHECK(counterWMultiCoreDevice->m_CounterSetUid == 0);
+ BOOST_CHECK(category->m_Counters.size() == 24);
+ for (size_t i = 0; i < 4; i ++)
+ {
+ BOOST_CHECK(category->m_Counters[category->m_Counters.size() - 4 + i] == counterWMultiCoreDevice->m_Uid + i);
+ }
- BOOST_TEST(uid0 > 0);
- BOOST_TEST(uid1 > 0);
- BOOST_TEST(uid2 > 0);
- BOOST_TEST(uid0 != uid1);
- BOOST_TEST(uid0 != uid2);
- BOOST_TEST(uid1 != uid2);
+ // Register a counter set for testing
+ const std::string counterSetName = "some_counter_set";
+ const CounterSet* counterSet = nullptr;
+ BOOST_CHECK_NO_THROW(counterSet = counterDirectory.RegisterCounterSet(counterSetName));
+ BOOST_CHECK(counterDirectory.GetCounterSetCount() == 1);
+ BOOST_CHECK(counterSet);
+ BOOST_CHECK(counterSet->m_Name == counterSetName);
+ BOOST_CHECK(counterSet->m_Uid >= 1);
+ BOOST_CHECK(counterSet->m_Count == 0);
+
+ // Register a counter with a valid parent category name and associated to a counter set
+ const Counter* counterWCounterSet = nullptr;
+ BOOST_CHECK_NO_THROW(counterWCounterSet
+ = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 10",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ armnn::EmptyOptional(), // Device UID
+ counterSet->m_Uid)); // Counter set UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 25);
+ BOOST_CHECK(counterWCounterSet);
+ BOOST_CHECK(counterWCounterSet->m_Uid >= 0);
+ BOOST_CHECK(counterWCounterSet->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWCounterSet->m_MaxCounterUid == counterWCounterSet->m_Uid);
+ BOOST_CHECK(counterWCounterSet->m_Class == 0);
+ BOOST_CHECK(counterWCounterSet->m_Interpolation == 1);
+ BOOST_CHECK(counterWCounterSet->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWCounterSet->m_Name == "valid name 10");
+ BOOST_CHECK(counterWCounterSet->m_Description == "valid description");
+ BOOST_CHECK(counterWCounterSet->m_Units == "");
+ BOOST_CHECK(counterWCounterSet->m_DeviceUid == 0);
+ BOOST_CHECK(counterWCounterSet->m_CounterSetUid == counterSet->m_Uid);
+ BOOST_CHECK(category->m_Counters.size() == 25);
+ BOOST_CHECK(category->m_Counters.back() == counterWCounterSet->m_Uid);
+
+ // Register a counter with a valid parent category name and associated to a device and a counter set
+ const Counter* counterWDeviceWCounterSet = nullptr;
+ BOOST_CHECK_NO_THROW(counterWDeviceWCounterSet
+ = counterDirectory.RegisterCounter(categoryName,
+ 0,
+ 1,
+ 123.45f,
+ "valid name 11",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ device->m_Uid, // Device UID
+ counterSet->m_Uid)); // Counter set UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 26);
+ BOOST_CHECK(counterWDeviceWCounterSet);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Uid >= 0);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Uid > counter->m_Uid);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_MaxCounterUid == counterWDeviceWCounterSet->m_Uid);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Class == 0);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Interpolation == 1);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Multiplier == 123.45f);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Name == "valid name 11");
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Description == "valid description");
+ BOOST_CHECK(counterWDeviceWCounterSet->m_Units == "");
+ BOOST_CHECK(counterWDeviceWCounterSet->m_DeviceUid == device->m_Uid);
+ BOOST_CHECK(counterWDeviceWCounterSet->m_CounterSetUid == counterSet->m_Uid);
+ BOOST_CHECK(category->m_Counters.size() == 26);
+ BOOST_CHECK(category->m_Counters.back() == counterWDeviceWCounterSet->m_Uid);
+
+ // Register another category for testing
+ const std::string anotherCategoryName = "some_other_category";
+ const Category* anotherCategory = nullptr;
+ BOOST_CHECK_NO_THROW(anotherCategory = counterDirectory.RegisterCategory(anotherCategoryName));
+ BOOST_CHECK(counterDirectory.GetCategoryCount() == 2);
+ BOOST_CHECK(anotherCategory);
+ BOOST_CHECK(anotherCategory != category);
+ BOOST_CHECK(anotherCategory->m_Name == anotherCategoryName);
+ BOOST_CHECK(anotherCategory->m_Counters.empty());
+ BOOST_CHECK(anotherCategory->m_DeviceUid == 0);
+ BOOST_CHECK(anotherCategory->m_CounterSetUid == 0);
+
+ // Register a counter to the other category
+ const Counter* anotherCounter = nullptr;
+ BOOST_CHECK_NO_THROW(anotherCounter = counterDirectory.RegisterCounter(anotherCategoryName,
+ 1,
+ 0,
+ .00043f,
+ "valid name",
+ "valid description",
+ armnn::EmptyOptional(), // Units
+ armnn::EmptyOptional(), // Number of cores
+ device->m_Uid, // Device UID
+ counterSet->m_Uid)); // Counter set UID
+ BOOST_CHECK(counterDirectory.GetCounterCount() == 27);
+ BOOST_CHECK(anotherCounter);
+ BOOST_CHECK(anotherCounter->m_Uid >= 0);
+ BOOST_CHECK(anotherCounter->m_MaxCounterUid == anotherCounter->m_Uid);
+ BOOST_CHECK(anotherCounter->m_Class == 1);
+ BOOST_CHECK(anotherCounter->m_Interpolation == 0);
+ BOOST_CHECK(anotherCounter->m_Multiplier == .00043f);
+ BOOST_CHECK(anotherCounter->m_Name == "valid name");
+ BOOST_CHECK(anotherCounter->m_Description == "valid description");
+ BOOST_CHECK(anotherCounter->m_Units == "");
+ BOOST_CHECK(anotherCounter->m_DeviceUid == device->m_Uid);
+ BOOST_CHECK(anotherCounter->m_CounterSetUid == counterSet->m_Uid);
+ BOOST_CHECK(anotherCategory->m_Counters.size() == 1);
+ BOOST_CHECK(anotherCategory->m_Counters.back() == anotherCounter->m_Uid);
}
BOOST_AUTO_TEST_CASE(CounterSelectionCommandHandlerParseData)
diff --git a/src/profiling/test/SendCounterPacketTests.cpp b/src/profiling/test/SendCounterPacketTests.cpp
index 4435ab67a3..c060f168cd 100644
--- a/src/profiling/test/SendCounterPacketTests.cpp
+++ b/src/profiling/test/SendCounterPacketTests.cpp
@@ -3,11 +3,12 @@
// SPDX-License-Identifier: MIT
//
-#include "../ProfilingUtils.hpp"
-#include "../EncodeVersion.hpp"
-#include "../SendCounterPacket.hpp"
#include "SendCounterPacketTests.hpp"
+#include <ProfilingUtils.hpp>
+#include <EncodeVersion.hpp>
+#include <SendCounterPacket.hpp>
+
#include <armnn/Exceptions.hpp>
#include <boost/test/unit_test.hpp>
@@ -30,7 +31,7 @@ BOOST_AUTO_TEST_CASE(MockSendCounterPacketTest)
BOOST_TEST(strcmp(buffer, "SendStreamMetaDataPacket") == 0);
- CounterDirectory counterDirectory(1, "counter_directory", 0, 0, 0);
+ CounterDirectory counterDirectory;
sendCounterPacket.SendCounterDirectoryPacket(counterDirectory);
BOOST_TEST(strcmp(buffer, "SendCounterDirectoryPacket") == 0);