From 9789702c0b276ca9518e590f30465da7e76a940f Mon Sep 17 00:00:00 2001 From: Jim Flynn Date: Sun, 2 Feb 2020 12:52:59 +0000 Subject: IVGCVSW-4393 Register backend counters Signed-off-by: David Monahan Change-Id: I419ecc2fce4b7e0fcaeb6d1f9cb687c0b660125d Signed-off-by: Jim Flynn --- Android.mk | 1 + CMakeLists.txt | 3 + .../armnn/backends/profiling/IBackendProfiling.hpp | 50 +++++++------ src/profiling/CounterDirectory.hpp | 14 ++-- src/profiling/CounterIdMap.cpp | 6 ++ src/profiling/CounterIdMap.hpp | 2 + src/profiling/ICounterRegistry.hpp | 52 +++++++++++++ src/profiling/ProfilingService.cpp | 8 +- src/profiling/ProfilingService.hpp | 4 +- src/profiling/RegisterBackendCounters.cpp | 87 ++++++++++++++++++++++ src/profiling/RegisterBackendCounters.hpp | 62 +++++++++++++++ src/profiling/test/ProfilingTests.cpp | 51 +++++++++++++ 12 files changed, 306 insertions(+), 34 deletions(-) create mode 100644 src/profiling/ICounterRegistry.hpp create mode 100644 src/profiling/RegisterBackendCounters.cpp create mode 100644 src/profiling/RegisterBackendCounters.hpp diff --git a/Android.mk b/Android.mk index 9a38a7228d..65e5380c87 100644 --- a/Android.mk +++ b/Android.mk @@ -199,6 +199,7 @@ LOCAL_SRC_FILES := \ src/profiling/ProfilingService.cpp \ src/profiling/ProfilingStateMachine.cpp \ src/profiling/ProfilingUtils.cpp \ + src/profiling/RegisterBackendCounters.cpp \ src/profiling/RequestCounterDirectoryCommandHandler.cpp \ src/profiling/SendCounterPacket.cpp \ src/profiling/SendTimelinePacket.cpp \ diff --git a/CMakeLists.txt b/CMakeLists.txt index c811ee5b54..950ad4a946 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -470,6 +470,7 @@ list(APPEND armnn_sources src/profiling/Holder.hpp src/profiling/IBufferManager.hpp src/profiling/ICounterDirectory.hpp + src/profiling/ICounterRegistry.hpp src/profiling/ICounterValues.hpp src/profiling/ISendCounterPacket.hpp src/profiling/IPacketBuffer.hpp @@ -500,6 +501,8 @@ list(APPEND armnn_sources src/profiling/ProfilingStateMachine.hpp src/profiling/ProfilingUtils.cpp src/profiling/ProfilingUtils.hpp + src/profiling/RegisterBackendCounters.cpp + src/profiling/RegisterBackendCounters.hpp src/profiling/RequestCounterDirectoryCommandHandler.cpp src/profiling/RequestCounterDirectoryCommandHandler.hpp src/profiling/SendCounterPacket.cpp diff --git a/include/armnn/backends/profiling/IBackendProfiling.hpp b/include/armnn/backends/profiling/IBackendProfiling.hpp index 6ed7aba97d..4c463a8128 100644 --- a/include/armnn/backends/profiling/IBackendProfiling.hpp +++ b/include/armnn/backends/profiling/IBackendProfiling.hpp @@ -39,29 +39,31 @@ struct CounterStatus class IRegisterBackendCounters { public: - uint16_t RegisterCategory(const std::string& categoryName, - const Optional& deviceUid = EmptyOptional(), - const Optional& counterSetUid = EmptyOptional()); - - uint16_t RegisterDevice(const std::string& deviceName, - uint16_t cores = 0, - const Optional& parentCategoryName = EmptyOptional()); - - uint16_t RegisterCounterSet(const std::string& counterSetName, - uint16_t count = 0, - const Optional& parentCategoryName = EmptyOptional()); - - uint16_t RegisterCounter(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& units = EmptyOptional(), - const Optional& numberOfCores = EmptyOptional(), - const Optional& deviceUid = EmptyOptional(), - const Optional& counterSetUid = EmptyOptional()); + virtual void RegisterCategory(const std::string& categoryName, + const Optional& deviceUid = EmptyOptional(), + const Optional& counterSetUid = EmptyOptional()) = 0; + + virtual uint16_t RegisterDevice(const std::string& deviceName, + uint16_t cores = 0, + const Optional& parentCategoryName = EmptyOptional()) = 0; + + virtual uint16_t RegisterCounterSet(const std::string& counterSetName, + uint16_t count = 0, + const Optional& parentCategoryName = EmptyOptional()) = 0; + + virtual uint16_t RegisterCounter(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& units = EmptyOptional(), + const Optional& numberOfCores = EmptyOptional(), + const Optional& deviceUid = EmptyOptional(), + const Optional& counterSetUid = EmptyOptional()) = 0; + + virtual ~IRegisterBackendCounters() {} }; class IBackendProfiling @@ -74,7 +76,7 @@ public: virtual ~IBackendProfiling() {} - IRegisterBackendCounters GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID); + IRegisterBackendCounters& GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID); ISendTimelinePacket& GetSendTimelinePacket(); diff --git a/src/profiling/CounterDirectory.hpp b/src/profiling/CounterDirectory.hpp index b0ddbcea3f..22bae89bbb 100644 --- a/src/profiling/CounterDirectory.hpp +++ b/src/profiling/CounterDirectory.hpp @@ -6,9 +6,7 @@ #pragma once #include "ICounterDirectory.hpp" - -#include -#include +#include "ICounterRegistry.hpp" #include #include @@ -22,7 +20,7 @@ namespace armnn namespace profiling { -class CounterDirectory final : public ICounterDirectory +class CounterDirectory final : public ICounterDirectory, public ICounterRegistry { public: CounterDirectory() = default; @@ -31,13 +29,13 @@ public: // Register profiling objects const Category* RegisterCategory (const std::string& categoryName, const Optional& deviceUid = EmptyOptional(), - const Optional& counterSetUid = EmptyOptional()); + const Optional& counterSetUid = EmptyOptional()) override; const Device* RegisterDevice (const std::string& deviceName, uint16_t cores = 0, - const Optional& parentCategoryName = EmptyOptional()); + const Optional& parentCategoryName = EmptyOptional()) override; const CounterSet* RegisterCounterSet(const std::string& counterSetName, uint16_t count = 0, - const Optional& parentCategoryName = EmptyOptional()); + const Optional& parentCategoryName = EmptyOptional()) override; const Counter* RegisterCounter(const BackendId& backendId, const uint16_t uid, const std::string& parentCategoryName, @@ -49,7 +47,7 @@ public: const Optional& units = EmptyOptional(), const Optional& numberOfCores = EmptyOptional(), const Optional& deviceUid = EmptyOptional(), - const Optional& counterSetUid = EmptyOptional()); + const Optional& counterSetUid = EmptyOptional()) override; // Getters for counts uint16_t GetCategoryCount() const override { return boost::numeric_cast(m_Categories.size()); } diff --git a/src/profiling/CounterIdMap.cpp b/src/profiling/CounterIdMap.cpp index 8ee80f913c..862600538b 100644 --- a/src/profiling/CounterIdMap.cpp +++ b/src/profiling/CounterIdMap.cpp @@ -21,6 +21,12 @@ void CounterIdMap::RegisterMapping(uint16_t globalCounterId, m_BackendCounterIdMap[backendIdPair] = globalCounterId; } +void CounterIdMap::Reset() +{ + m_GlobalCounterIdMap.clear(); + m_BackendCounterIdMap.clear(); +} + uint16_t CounterIdMap::GetGlobalId(uint16_t backendCounterId, const armnn::BackendId& backendId) const { std::pair backendIdPair(backendCounterId, backendId); diff --git a/src/profiling/CounterIdMap.hpp b/src/profiling/CounterIdMap.hpp index cb6b9c92e8..5c1a6ea609 100644 --- a/src/profiling/CounterIdMap.hpp +++ b/src/profiling/CounterIdMap.hpp @@ -26,6 +26,7 @@ public: virtual void RegisterMapping(uint16_t globalCounterId, uint16_t backendCounterId, const armnn::BackendId& backendId) = 0; + virtual void Reset() = 0; virtual ~IRegisterCounterMapping() {} }; @@ -38,6 +39,7 @@ public: void RegisterMapping(uint16_t globalCounterId, uint16_t backendCounterId, const armnn::BackendId& backendId) override; + void Reset() override; uint16_t GetGlobalId(uint16_t backendCounterId, const armnn::BackendId& backendId) const override; const std::pair& GetBackendId(uint16_t globalCounterId) const override; private: diff --git a/src/profiling/ICounterRegistry.hpp b/src/profiling/ICounterRegistry.hpp new file mode 100644 index 0000000000..75bc8ef97f --- /dev/null +++ b/src/profiling/ICounterRegistry.hpp @@ -0,0 +1,52 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include + +namespace armnn +{ + +namespace profiling +{ + +class ICounterRegistry +{ +public: + virtual ~ICounterRegistry() {} + + // Register profiling objects + virtual const Category* RegisterCategory (const std::string& categoryName, + const Optional& deviceUid, + const Optional& counterSetUid) = 0; + + virtual const Device* RegisterDevice (const std::string& deviceName, + uint16_t cores, + const Optional& parentCategoryName) = 0; + + virtual const CounterSet* RegisterCounterSet(const std::string& counterSetName, + uint16_t count, + const Optional& parentCategoryName) = 0; + + virtual 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& units, + const Optional& numberOfCores, + const Optional& deviceUid, + const Optional& counterSetUid) = 0; + +}; + +} // namespace profiling + +} // namespace armnn diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp index b06f149486..926e54a5bd 100644 --- a/src/profiling/ProfilingService.cpp +++ b/src/profiling/ProfilingService.cpp @@ -186,6 +186,11 @@ const ICounterDirectory& ProfilingService::GetCounterDirectory() const return m_CounterDirectory; } +ICounterRegistry& ProfilingService::GetCounterRegistry() +{ + return m_CounterDirectory; +} + ProfilingState ProfilingService::GetCurrentState() const { return m_StateMachine.GetCurrentState(); @@ -214,7 +219,7 @@ const ICounterMappings& ProfilingService::GetCounterMappings() const return m_CounterIdMap; } -IRegisterCounterMapping& ProfilingService::GetCounterMappingRegistrar() +IRegisterCounterMapping& ProfilingService::GetCounterMappingRegistry() { return m_CounterIdMap; } @@ -381,6 +386,7 @@ void ProfilingService::Reset() m_CounterIndex.clear(); m_CounterValues.clear(); m_CounterDirectory.Clear(); + m_CounterIdMap.Reset(); m_BufferManager.Reset(); // ...finally reset the profiling state machine diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp index 9cf7545205..e510589caa 100644 --- a/src/profiling/ProfilingService.hpp +++ b/src/profiling/ProfilingService.hpp @@ -10,6 +10,7 @@ #include "ConnectionAcknowledgedCommandHandler.hpp" #include "CounterDirectory.hpp" #include "CounterIdMap.hpp" +#include "ICounterRegistry.hpp" #include "ICounterValues.hpp" #include "PeriodicCounterCapture.hpp" #include "PeriodicCounterSelectionCommandHandler.hpp" @@ -63,13 +64,14 @@ public: void Disconnect(); const ICounterDirectory& GetCounterDirectory() const; + ICounterRegistry& GetCounterRegistry(); ProfilingState GetCurrentState() const; bool IsCounterRegistered(uint16_t counterUid) const override; uint32_t GetCounterValue(uint16_t counterUid) const override; uint16_t GetCounterCount() const override; // counter global/backend mapping functions const ICounterMappings& GetCounterMappings() const; - IRegisterCounterMapping& GetCounterMappingRegistrar(); + IRegisterCounterMapping& GetCounterMappingRegistry(); // Getters for the profiling service state bool IsProfilingEnabled(); diff --git a/src/profiling/RegisterBackendCounters.cpp b/src/profiling/RegisterBackendCounters.cpp new file mode 100644 index 0000000000..0c68838cd6 --- /dev/null +++ b/src/profiling/RegisterBackendCounters.cpp @@ -0,0 +1,87 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RegisterBackendCounters.hpp" + +namespace armnn +{ + +namespace profiling +{ + +void RegisterBackendCounters::RegisterCategory(const std::string& categoryName, + const Optional& deviceUid, + const Optional& counterSetUid) +{ + m_CounterDirectory.RegisterCategory(categoryName, deviceUid, counterSetUid); +} + +uint16_t RegisterBackendCounters::RegisterDevice(const std::string& deviceName, + uint16_t cores, + const Optional& parentCategoryName) +{ + const Device* devicePtr = m_CounterDirectory.RegisterDevice(deviceName, cores, parentCategoryName); + return devicePtr->m_Uid; +} + +uint16_t RegisterBackendCounters::RegisterCounterSet(const std::string& counterSetName, + uint16_t count, + const Optional& parentCategoryName) +{ + const CounterSet* counterSetPtr = m_CounterDirectory.RegisterCounterSet(counterSetName, count, parentCategoryName); + return counterSetPtr->m_Uid; +} + +uint16_t RegisterBackendCounters::RegisterCounter(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& units, + const Optional& numberOfCores, + const Optional& deviceUid, + const Optional& counterSetUid) +{ + ++m_CurrentMaxGlobalCounterID; + const Counter* counterPtr = m_CounterDirectory.RegisterCounter(m_BackendId, + m_CurrentMaxGlobalCounterID, + parentCategoryName, + counterClass, + interpolation, + multiplier, + name, + description, + units, + numberOfCores, + deviceUid, + counterSetUid); + m_CurrentMaxGlobalCounterID = counterPtr->m_MaxCounterUid; + // register mappings + IRegisterCounterMapping& counterIdMap = ProfilingService::Instance().GetCounterMappingRegistry(); + uint16_t globalCounterId = counterPtr->m_Uid; + if (globalCounterId == counterPtr->m_MaxCounterUid) + { + counterIdMap.RegisterMapping(globalCounterId, uid, m_BackendId); + } + else + { + uint16_t backendCounterId = uid; + while (globalCounterId <= counterPtr->m_MaxCounterUid) + { + // register mapping + // globalCounterId -> backendCounterId, m_BackendId + counterIdMap.RegisterMapping(globalCounterId, backendCounterId, m_BackendId); + ++globalCounterId; + ++backendCounterId; + } + } + return m_CurrentMaxGlobalCounterID; +} + +} // namespace profiling + +} // namespace armnn diff --git a/src/profiling/RegisterBackendCounters.hpp b/src/profiling/RegisterBackendCounters.hpp new file mode 100644 index 0000000000..41886c0444 --- /dev/null +++ b/src/profiling/RegisterBackendCounters.hpp @@ -0,0 +1,62 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "armnn/backends/profiling/IBackendProfiling.hpp" +#include "CounterIdMap.hpp" +#include "CounterDirectory.hpp" +#include "ProfilingService.hpp" + +namespace armnn +{ + +namespace profiling +{ + +class RegisterBackendCounters : public IRegisterBackendCounters +{ +public: + + RegisterBackendCounters(uint16_t currentMaxGlobalCounterID, const BackendId& backendId) + : m_CurrentMaxGlobalCounterID(currentMaxGlobalCounterID), + m_CounterDirectory(ProfilingService::Instance().GetCounterRegistry()), + m_BackendId(backendId) {} + + ~RegisterBackendCounters() = default; + + void RegisterCategory(const std::string& categoryName, + const Optional& deviceUid = EmptyOptional(), + const Optional& counterSetUid = EmptyOptional()) override; + + uint16_t RegisterDevice(const std::string& deviceName, + uint16_t cores = 0, + const Optional& parentCategoryName = EmptyOptional()) override; + + uint16_t RegisterCounterSet(const std::string& counterSetName, + uint16_t count = 0, + const Optional& parentCategoryName = EmptyOptional()) override; + + uint16_t RegisterCounter(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& units = EmptyOptional(), + const Optional& numberOfCores = EmptyOptional(), + const Optional& deviceUid = EmptyOptional(), + const Optional& counterSetUid = EmptyOptional()) override; + +private: + uint16_t m_CurrentMaxGlobalCounterID; + ICounterRegistry& m_CounterDirectory; + const BackendId& m_BackendId; +}; + +} // namespace profiling + +} // namespace armnn \ No newline at end of file diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp index e127a18ac7..d06201d3f4 100644 --- a/src/profiling/test/ProfilingTests.cpp +++ b/src/profiling/test/ProfilingTests.cpp @@ -40,6 +40,7 @@ #include #include #include +#include using namespace armnn::profiling; using PacketType = MockProfilingConnection::PacketType; @@ -3168,6 +3169,7 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceBadPeriodicCounterSelectionPacket) BOOST_FAIL("Expected string not found."); } } + BOOST_AUTO_TEST_CASE(CheckCounterIdMap) { CounterIdMap counterIdMap; @@ -3208,4 +3210,53 @@ BOOST_AUTO_TEST_CASE(CheckCounterIdMap) BOOST_CHECK(counterIdMap.GetGlobalId(1, cpuAccId) == 5); } +BOOST_AUTO_TEST_CASE(CheckRegisterBackendCounters) +{ + uint16_t globalCounterIds = armnn::profiling::INFERENCES_RUN; + armnn::BackendId cpuRefId(armnn::Compute::CpuRef); + + RegisterBackendCounters registerBackendCounters(globalCounterIds, cpuRefId); + + // Reset the profiling service to the uninitialized state + armnn::Runtime::CreationOptions::ExternalProfilingOptions options; + options.m_EnableProfiling = true; + ProfilingService& profilingService = ProfilingService::Instance(); + profilingService.ResetExternalProfilingOptions(options, true); + + BOOST_CHECK(profilingService.GetCounterDirectory().GetCategories().empty()); + registerBackendCounters.RegisterCategory("categoryOne"); + auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("categoryOne"); + BOOST_CHECK(categoryOnePtr); + + BOOST_CHECK(profilingService.GetCounterDirectory().GetDevices().empty()); + globalCounterIds = registerBackendCounters.RegisterDevice("deviceOne"); + auto deviceOnePtr = profilingService.GetCounterDirectory().GetDevice(globalCounterIds); + BOOST_CHECK(deviceOnePtr); + BOOST_CHECK(deviceOnePtr->m_Name == "deviceOne"); + + BOOST_CHECK(profilingService.GetCounterDirectory().GetCounterSets().empty()); + globalCounterIds = registerBackendCounters.RegisterCounterSet("counterSetOne"); + auto counterSetOnePtr = profilingService.GetCounterDirectory().GetCounterSet(globalCounterIds); + BOOST_CHECK(counterSetOnePtr); + BOOST_CHECK(counterSetOnePtr->m_Name == "counterSetOne"); + + uint16_t newGlobalCounterId = registerBackendCounters.RegisterCounter(0, + "categoryOne", + 0, + 0, + 1.f, + "CounterOne", + "first test counter"); + BOOST_CHECK(newGlobalCounterId = armnn::profiling::INFERENCES_RUN + 1); + uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId); + BOOST_CHECK(mappedGlobalId == newGlobalCounterId); + auto backendMapping = profilingService.GetCounterMappings().GetBackendId(newGlobalCounterId); + BOOST_CHECK(backendMapping.first == 0); + BOOST_CHECK(backendMapping.second == cpuRefId); + + // Reset the profiling service to stop any running thread + options.m_EnableProfiling = false; + profilingService.ResetExternalProfilingOptions(options, true); +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.1