From c1536d69c1468514425e143b0578656f51598b94 Mon Sep 17 00:00:00 2001 From: David Monahan Date: Wed, 12 Feb 2020 15:52:35 +0000 Subject: IVGCVSW-4400 Backend Counter Registry Functionality * Adding BackendProfilingContext to the MockBackend * Made IBackendProfilingContext pure Virtual * Added UnitTest using MockBackend for testing Backend Counter Registration * Moved Registry of backend counters from Initialize() to AddBackendProfilingContext() * Added m_MaxGlobalCounterId to ProfilingService * Removed automatic registration of MockBack in BackendRegistry() Signed-off-by: David Monahan Change-Id: Ie1c6c31e56d1ac7079d6116ecad041961014aedc --- .../profiling/IBackendProfilingContext.hpp | 12 ++-- .../backendsCommon/test/BackendProfilingTests.cpp | 41 +++++++++++ .../backendsCommon/test/BackendRegistryTests.cpp | 2 + src/backends/backendsCommon/test/CMakeLists.txt | 1 + src/backends/backendsCommon/test/MockBackend.cpp | 31 +++++--- src/backends/backendsCommon/test/MockBackend.hpp | 82 ++++++++++++++++++++++ .../backendsCommon/test/OptimizationViewsTests.cpp | 1 + .../test/OptimizeSubgraphViewTests.cpp | 8 +++ src/profiling/ProfilingService.cpp | 17 +++-- src/profiling/ProfilingService.hpp | 7 +- src/profiling/test/ProfilingTestUtils.cpp | 2 + 11 files changed, 175 insertions(+), 29 deletions(-) create mode 100644 src/backends/backendsCommon/test/BackendProfilingTests.cpp diff --git a/include/armnn/backends/profiling/IBackendProfilingContext.hpp b/include/armnn/backends/profiling/IBackendProfilingContext.hpp index 33c8bba91b..d7f062bde9 100644 --- a/include/armnn/backends/profiling/IBackendProfilingContext.hpp +++ b/include/armnn/backends/profiling/IBackendProfilingContext.hpp @@ -15,17 +15,13 @@ namespace profiling class IBackendProfilingContext { -protected: - IBackendProfilingContext(const IRuntime::CreationOptions&) - {} - public: virtual ~IBackendProfilingContext() {} - virtual uint16_t RegisterCounters(uint16_t currentMaxGlobalCounterID); - virtual void ActivateCounters(uint32_t capturePeriod, const std::vector& counterIds); - virtual std::vector ReportCounterValues(); - virtual void EnableProfiling(bool flag); + virtual uint16_t RegisterCounters(uint16_t currentMaxGlobalCounterID) = 0; + virtual void ActivateCounters(uint32_t capturePeriod, const std::vector& counterIds) = 0; + virtual std::vector ReportCounterValues() = 0; + virtual void EnableProfiling(bool flag) = 0; }; using IBackendProfilingContextUniquePtr = std::unique_ptr; diff --git a/src/backends/backendsCommon/test/BackendProfilingTests.cpp b/src/backends/backendsCommon/test/BackendProfilingTests.cpp new file mode 100644 index 0000000000..fc21730651 --- /dev/null +++ b/src/backends/backendsCommon/test/BackendProfilingTests.cpp @@ -0,0 +1,41 @@ +// +// Copyright © 2020 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "MockBackend.hpp" +#include "MockBackendId.hpp" +#include "Runtime.hpp" + +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(BackendProfilingTestSuite) + +BOOST_AUTO_TEST_CASE(BackendProfilingCounterRegisterMockBackendTest) +{ + // Reset the profiling service to the uninitialized state + armnn::IRuntime::CreationOptions options; + options.m_ProfilingOptions.m_EnableProfiling = true; + armnn::profiling::ProfilingService& profilingService = armnn::profiling::ProfilingService::Instance(); + profilingService.ConfigureProfilingService(options.m_ProfilingOptions, true); + + armnn::MockBackendInitialiser initialiser; + // Create a runtime + armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); + + // Check if the MockBackends 3 dummy counters {0, 1, 2-5 (four cores)} are registered + armnn::BackendId mockId = armnn::MockBackendId(); + const armnn::profiling::ICounterMappings& counterMap = profilingService.GetCounterMappings(); + BOOST_CHECK(counterMap.GetGlobalId(0, mockId) == 5); + BOOST_CHECK(counterMap.GetGlobalId(1, mockId) == 6); + BOOST_CHECK(counterMap.GetGlobalId(2, mockId) == 7); + BOOST_CHECK(counterMap.GetGlobalId(3, mockId) == 8); + BOOST_CHECK(counterMap.GetGlobalId(4, mockId) == 9); + BOOST_CHECK(counterMap.GetGlobalId(5, mockId) == 10); + options.m_ProfilingOptions.m_EnableProfiling = false; + profilingService.ResetExternalProfilingOptions(options.m_ProfilingOptions, true); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/backends/backendsCommon/test/BackendRegistryTests.cpp b/src/backends/backendsCommon/test/BackendRegistryTests.cpp index 172c0a9169..213d114248 100644 --- a/src/backends/backendsCommon/test/BackendRegistryTests.cpp +++ b/src/backends/backendsCommon/test/BackendRegistryTests.cpp @@ -72,6 +72,7 @@ BOOST_AUTO_TEST_CASE(TestRegistryHelper) factoryFunction(); BOOST_TEST(called == true); + BackendRegistryInstance().Deregister("HelloWorld"); } BOOST_AUTO_TEST_CASE(TestDirectCallToRegistry) @@ -99,6 +100,7 @@ BOOST_AUTO_TEST_CASE(TestDirectCallToRegistry) factoryFunction(); BOOST_TEST(called == true); + BackendRegistryInstance().Deregister("HelloWorld"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index 4716bd47e4..0376e3e5e6 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -7,6 +7,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources ActivationFixture.hpp ArgMinMaxEndToEndTestImpl.hpp BackendIdTests.cpp + BackendProfilingTests.cpp BackendRegistryTests.cpp CommonTestUtils.cpp CommonTestUtils.hpp diff --git a/src/backends/backendsCommon/test/MockBackend.cpp b/src/backends/backendsCommon/test/MockBackend.cpp index ac99738a92..7ad700c786 100644 --- a/src/backends/backendsCommon/test/MockBackend.cpp +++ b/src/backends/backendsCommon/test/MockBackend.cpp @@ -5,6 +5,7 @@ #include "MockBackend.hpp" #include "MockBackendId.hpp" +#include "armnn/backends/profiling/IBackendProfilingContext.hpp" #include @@ -66,19 +67,25 @@ bool IsLayerOptimizable(const armnn::Layer& layer) namespace armnn { -namespace +MockBackendInitialiser::MockBackendInitialiser() { + BackendRegistryInstance().Register(MockBackend::GetIdStatic(), + []() + { + return IBackendInternalUniquePtr(new MockBackend); + }); +} -static BackendRegistry::StaticRegistryInitializer g_RegisterHelper +MockBackendInitialiser::~MockBackendInitialiser() { - BackendRegistryInstance(), - MockBackend::GetIdStatic(), - []() + try { - return IBackendInternalUniquePtr(new MockBackend); + BackendRegistryInstance().Deregister(MockBackend::GetIdStatic()); + } + catch (...) + { + std::cerr << "could not deregister mock backend" << std::endl; } -}; - } const BackendId& MockBackend::GetIdStatic() @@ -99,9 +106,13 @@ IBackendInternal::IBackendContextPtr MockBackend::CreateBackendContext(const IRu } IBackendInternal::IBackendProfilingContextPtr MockBackend::CreateBackendProfilingContext( - const IRuntime::CreationOptions&, IBackendProfilingPtr&) + const IRuntime::CreationOptions& options, IBackendProfilingPtr& backendProfiling) { - return IBackendProfilingContextPtr{}; + boost::ignore_unused(options); + IBackendInternal::IBackendProfilingContextPtr context = + std::make_shared(MockBackendProfilingContext(backendProfiling)); + MockBackendProfilingService::Instance().SetProfilingContextPtr(context); + return context; } IBackendInternal::IMemoryManagerUniquePtr MockBackend::CreateMemoryManager() const diff --git a/src/backends/backendsCommon/test/MockBackend.hpp b/src/backends/backendsCommon/test/MockBackend.hpp index d1a0082e2e..21ce7ab85d 100644 --- a/src/backends/backendsCommon/test/MockBackend.hpp +++ b/src/backends/backendsCommon/test/MockBackend.hpp @@ -5,6 +5,10 @@ #pragma once +#include "armnn/backends/profiling/IBackendProfiling.hpp" +#include "armnn/backends/profiling/IBackendProfilingContext.hpp" +#include "MockBackendId.hpp" + #include #include #include @@ -13,6 +17,84 @@ namespace armnn { +class MockBackendInitialiser +{ +public: + MockBackendInitialiser(); + ~MockBackendInitialiser(); +}; + +class MockBackendProfilingService +{ +public: + // Getter for the singleton instance + static MockBackendProfilingService& Instance() + { + static MockBackendProfilingService instance; + return instance; + } + + armnn::profiling::IBackendProfilingContext* GetContext() + { + return m_sharedContext.get(); + } + + void SetProfilingContextPtr(IBackendInternal::IBackendProfilingContextPtr& shared) + { + m_sharedContext = shared; + } + +private: + IBackendInternal::IBackendProfilingContextPtr m_sharedContext; +}; + +class MockBackendProfilingContext : public profiling::IBackendProfilingContext +{ +public: + MockBackendProfilingContext(IBackendInternal::IBackendProfilingPtr& backendProfiling) + : m_BackendProfiling(backendProfiling) + {} + + ~MockBackendProfilingContext() = default; + + IBackendInternal::IBackendProfilingPtr& GetBackendProfiling() + { + return m_BackendProfiling; + } + + uint16_t RegisterCounters(uint16_t currentMaxGlobalCounterId) + { + std::unique_ptr counterRegistrar = + m_BackendProfiling->GetCounterRegistrationInterface(currentMaxGlobalCounterId); + + std::string categoryName("MockCounters"); + counterRegistrar->RegisterCategory(categoryName); + uint16_t nextMaxGlobalCounterId = counterRegistrar->RegisterCounter( + 0, categoryName, 0, 0, 1.f, "Mock Counter One", "Some notional counter"); + + nextMaxGlobalCounterId = counterRegistrar->RegisterCounter( + 1, categoryName, 0, 0, 1.f, "Mock Counter Two", "Another notional counter"); + + std::string units("microseconds"); + nextMaxGlobalCounterId = counterRegistrar->RegisterCounter( + 2, categoryName, 0, 0, 1.f, "Mock MultiCore Counter", "A dummy four core counter", units, 4); + return nextMaxGlobalCounterId; + } + + void ActivateCounters(uint32_t, const std::vector&) + {} + + std::vector ReportCounterValues() + { + return std::vector(); + } + + void EnableProfiling(bool) + {} + +private: + IBackendInternal::IBackendProfilingPtr& m_BackendProfiling; +}; class MockBackend : public IBackendInternal { diff --git a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp index 1efc69789e..3aebe3e964 100644 --- a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp +++ b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp @@ -199,6 +199,7 @@ BOOST_AUTO_TEST_CASE(OptimizeViewsValidateDeviceMockBackend) input1->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32)); addition->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32)); + armnn::MockBackendInitialiser initialiser; armnn::IRuntime::CreationOptions options; armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); diff --git a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp index 162cc8436c..f7ebf1a14e 100644 --- a/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp +++ b/src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp @@ -564,6 +564,7 @@ void FullyUnsupporteSubgraphTestImpl1() BOOST_TEST(Contains(layersInGraph, "pooling layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -629,6 +630,7 @@ void FullyUnsupporteSubgraphTestImpl2() BOOST_TEST(Contains(layersInGraph, "pooling3 layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -704,6 +706,7 @@ void FullyOptimizableSubgraphTestImpl1() BOOST_TEST(Contains(layersInGraph, "conv layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -772,6 +775,7 @@ void FullyOptimizableSubgraphTestImpl2() BOOST_TEST(Contains(layersInGraph, "conv5 layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -857,6 +861,7 @@ void PartiallySupportedSubgraphTestImpl() BOOST_TEST(Contains(layersInGraph, "pooling3 layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -982,6 +987,7 @@ void FullyUnoptimizableSubgraphTestImpl1() BOOST_TEST(Contains(layersInGraph, "conv layer unoptimizable")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -1049,6 +1055,7 @@ void PartiallyOptimizableSubgraphTestImpl1() BOOST_TEST(Contains(layersInGraph, "conv5 layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); @@ -1181,6 +1188,7 @@ void PartiallyOptimizableSubgraphTestImpl2() BOOST_TEST(Contains(layersInGraph, "add layer")); // Create a mock backend object + MockBackendInitialiser initialiser; // Register the Mock Backend auto backendObjPtr = CreateBackendObject(MockBackendId()); BOOST_TEST((backendObjPtr != nullptr)); diff --git a/src/profiling/ProfilingService.cpp b/src/profiling/ProfilingService.cpp index c73f3b29ec..27b05a60cf 100644 --- a/src/profiling/ProfilingService.cpp +++ b/src/profiling/ProfilingService.cpp @@ -181,6 +181,15 @@ void ProfilingService::Disconnect() } } +// Store a profiling context returned from a backend that support profiling, and register its counters +void ProfilingService::AddBackendProfilingContext(const BackendId backendId, + std::shared_ptr profilingContext) +{ + BOOST_ASSERT(profilingContext != nullptr); + // Register the backend counters + m_MaxGlobalCounterId = profilingContext->RegisterCounters(m_MaxGlobalCounterId); + m_BackendProfilingContexts.emplace(backendId, std::move(profilingContext)); +} const ICounterDirectory& ProfilingService::GetCounterDirectory() const { return m_CounterDirectory; @@ -369,13 +378,6 @@ void ProfilingService::Initialize() BOOST_ASSERT(inferencesRunCounter); InitializeCounterValue(inferencesRunCounter->m_Uid); } - // Register the backend counters - uint16_t maxGlobalCounterId = armnn::profiling::INFERENCES_RUN; - for (auto&& profilingContext : m_BackendProfilingContexts) - { - BOOST_ASSERT(profilingContext.second != nullptr); - maxGlobalCounterId = profilingContext.second->RegisterCounters(maxGlobalCounterId); - } } void ProfilingService::InitializeCounterValue(uint16_t counterUid) @@ -409,6 +411,7 @@ void ProfilingService::Reset() // ...finally reset the profiling state machine m_StateMachine.Reset(); m_BackendProfilingContexts.clear(); + m_MaxGlobalCounterId = armnn::profiling::INFERENCES_RUN; } void ProfilingService::Stop() diff --git a/src/profiling/ProfilingService.hpp b/src/profiling/ProfilingService.hpp index 27166b362e..54c6540f7e 100644 --- a/src/profiling/ProfilingService.hpp +++ b/src/profiling/ProfilingService.hpp @@ -67,10 +67,7 @@ public: // Store a profiling context returned from a backend that support profiling. void AddBackendProfilingContext(const BackendId backendId, - std::shared_ptr profilingContext) - { - m_BackendProfilingContexts.emplace(backendId, std::move(profilingContext)); - } + std::shared_ptr profilingContext); const ICounterDirectory& GetCounterDirectory() const; ICounterRegistry& GetCounterRegistry(); @@ -147,6 +144,7 @@ private: TimelinePacketWriterFactory m_TimelinePacketWriterFactory; std::unordered_map> m_BackendProfilingContexts; + uint16_t m_MaxGlobalCounterId; protected: // Default constructor/destructor kept protected for testing @@ -196,6 +194,7 @@ protected: m_PacketVersionResolver.ResolvePacketVersion(0, 5).GetEncodedValue(), m_StateMachine) , m_TimelinePacketWriterFactory(m_BufferManager) + , m_MaxGlobalCounterId(armnn::profiling::INFERENCES_RUN) { // Register the "Connection Acknowledged" command handler m_CommandHandlerRegistry.RegisterFunctor(&m_ConnectionAcknowledgedCommandHandler); diff --git a/src/profiling/test/ProfilingTestUtils.cpp b/src/profiling/test/ProfilingTestUtils.cpp index bc8b7a7b4d..dd54ca9ebc 100644 --- a/src/profiling/test/ProfilingTestUtils.cpp +++ b/src/profiling/test/ProfilingTestUtils.cpp @@ -359,6 +359,8 @@ void VerifyPostOptimisationStructureTestImpl(armnn::BackendId backendId) // Create runtime in which test will run armnn::IRuntime::CreationOptions options; options.m_ProfilingOptions.m_EnableProfiling = true; + armnn::profiling::ProfilingService& profilingService = armnn::profiling::ProfilingService::Instance(); + profilingService.ConfigureProfilingService(options.m_ProfilingOptions, true); armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); // build up the structure of the network -- cgit v1.2.1