From 2dcd3fef30ad3ac41621f3f8b142632e912ea42d Mon Sep 17 00:00:00 2001 From: James Conroy Date: Thu, 6 Feb 2020 18:34:52 +0000 Subject: IVGCVSW-4319 Implement Counter Status Querying * Adds implementations for GetCounterStatus and GetActiveCounters. * Adds CheckCounterStatusQuery in ProfilingTests. * Modifies Holder and ProfilingService to open up access to CaptureData for use by BackendProfiling. Signed-off-by: James Conroy Signed-off-by: Colm Donelan Change-Id: Iec47952545c0072a71088b12ca3dc31673fa9c51 --- .../armnn/backends/profiling/IBackendProfiling.hpp | 12 +- src/profiling/Holder.cpp | 13 ++ src/profiling/Holder.hpp | 1 + src/profiling/ProfilingService.cpp | 10 ++ src/profiling/ProfilingService.hpp | 3 + src/profiling/backends/BackendProfiling.cpp | 37 +++++- src/profiling/backends/BackendProfiling.hpp | 21 +-- src/profiling/test/ProfilingTests.cpp | 141 ++++++++++++++++++++- 8 files changed, 223 insertions(+), 15 deletions(-) diff --git a/include/armnn/backends/profiling/IBackendProfiling.hpp b/include/armnn/backends/profiling/IBackendProfiling.hpp index d3c52996f4..a649ece74f 100644 --- a/include/armnn/backends/profiling/IBackendProfiling.hpp +++ b/include/armnn/backends/profiling/IBackendProfiling.hpp @@ -30,6 +30,14 @@ struct Timestamp struct CounterStatus { + CounterStatus(uint16_t backendCounterId, + uint16_t globalCounterId, + bool enabled, + uint32_t samplingRateInMicroseconds) + : m_BackendCounterId(backendCounterId), + m_GlobalCounterId(globalCounterId), + m_Enabled(enabled), + m_SamplingRateInMicroseconds(samplingRateInMicroseconds) {} uint16_t m_BackendCounterId; uint16_t m_GlobalCounterId; bool m_Enabled; @@ -73,7 +81,7 @@ public: {} virtual std::unique_ptr - GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID) = 0; + GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID) = 0; virtual std::unique_ptr GetSendTimelinePacket() = 0; @@ -88,5 +96,7 @@ public: virtual bool IsProfilingEnabled() const = 0; }; + } // namespace profiling + } // namespace armnn \ No newline at end of file diff --git a/src/profiling/Holder.cpp b/src/profiling/Holder.cpp index 750be7ec74..41c2993929 100644 --- a/src/profiling/Holder.cpp +++ b/src/profiling/Holder.cpp @@ -46,6 +46,19 @@ CaptureData Holder::GetCaptureData() const return m_CaptureData; } +bool CaptureData::IsCounterIdInCaptureData(uint16_t counterId) +{ + for (auto m_CounterId : m_CounterIds) { + if (m_CounterId == counterId) + { + return true; + } + } + + // Return false by default unless counterId is found + return false; +} + void Holder::SetCaptureData(uint32_t capturePeriod, const std::vector& counterIds) { std::lock_guard lockGuard(m_CaptureThreadMutex); diff --git a/src/profiling/Holder.hpp b/src/profiling/Holder.hpp index 3143105ab4..9785b98312 100644 --- a/src/profiling/Holder.hpp +++ b/src/profiling/Holder.hpp @@ -33,6 +33,7 @@ public: void SetCounterIds(const std::vector& counterIds); uint32_t GetCapturePeriod() const; const std::vector& GetCounterIds() const; + bool IsCounterIdInCaptureData(uint16_t counterId); private: uint32_t m_CapturePeriod; diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp index 5cee477bd5..3540fc43e0 100644 --- a/src/profiling/ProfilingService.cpp +++ b/src/profiling/ProfilingService.cpp @@ -224,6 +224,16 @@ IRegisterCounterMapping& ProfilingService::GetCounterMappingRegistry() return m_CounterIdMap; } +CaptureData ProfilingService::GetCaptureData() +{ + return m_Holder.GetCaptureData(); +} + +void ProfilingService::SetCaptureData(uint32_t capturePeriod, const std::vector& counterIds) +{ + m_Holder.SetCaptureData(capturePeriod, counterIds); +} + void ProfilingService::SetCounterValue(uint16_t counterUid, uint32_t value) { CheckCounterUid(counterUid); diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp index 4438952853..17099b1247 100644 --- a/src/profiling/ProfilingService.hpp +++ b/src/profiling/ProfilingService.hpp @@ -84,6 +84,9 @@ public: // Getters for the profiling service state bool IsProfilingEnabled(); + CaptureData GetCaptureData(); + void SetCaptureData(uint32_t capturePeriod, const std::vector& counterIds); + // Setters for the profiling service state void SetCounterValue(uint16_t counterUid, uint32_t value) override; uint32_t AddCounterValue(uint16_t counterUid, uint32_t value) override; diff --git a/src/profiling/backends/BackendProfiling.cpp b/src/profiling/backends/BackendProfiling.cpp index a49122a7a1..884fb3f2ff 100644 --- a/src/profiling/backends/BackendProfiling.cpp +++ b/src/profiling/backends/BackendProfiling.cpp @@ -15,7 +15,7 @@ namespace profiling std::unique_ptr BackendProfiling::GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID) { - return std::make_unique(RegisterBackendCounters(currentMaxGlobalCounterID, m_backendId)); + return std::make_unique(RegisterBackendCounters(currentMaxGlobalCounterID, m_BackendId)); } std::unique_ptr BackendProfiling::GetSendTimelinePacket() @@ -29,14 +29,43 @@ IProfilingGuidGenerator& BackendProfiling::GetProfilingGuidGenerator() return m_ProfilingService; } -CounterStatus BackendProfiling::GetCounterStatus(uint16_t) +CounterStatus BackendProfiling::GetCounterStatus(uint16_t backendCounterId) { - return CounterStatus(); + uint16_t globalCounterId = m_ProfilingService.GetCounterMappings().GetGlobalId(backendCounterId, m_BackendId); + CaptureData captureData = m_ProfilingService.GetCaptureData(); + + CounterStatus counterStatus(backendCounterId, globalCounterId, false, 0); + + if (captureData.IsCounterIdInCaptureData(globalCounterId)) + { + counterStatus.m_Enabled = true; + counterStatus.m_SamplingRateInMicroseconds = captureData.GetCapturePeriod(); + } + + return counterStatus; } std::vector BackendProfiling::GetActiveCounters() { - return std::vector(); + CaptureData captureData = m_ProfilingService.GetCaptureData(); + + const std::vector& globalCounterIds = captureData.GetCounterIds(); + std::vector activeCounterIds; + + for (auto globalCounterId : globalCounterIds) { + // Get pair of local counterId and backendId using globalCounterId + const std::pair& backendCounterIdPair = + ProfilingService::Instance().GetCounterMappings().GetBackendId(globalCounterId); + if (backendCounterIdPair.second == m_BackendId) + { + activeCounterIds.emplace_back(backendCounterIdPair.first, + globalCounterId, + true, + captureData.GetCapturePeriod()); + } + } + + return activeCounterIds; } bool BackendProfiling::IsProfilingEnabled() const diff --git a/src/profiling/backends/BackendProfiling.hpp b/src/profiling/backends/BackendProfiling.hpp index 2bc365a1de..e0e0f58e7d 100644 --- a/src/profiling/backends/BackendProfiling.hpp +++ b/src/profiling/backends/BackendProfiling.hpp @@ -3,7 +3,9 @@ // SPDX-License-Identifier: MIT // -#include +#pragma once + +#include "ProfilingService.hpp" #include namespace armnn @@ -15,17 +17,18 @@ namespace profiling class BackendProfiling : public IBackendProfiling { public: - BackendProfiling(const IRuntime::CreationOptions& options, ProfilingService& profilingService, const BackendId& id) - : m_options(options) - , m_ProfilingService(profilingService) - , m_backendId(id) - {} + BackendProfiling(const IRuntime::CreationOptions& options, + ProfilingService& profilingService, + const BackendId& backendId) + : m_Options(options), + m_ProfilingService(profilingService), + m_BackendId(backendId) {} ~BackendProfiling() {} std::unique_ptr - GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID) override; + GetCounterRegistrationInterface(uint16_t currentMaxGlobalCounterID) override; std::unique_ptr GetSendTimelinePacket() override; @@ -41,9 +44,9 @@ public: bool IsProfilingEnabled() const override; private: - IRuntime::CreationOptions m_options; + IRuntime::CreationOptions m_Options; ProfilingService& m_ProfilingService; - BackendId m_backendId; + 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 d06201d3f4..b15ddf7885 100644 --- a/src/profiling/test/ProfilingTests.cpp +++ b/src/profiling/test/ProfilingTests.cpp @@ -5,6 +5,7 @@ #include "ProfilingTests.hpp" +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +42,7 @@ #include #include #include -#include + using namespace armnn::profiling; using PacketType = MockProfilingConnection::PacketType; @@ -3259,4 +3261,141 @@ BOOST_AUTO_TEST_CASE(CheckRegisterBackendCounters) profilingService.ResetExternalProfilingOptions(options, true); } +BOOST_AUTO_TEST_CASE(CheckCounterStatusQuery) +{ + armnn::IRuntime::CreationOptions options; + options.m_ProfilingOptions.m_EnableProfiling = true; + + // Reset the profiling service to the uninitialized state + ProfilingService& profilingService = ProfilingService::Instance(); + profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true); + + const armnn::BackendId cpuRefId(armnn::Compute::CpuRef); + const armnn::BackendId cpuAccId(armnn::Compute::CpuAcc); + + // Create BackendProfiling for each backend + BackendProfiling backendProfilingCpuRef(options, profilingService, cpuRefId); + BackendProfiling backendProfilingCpuAcc(options, profilingService, cpuAccId); + + uint16_t initialNumGlobalCounterIds = armnn::profiling::INFERENCES_RUN; + + // Create RegisterBackendCounters for CpuRef + RegisterBackendCounters registerBackendCountersCpuRef(initialNumGlobalCounterIds, cpuRefId); + + // Create 'testCategory' in CounterDirectory (backend agnostic) + BOOST_CHECK(profilingService.GetCounterDirectory().GetCategories().empty()); + registerBackendCountersCpuRef.RegisterCategory("testCategory"); + auto categoryOnePtr = profilingService.GetCounterDirectory().GetCategory("testCategory"); + BOOST_CHECK(categoryOnePtr); + + // Counters: + // Global | Local | Backend + // 5 | 0 | CpuRef + // 6 | 1 | CpuRef + // 7 | 1 | CpuAcc + + std::vector cpuRefCounters = {0, 1}; + std::vector cpuAccCounters = {0}; + + // Register the backend counters for CpuRef and validate GetGlobalId and GetBackendId + uint16_t currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter( + 0, "testCategory", 0, 0, 1.f, "CpuRefCounter0", "Zeroth CpuRef Counter"); + BOOST_CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 1); + uint16_t mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuRefId); + BOOST_CHECK(mappedGlobalId == currentNumGlobalCounterIds); + auto backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds); + BOOST_CHECK(backendMapping.first == 0); + BOOST_CHECK(backendMapping.second == cpuRefId); + + currentNumGlobalCounterIds = registerBackendCountersCpuRef.RegisterCounter( + 1, "testCategory", 0, 0, 1.f, "CpuRefCounter1", "First CpuRef Counter"); + BOOST_CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 2); + mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(1, cpuRefId); + BOOST_CHECK(mappedGlobalId == currentNumGlobalCounterIds); + backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds); + BOOST_CHECK(backendMapping.first == 1); + BOOST_CHECK(backendMapping.second == cpuRefId); + + // Create RegisterBackendCounters for CpuAcc + RegisterBackendCounters registerBackendCountersCpuAcc(currentNumGlobalCounterIds, cpuAccId); + + // Register the backend counter for CpuAcc and validate GetGlobalId and GetBackendId + currentNumGlobalCounterIds = registerBackendCountersCpuAcc.RegisterCounter( + 0, "testCategory", 0, 0, 1.f, "CpuAccCounter0", "Zeroth CpuAcc Counter"); + BOOST_CHECK(currentNumGlobalCounterIds == initialNumGlobalCounterIds + 3); + mappedGlobalId = profilingService.GetCounterMappings().GetGlobalId(0, cpuAccId); + BOOST_CHECK(mappedGlobalId == currentNumGlobalCounterIds); + backendMapping = profilingService.GetCounterMappings().GetBackendId(currentNumGlobalCounterIds); + BOOST_CHECK(backendMapping.first == 0); + BOOST_CHECK(backendMapping.second == cpuAccId); + + // Create vectors for active counters + const std::vector activeGlobalCounterIds = {5}; // CpuRef(0) activated + const std::vector newActiveGlobalCounterIds = {6, 7}; // CpuRef(0) and CpuAcc(1) activated + + const uint32_t capturePeriod = 200; + const uint32_t newCapturePeriod = 100; + + // Set capture period and active counters in CaptureData + profilingService.SetCaptureData(capturePeriod, activeGlobalCounterIds); + + // Get vector of active counters for CpuRef and CpuAcc backends + std::vector cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters(); + std::vector cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters(); + BOOST_CHECK_EQUAL(cpuRefCounterStatus.size(), 1); + BOOST_CHECK_EQUAL(cpuAccCounterStatus.size(), 0); + + // Check active CpuRef counter + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_GlobalCounterId, activeGlobalCounterIds[0]); + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[0]); + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, capturePeriod); + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_Enabled, true); + + // Check inactive CpuRef counter + CounterStatus inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[1]); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_GlobalCounterId, 6); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[1]); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_Enabled, false); + + // Check inactive CpuAcc counter + CounterStatus inactiveCpuAccCounter = backendProfilingCpuAcc.GetCounterStatus(cpuAccCounters[0]); + BOOST_CHECK_EQUAL(inactiveCpuAccCounter.m_GlobalCounterId, 7); + BOOST_CHECK_EQUAL(inactiveCpuAccCounter.m_BackendCounterId, cpuAccCounters[0]); + BOOST_CHECK_EQUAL(inactiveCpuAccCounter.m_SamplingRateInMicroseconds, 0); + BOOST_CHECK_EQUAL(inactiveCpuAccCounter.m_Enabled, false); + + // Set new capture period and new active counters in CaptureData + profilingService.SetCaptureData(newCapturePeriod, newActiveGlobalCounterIds); + + // Get vector of active counters for CpuRef and CpuAcc backends + cpuRefCounterStatus = backendProfilingCpuRef.GetActiveCounters(); + cpuAccCounterStatus = backendProfilingCpuAcc.GetActiveCounters(); + BOOST_CHECK_EQUAL(cpuRefCounterStatus.size(), 1); + BOOST_CHECK_EQUAL(cpuAccCounterStatus.size(), 1); + + // Check active CpuRef counter + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[0]); + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_BackendCounterId, cpuRefCounters[1]); + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod); + BOOST_CHECK_EQUAL(cpuRefCounterStatus[0].m_Enabled, true); + + // Check active CpuAcc counter + BOOST_CHECK_EQUAL(cpuAccCounterStatus[0].m_GlobalCounterId, newActiveGlobalCounterIds[1]); + BOOST_CHECK_EQUAL(cpuAccCounterStatus[0].m_BackendCounterId, cpuAccCounters[0]); + BOOST_CHECK_EQUAL(cpuAccCounterStatus[0].m_SamplingRateInMicroseconds, newCapturePeriod); + BOOST_CHECK_EQUAL(cpuAccCounterStatus[0].m_Enabled, true); + + // Check inactive CpuRef counter + inactiveCpuRefCounter = backendProfilingCpuRef.GetCounterStatus(cpuRefCounters[0]); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_GlobalCounterId, 5); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_BackendCounterId, cpuRefCounters[0]); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_SamplingRateInMicroseconds, 0); + BOOST_CHECK_EQUAL(inactiveCpuRefCounter.m_Enabled, false); + + // Reset the profiling service to stop any running thread + options.m_ProfilingOptions.m_EnableProfiling = false; + profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true); +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.1