From 60a20fb62c992c4c6369bb7f532957f3e151f3d8 Mon Sep 17 00:00:00 2001 From: Narumol Prangnawarat Date: Mon, 9 Dec 2019 17:24:41 +0000 Subject: IVGCVSW-4212 Example of standalone dynamic reference backend * Add example to build dynamic reference backend * Add functions to clear dynamic backends * Fix the error when dynamic backend is not deregistered * Add DYARMNN_DYNAMIC_BACKEND_ENABLED to check disable empty dynamic backend when dynamic backend is enabled Signed-off-by: Narumol Prangnawarat Change-Id: I1ef3a3f10ed6ca5ec18d0af04b007fc3bc71a3cb --- cmake/GlobalConfig.cmake | 5 ++++ include/armnn/BackendRegistry.hpp | 2 ++ src/armnn/BackendRegistry.cpp | 5 ++++ src/armnn/DeviceSpec.hpp | 21 ++++++++++++- src/armnn/Runtime.cpp | 6 +++- .../backendsCommon/DynamicBackendUtils.cpp | 12 ++++++++ .../backendsCommon/DynamicBackendUtils.hpp | 1 + .../backendsCommon/test/DynamicBackendTests.cpp | 2 ++ .../backendsCommon/test/DynamicBackendTests.hpp | 4 +++ .../backendsCommon/test/OptimizationViewsTests.cpp | 10 ++----- src/dynamic/reference/CMakeLists.txt | 35 ++++++++++++++++++++++ src/dynamic/reference/RefDynamicBackend.cpp | 33 ++++++++++++++++++++ src/dynamic/reference/RefDynamicBackend.hpp | 15 ++++++++++ 13 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 src/dynamic/reference/CMakeLists.txt create mode 100644 src/dynamic/reference/RefDynamicBackend.cpp create mode 100644 src/dynamic/reference/RefDynamicBackend.hpp diff --git a/cmake/GlobalConfig.cmake b/cmake/GlobalConfig.cmake index 191cd9d8aa..51a7efd675 100644 --- a/cmake/GlobalConfig.cmake +++ b/cmake/GlobalConfig.cmake @@ -302,6 +302,11 @@ if(ARMNNREF) add_definitions(-DARMNNREF_ENABLED) endif() +# ArmNN dynamic backend +if(DYNAMIC_BACKEND_PATHS) + add_definitions(-DARMNN_DYNAMIC_BACKEND_ENABLED) +endif() + # Streamline annotate if(PROFILING_BACKEND_STREAMLINE) include_directories("${GATOR_ROOT}/annotate") diff --git a/include/armnn/BackendRegistry.hpp b/include/armnn/BackendRegistry.hpp index 82e59d970b..a0cfee9391 100644 --- a/include/armnn/BackendRegistry.hpp +++ b/include/armnn/BackendRegistry.hpp @@ -43,6 +43,8 @@ public: } }; + void Deregister(const BackendId& id); + protected: using FactoryStorage = std::unordered_map; diff --git a/src/armnn/BackendRegistry.cpp b/src/armnn/BackendRegistry.cpp index 45f73b8daf..dc3e2bc254 100644 --- a/src/armnn/BackendRegistry.cpp +++ b/src/armnn/BackendRegistry.cpp @@ -27,6 +27,11 @@ void BackendRegistry::Register(const BackendId& id, BackendRegistry::FactoryFunc m_Factories[id] = factory; } +void BackendRegistry::Deregister(const BackendId& id) +{ + m_Factories.erase(id); +} + bool BackendRegistry::IsBackendRegistered(const BackendId& id) const { return (m_Factories.find(id) != m_Factories.end()); diff --git a/src/armnn/DeviceSpec.hpp b/src/armnn/DeviceSpec.hpp index 32264706fd..703a4b123f 100644 --- a/src/armnn/DeviceSpec.hpp +++ b/src/armnn/DeviceSpec.hpp @@ -24,14 +24,33 @@ public: return m_SupportedBackends; } - void AddSupportedBackends(const BackendIdSet& backendIds) + void AddSupportedBackends(const BackendIdSet& backendIds, bool isDynamic = false) { m_SupportedBackends.insert(backendIds.begin(), backendIds.end()); + if (isDynamic) + { + m_DynamicBackends.insert(backendIds.begin(), backendIds.end()); + } + } + + void ClearDynamicBackends() + { + for (const auto& id : m_DynamicBackends) + { + m_SupportedBackends.erase(id); + } + m_DynamicBackends.clear(); + } + + const BackendIdSet& GetDynamicBackends() const + { + return m_DynamicBackends; } private: DeviceSpec() = delete; BackendIdSet m_SupportedBackends; + BackendIdSet m_DynamicBackends; }; } // namespace armnn diff --git a/src/armnn/Runtime.cpp b/src/armnn/Runtime.cpp index 9b0ce1a345..4ad6fa59a0 100644 --- a/src/armnn/Runtime.cpp +++ b/src/armnn/Runtime.cpp @@ -214,6 +214,10 @@ Runtime::~Runtime() << std::endl; } } + + // Clear all dynamic backends. + DynamicBackendUtils::DeregisterDynamicBackends(m_DeviceSpec.GetDynamicBackends()); + m_DeviceSpec.ClearDynamicBackends(); } LoadedNetwork* Runtime::GetLoadedNetworkPtr(NetworkId networkId) const @@ -273,7 +277,7 @@ void Runtime::LoadDynamicBackends(const std::string& overrideBackendPath) BackendIdSet registeredBackendIds = DynamicBackendUtils::RegisterDynamicBackends(m_DynamicBackends); // Add the registered dynamic backend ids to the list of supported backends - m_DeviceSpec.AddSupportedBackends(registeredBackendIds); + m_DeviceSpec.AddSupportedBackends(registeredBackendIds, true); } } // namespace armnn diff --git a/src/backends/backendsCommon/DynamicBackendUtils.cpp b/src/backends/backendsCommon/DynamicBackendUtils.cpp index ab0006d739..f893458b88 100644 --- a/src/backends/backendsCommon/DynamicBackendUtils.cpp +++ b/src/backends/backendsCommon/DynamicBackendUtils.cpp @@ -310,6 +310,18 @@ std::vector DynamicBackendUtils::CreateDynamicBackends(const return dynamicBackends; } +void DynamicBackendUtils::DeregisterDynamicBackends(const BackendIdSet& dynamicBackends) +{ + // Get a reference of the backend registry + BackendRegistry& backendRegistry = BackendRegistryInstance(); + + for (const auto& id : dynamicBackends) + { + backendRegistry.Deregister(id); + } + +} + BackendIdSet DynamicBackendUtils::RegisterDynamicBackends(const std::vector& dynamicBackends) { // Get a reference of the backend registry diff --git a/src/backends/backendsCommon/DynamicBackendUtils.hpp b/src/backends/backendsCommon/DynamicBackendUtils.hpp index 2763b9d7d2..f4cdd4db0c 100644 --- a/src/backends/backendsCommon/DynamicBackendUtils.hpp +++ b/src/backends/backendsCommon/DynamicBackendUtils.hpp @@ -42,6 +42,7 @@ public: static std::vector CreateDynamicBackends(const std::vector& sharedObjects); static BackendIdSet RegisterDynamicBackends(const std::vector& dynamicBackends); + static void DeregisterDynamicBackends(const BackendIdSet& dynamicBackends); protected: /// Protected methods for testing purposes diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp index c6606be9ff..40e063d8c4 100644 --- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp +++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp @@ -55,7 +55,9 @@ ARMNN_SIMPLE_TEST_CASE(RegisterMultipleDynamicBackends, RegisterMultipleDynamicB ARMNN_SIMPLE_TEST_CASE(RegisterMultipleInvalidDynamicBackends, RegisterMultipleInvalidDynamicBackendsTestImpl); ARMNN_SIMPLE_TEST_CASE(RegisterMixedDynamicBackends, RegisterMixedDynamicBackendsTestImpl); +#if !defined(ARMNN_DYNAMIC_BACKEND_ENABLED) ARMNN_SIMPLE_TEST_CASE(RuntimeEmpty, RuntimeEmptyTestImpl); +#endif ARMNN_SIMPLE_TEST_CASE(RuntimeDynamicBackends, RuntimeDynamicBackendsTestImpl); ARMNN_SIMPLE_TEST_CASE(RuntimeDuplicateDynamicBackends, RuntimeDuplicateDynamicBackendsTestImpl); ARMNN_SIMPLE_TEST_CASE(RuntimeInvalidDynamicBackends, RuntimeInvalidDynamicBackendsTestImpl); diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp index 561578e841..4238ef6f7d 100644 --- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp +++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp @@ -1198,6 +1198,8 @@ void RegisterMixedDynamicBackendsTestImpl() } } +#if !defined(ARMNN_DYNAMIC_BACKEND_ENABLED) + void RuntimeEmptyTestImpl() { using namespace armnn; @@ -1218,6 +1220,8 @@ void RuntimeEmptyTestImpl() BOOST_TEST(backendRegistry.Size() == 0); } +#endif + void RuntimeDynamicBackendsTestImpl() { using namespace armnn; diff --git a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp index 5474f5ddac..639e1fd59e 100644 --- a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp +++ b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp @@ -25,14 +25,8 @@ void CheckLayers(Graph& graph) { case LayerType::Input: ++m_inputLayerCount; - if (layer->GetGuid() == profiling::ProfilingGuid(0)) - { - BOOST_TEST(layer->GetName() == "inLayer0"); - } - else if (layer->GetGuid() == profiling::ProfilingGuid(1)) - { - BOOST_TEST(layer->GetName() == "inLayer1"); - } + BOOST_TEST((layer->GetName() == std::string("inLayer0") || + layer->GetName() == std::string("inLayer1"))); break; // The Addition layer should become a PreCompiled Layer after Optimisation case LayerType::PreCompiled: diff --git a/src/dynamic/reference/CMakeLists.txt b/src/dynamic/reference/CMakeLists.txt new file mode 100644 index 0000000000..79bf7ec362 --- /dev/null +++ b/src/dynamic/reference/CMakeLists.txt @@ -0,0 +1,35 @@ +# +# Copyright © 2019 Arm Ltd. All rights reserved. +# SPDX-License-Identifier: MIT +# + +cmake_minimum_required (VERSION 3.0.2) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# File needed to wrap the existing backend into a dynamic one +list(APPEND armnnRefDynamicBackend_sources + RefDynamicBackend.cpp + RefDynamicBackend.hpp +) + +# Set the backend source path +set(RefBackendPath ${PROJECT_SOURCE_DIR}/../../../src/backends/reference) + +# Source files of the backend, taken directly from the source tree +file(GLOB RefBackendBaseFiles ${RefBackendPath}/*.cpp) +file(GLOB RefBackendWorloadFiles ${RefBackendPath}/workloads/*.cpp) +set(RefBackendFiles ${RefBackendBaseFiles} ${RefBackendWorloadFiles}) + +# Remove the file that contains the static backend registration +list(REMOVE_ITEM RefBackendFiles ${RefBackendPath}/RefRegistryInitializer.cpp) + +# Create the shared object +add_library(Arm_CpuRef_backend MODULE ${armnnRefDynamicBackend_sources} ${RefBackendFiles}) + +target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../include) +target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../third-party) # for half +target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/armnn) +target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/armnnUtils) +target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/backends) +target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/../../../src/profiling) \ No newline at end of file diff --git a/src/dynamic/reference/RefDynamicBackend.cpp b/src/dynamic/reference/RefDynamicBackend.cpp new file mode 100644 index 0000000000..f2ed0f6033 --- /dev/null +++ b/src/dynamic/reference/RefDynamicBackend.cpp @@ -0,0 +1,33 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefDynamicBackend.hpp" + +#include + +using namespace armnn; + +const char* GetBackendId() +{ + return RefBackend::GetIdStatic().Get().c_str(); +} + +void GetVersion(uint32_t* outMajor, uint32_t* outMinor) +{ + if (!outMajor || !outMinor) + { + return; + } + + BackendVersion apiVersion = IBackendInternal::GetApiVersion(); + + *outMajor = apiVersion.m_Major; + *outMinor = apiVersion.m_Minor; +} + +void* BackendFactory() +{ + return new RefBackend(); +} diff --git a/src/dynamic/reference/RefDynamicBackend.hpp b/src/dynamic/reference/RefDynamicBackend.hpp new file mode 100644 index 0000000000..bc680a1fba --- /dev/null +++ b/src/dynamic/reference/RefDynamicBackend.hpp @@ -0,0 +1,15 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include + +extern "C" +{ +const char* GetBackendId(); +void GetVersion(uint32_t* outMajor, uint32_t* outMinor); +void* BackendFactory(); +} -- cgit v1.2.1