IVGCVSW-4400 Backend Counter Registry Functionality
authorDavid Monahan <david.monahan@arm.com>
Wed, 12 Feb 2020 15:52:35 +0000 (15:52 +0000)
committerDavid Monahan <david.monahan@arm.com>
Thu, 13 Feb 2020 14:58:57 +0000 (14:58 +0000)
 * 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 <david.monahan@arm.com>
Change-Id: Ie1c6c31e56d1ac7079d6116ecad041961014aedc

include/armnn/backends/profiling/IBackendProfilingContext.hpp
src/backends/backendsCommon/test/BackendProfilingTests.cpp [new file with mode: 0644]
src/backends/backendsCommon/test/BackendRegistryTests.cpp
src/backends/backendsCommon/test/CMakeLists.txt
src/backends/backendsCommon/test/MockBackend.cpp
src/backends/backendsCommon/test/MockBackend.hpp
src/backends/backendsCommon/test/OptimizationViewsTests.cpp
src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp
src/profiling/ProfilingService.cpp
src/profiling/ProfilingService.hpp
src/profiling/test/ProfilingTestUtils.cpp

index 33c8bba..d7f062b 100644 (file)
@@ -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<uint16_t>& counterIds);
-    virtual std::vector<Timestamp> ReportCounterValues();
-    virtual void EnableProfiling(bool flag);
+    virtual uint16_t RegisterCounters(uint16_t currentMaxGlobalCounterID) = 0;
+    virtual void ActivateCounters(uint32_t capturePeriod, const std::vector<uint16_t>& counterIds) = 0;
+    virtual std::vector<Timestamp> ReportCounterValues() = 0;
+    virtual void EnableProfiling(bool flag) = 0;
 };
 
 using IBackendProfilingContextUniquePtr = std::unique_ptr<IBackendProfilingContext>;
diff --git a/src/backends/backendsCommon/test/BackendProfilingTests.cpp b/src/backends/backendsCommon/test/BackendProfilingTests.cpp
new file mode 100644 (file)
index 0000000..fc21730
--- /dev/null
@@ -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 <armnn/BackendId.hpp>
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+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
index 172c0a9..213d114 100644 (file)
@@ -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()
index 4716bd4..0376e3e 100644 (file)
@@ -7,6 +7,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources
     ActivationFixture.hpp
     ArgMinMaxEndToEndTestImpl.hpp
     BackendIdTests.cpp
+    BackendProfilingTests.cpp
     BackendRegistryTests.cpp
     CommonTestUtils.cpp
     CommonTestUtils.hpp
index ac99738..7ad700c 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "MockBackend.hpp"
 #include "MockBackendId.hpp"
+#include "armnn/backends/profiling/IBackendProfilingContext.hpp"
 
 #include <armnn/BackendRegistry.hpp>
 
@@ -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>(MockBackendProfilingContext(backendProfiling));
+    MockBackendProfilingService::Instance().SetProfilingContextPtr(context);
+    return context;
 }
 
 IBackendInternal::IMemoryManagerUniquePtr MockBackend::CreateMemoryManager() const
index d1a0082..21ce7ab 100644 (file)
@@ -5,6 +5,10 @@
 
 #pragma once
 
+#include "armnn/backends/profiling/IBackendProfiling.hpp"
+#include "armnn/backends/profiling/IBackendProfilingContext.hpp"
+#include "MockBackendId.hpp"
+
 #include <LayerSupportCommon.hpp>
 #include <armnn/backends/IBackendInternal.hpp>
 #include <armnn/backends/OptimizationViews.hpp>
 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<profiling::IRegisterBackendCounters> 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<uint16_t>&)
+    {}
+
+    std::vector<profiling::Timestamp> ReportCounterValues()
+    {
+        return std::vector<profiling::Timestamp>();
+    }
+
+    void EnableProfiling(bool)
+    {}
+
+private:
+    IBackendInternal::IBackendProfilingPtr& m_BackendProfiling;
+};
 
 class MockBackend : public IBackendInternal
 {
index 1efc697..3aebe3e 100644 (file)
@@ -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));
 
index 162cc84..f7ebf1a 100644 (file)
@@ -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));
 
index c73f3b2..27b05a6 100644 (file)
@@ -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<armnn::profiling::IBackendProfilingContext> 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()
index 27166b3..54c6540 100644 (file)
@@ -67,10 +67,7 @@ public:
 
     // Store a profiling context returned from a backend that support profiling.
     void AddBackendProfilingContext(const BackendId backendId,
-        std::shared_ptr<armnn::profiling::IBackendProfilingContext> profilingContext)
-    {
-        m_BackendProfilingContexts.emplace(backendId, std::move(profilingContext));
-    }
+        std::shared_ptr<armnn::profiling::IBackendProfilingContext> profilingContext);
 
     const ICounterDirectory& GetCounterDirectory() const;
     ICounterRegistry& GetCounterRegistry();
@@ -147,6 +144,7 @@ private:
     TimelinePacketWriterFactory m_TimelinePacketWriterFactory;
     std::unordered_map<BackendId,
         std::shared_ptr<armnn::profiling::IBackendProfilingContext>> 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);
index bc8b7a7..dd54ca9 100644 (file)
@@ -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