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 <narumol.prangnawarat@arm.com>
Change-Id: I1ef3a3f10ed6ca5ec18d0af04b007fc3bc71a3cb
diff --git a/src/armnn/BackendRegistry.cpp b/src/armnn/BackendRegistry.cpp
index 45f73b8..dc3e2bc 100644
--- a/src/armnn/BackendRegistry.cpp
+++ b/src/armnn/BackendRegistry.cpp
@@ -27,6 +27,11 @@
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 3226470..703a4b1 100644
--- a/src/armnn/DeviceSpec.hpp
+++ b/src/armnn/DeviceSpec.hpp
@@ -24,14 +24,33 @@
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 9b0ce1a..4ad6fa5 100644
--- a/src/armnn/Runtime.cpp
+++ b/src/armnn/Runtime.cpp
@@ -214,6 +214,10 @@
<< std::endl;
}
}
+
+ // Clear all dynamic backends.
+ DynamicBackendUtils::DeregisterDynamicBackends(m_DeviceSpec.GetDynamicBackends());
+ m_DeviceSpec.ClearDynamicBackends();
}
LoadedNetwork* Runtime::GetLoadedNetworkPtr(NetworkId networkId) const
@@ -273,7 +277,7 @@
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 ab0006d..f893458 100644
--- a/src/backends/backendsCommon/DynamicBackendUtils.cpp
+++ b/src/backends/backendsCommon/DynamicBackendUtils.cpp
@@ -310,6 +310,18 @@
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<DynamicBackendPtr>& dynamicBackends)
{
// Get a reference of the backend registry
diff --git a/src/backends/backendsCommon/DynamicBackendUtils.hpp b/src/backends/backendsCommon/DynamicBackendUtils.hpp
index 2763b9d..f4cdd4d 100644
--- a/src/backends/backendsCommon/DynamicBackendUtils.hpp
+++ b/src/backends/backendsCommon/DynamicBackendUtils.hpp
@@ -42,6 +42,7 @@
static std::vector<DynamicBackendPtr> CreateDynamicBackends(const std::vector<std::string>& sharedObjects);
static BackendIdSet RegisterDynamicBackends(const std::vector<DynamicBackendPtr>& 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 c6606be..40e063d 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
@@ -55,7 +55,9 @@
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 561578e..4238ef6 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
@@ -1198,6 +1198,8 @@
}
}
+#if !defined(ARMNN_DYNAMIC_BACKEND_ENABLED)
+
void RuntimeEmptyTestImpl()
{
using namespace armnn;
@@ -1218,6 +1220,8 @@
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 5474f5d..639e1fd 100644
--- a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
@@ -25,14 +25,8 @@
{
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 0000000..79bf7ec
--- /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 0000000..f2ed0f6
--- /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 <reference/RefBackend.hpp>
+
+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 0000000..bc680a1
--- /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 <cstdint>
+
+extern "C"
+{
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+}