Description: Split out backends to dynamically loadable libraries
  * Add cl neon ref internal headers
  * Link acl libraries
  * Remove workloads from libarmnn
  * Shared aclcommon linked to Neon and Cl Backends
  * Remove backend tests
  * Link OpenCl libraries to GpuAcc Backend
  * Version the AclCommon library
 .
 Signed-off-by: Francis Murtagh <francis.murtagh@arm.com>
 Change-Id: I524fcc7de1f696185c19b5741f46eb4d435ca89d
Author: Francis Murtagh <francis.murtagh@arm.com>
X-Dgit-Generated: 20.08-1 ec2767a01cbc8e65137798609be54e4c039083f6

---

--- armnn-20.08.orig/CMakeLists.txt
+++ armnn-20.08/CMakeLists.txt
@@ -608,11 +608,11 @@ target_link_libraries(armnn ${Boost_THRE
                             ${Boost_SYSTEM_LIBRARY})
 
 if(ARMCOMPUTENEON OR ARMCOMPUTECL)
-    target_link_libraries(armnn ${ARMCOMPUTE_LIBRARIES})
+   #target_link_libraries(armnn ${ARMCOMPUTE_LIBRARIES})
 endif()
 
 if(ARMCOMPUTECL AND OPENCL_LIBRARIES)
-    target_link_libraries(armnn ${OPENCL_LIBRARIES})
+    #target_link_libraries(armnn ${OPENCL_LIBRARIES})
 endif()
 
 if(PROFILING_BACKEND_STREAMLINE AND (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android)))
--- armnn-20.08.orig/src/armnn/test/UnitTests.hpp
+++ armnn-20.08/src/armnn/test/UnitTests.hpp
@@ -6,7 +6,14 @@
 
 #include <armnn/Logging.hpp>
 #include <armnn/Utils.hpp>
+
+#if defined(ARMNNREF_ENABLED)
+
 #include <reference/RefWorkloadFactory.hpp>
+#include <reference/test/RefWorkloadFactoryHelper.hpp>
+
+#endif
+
 #include <backendsCommon/test/LayerTests.hpp>
 #include <backendsCommon/test/WorkloadFactoryHelper.hpp>
 #include "TensorHelpers.hpp"
@@ -74,6 +81,24 @@ void RunTestFunction(const char* testNam
     armnn::ProfilerManager::GetInstance().RegisterProfiler(nullptr);
 }
 
+
+template<typename FactoryType, typename TFuncPtr, typename... Args>
+void RunTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
+{
+    std::unique_ptr<armnn::Profiler> profiler = std::make_unique<armnn::Profiler>();
+    armnn::ProfilerManager::GetInstance().RegisterProfiler(profiler.get());
+
+    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
+    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
+
+    auto tensorHandleFactory = WorkloadFactoryHelper<FactoryType>::GetTensorHandleFactory(memoryManager);
+
+    auto testResult = (*testFunction)(workloadFactory, memoryManager, tensorHandleFactory, args...);
+    CompareTestResultIfSupported(testName, testResult);
+
+    armnn::ProfilerManager::GetInstance().RegisterProfiler(nullptr);
+}
+
 #define ARMNN_SIMPLE_TEST_CASE(TestName, TestFunction) \
     BOOST_AUTO_TEST_CASE(TestName) \
     { \
@@ -86,6 +111,15 @@ void RunTestFunction(const char* testNam
         RunTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
     }
 
+#define ARMNN_AUTO_TEST_CASE_WITH_THF(TestName, TestFunction, ...) \
+    BOOST_AUTO_TEST_CASE(TestName) \
+    { \
+        RunTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
+#if defined(ARMNNREF_ENABLED)
+
+
 template<typename FactoryType, typename TFuncPtr, typename... Args>
 void CompareRefTestFunction(const char* testName, TFuncPtr testFunction, Args... args)
 {
@@ -98,14 +132,44 @@ void CompareRefTestFunction(const char*
     CompareTestResultIfSupported(testName, testResult);
 }
 
+template<typename FactoryType, typename TFuncPtr, typename... Args>
+void CompareRefTestFunctionUsingTensorHandleFactory(const char* testName, TFuncPtr testFunction, Args... args)
+{
+    auto memoryManager = WorkloadFactoryHelper<FactoryType>::GetMemoryManager();
+    FactoryType workloadFactory = WorkloadFactoryHelper<FactoryType>::GetFactory(memoryManager);
+
+    armnn::RefWorkloadFactory refWorkloadFactory;
+    auto tensorHandleFactory = WorkloadFactoryHelper<FactoryType>::GetTensorHandleFactory(memoryManager);
+    auto refTensorHandleFactory =
+        RefWorkloadFactoryHelper::GetTensorHandleFactory(memoryManager);
+
+    auto testResult = (*testFunction)(
+        workloadFactory, memoryManager, refWorkloadFactory, tensorHandleFactory, refTensorHandleFactory, args...);
+    CompareTestResultIfSupported(testName, testResult);
+}
+
+#endif
+
 #define ARMNN_COMPARE_REF_AUTO_TEST_CASE(TestName, TestFunction, ...) \
     BOOST_AUTO_TEST_CASE(TestName) \
     { \
         CompareRefTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
     }
 
+#define ARMNN_COMPARE_REF_AUTO_TEST_CASE_WITH_THF(TestName, TestFunction, ...) \
+    BOOST_AUTO_TEST_CASE(TestName) \
+    { \
+        CompareRefTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
+
 #define ARMNN_COMPARE_REF_FIXTURE_TEST_CASE(TestName, Fixture, TestFunction, ...) \
     BOOST_FIXTURE_TEST_CASE(TestName, Fixture) \
     { \
         CompareRefTestFunction<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
     }
+
+#define ARMNN_COMPARE_REF_FIXTURE_TEST_CASE_WITH_THF(TestName, Fixture, TestFunction, ...) \
+    BOOST_FIXTURE_TEST_CASE(TestName, Fixture) \
+    { \
+        CompareRefTestFunctionUsingTensorHandleFactory<FactoryType>(#TestName, &TestFunction, ##__VA_ARGS__); \
+    }
--- armnn-20.08.orig/src/backends/aclCommon/CMakeLists.txt
+++ armnn-20.08/src/backends/aclCommon/CMakeLists.txt
@@ -12,13 +12,17 @@ list(APPEND armnnAclCommon_sources
     BaseMemoryManager.hpp
 )
 
-if(BUILD_UNIT_TESTS)
-    add_subdirectory(test)
-endif()
+#if(BUILD_UNIT_TESTS)
+#    add_subdirectory(test)
+#endif()
 
-add_library(armnnAclCommon OBJECT ${armnnAclCommon_sources})
+add_library(armnnAclCommon SHARED ${armnnAclCommon_sources})
 target_include_directories(armnnAclCommon PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
 target_include_directories(armnnAclCommon PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
 target_include_directories(armnnAclCommon PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
 target_include_directories(armnnAclCommon PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
 target_include_directories(armnnAclCommon PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+set_target_properties(armnnAclCommon PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} )
+
+install(TARGETS armnnAclCommon
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/)
--- armnn-20.08.orig/src/backends/aclCommon/common.cmake
+++ armnn-20.08/src/backends/aclCommon/common.cmake
@@ -5,6 +5,6 @@
 
 if(ARMCOMPUTENEON OR ARMCOMPUTECL)
     add_subdirectory(${PROJECT_SOURCE_DIR}/src/backends/aclCommon)
-    list(APPEND armnnLibraries armnnAclCommon)
-    list(APPEND armnnUnitTestLibraries armnnAclCommonUnitTests)
+#    list(APPEND armnnLibraries armnnAclCommon)
+#    list(APPEND armnnUnitTestLibraries armnnAclCommonUnitTests)
 endif()
--- armnn-20.08.orig/src/backends/backendsCommon/CMakeLists.txt
+++ armnn-20.08/src/backends/backendsCommon/CMakeLists.txt
@@ -44,9 +44,9 @@ list(APPEND armnnBackendsCommon_sources
     WorkloadUtils.hpp
 )
 
-if(BUILD_UNIT_TESTS)
-    add_subdirectory(test)
-endif()
+#if(BUILD_UNIT_TESTS)
+#    add_subdirectory(test)
+#endif()
 
 add_library(armnnBackendsCommon OBJECT ${armnnBackendsCommon_sources})
 target_include_directories(armnnBackendsCommon PRIVATE ${PROJECT_SOURCE_DIR}/include/armnn/backends)
--- armnn-20.08.orig/src/backends/backendsCommon/common.cmake
+++ armnn-20.08/src/backends/backendsCommon/common.cmake
@@ -5,4 +5,4 @@
 
 add_subdirectory(${PROJECT_SOURCE_DIR}/src/backends/backendsCommon)
 list(APPEND armnnLibraries armnnBackendsCommon)
-list(APPEND armnnUnitTestLibraries armnnBackendsCommonUnitTests)
+#list(APPEND armnnUnitTestLibraries armnnBackendsCommonUnitTests)
--- armnn-20.08.orig/src/backends/cl/CMakeLists.txt
+++ armnn-20.08/src/backends/cl/CMakeLists.txt
@@ -14,7 +14,7 @@ if(ARMCOMPUTECL)
         ClContextControl.hpp
         ClLayerSupport.cpp
         ClLayerSupport.hpp
-        ClRegistryInitializer.cpp
+        #ClRegistryInitializer.cpp
         ClTensorHandle.hpp
         ClTensorHandleFactory.cpp
         ClTensorHandleFactory.hpp
@@ -26,10 +26,32 @@ if(ARMCOMPUTECL)
 
     add_subdirectory(workloads)
 
-    if(BUILD_UNIT_TESTS)
-        add_subdirectory(test)
+#    if(BUILD_UNIT_TESTS)
+#        add_subdirectory(test)
+#    endif()
+
+    # add workload object to backend module instead of adding to armnn
+    add_library(Arm_GpuAcc_backend MODULE ${armnnClBackend_sources} $<TARGET_OBJECTS:armnnClBackendWorkloads>)
+
+    target_include_directories(Arm_GpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+    target_include_directories(Arm_GpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+    target_include_directories(Arm_GpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+    target_include_directories(Arm_GpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
+    target_include_directories(Arm_GpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+    set_target_properties(Arm_GpuAcc_backend PROPERTIES PREFIX "")
+    target_link_libraries(Arm_GpuAcc_backend ${ARMCOMPUTE_LIBRARIES})
+    target_link_libraries(Arm_GpuAcc_backend armnn)
+    message("# Link OpenCl libraries to GpuAcc backend: "${OPENCL_LIBRARIES})
+    target_link_libraries(Arm_GpuAcc_backend armnnAclCommon)
+    if(OPENCL_LIBRARIES)
+        target_link_libraries(Arm_GpuAcc_backend ${OPENCL_LIBRARIES})
     endif()
 
+    set(armnnMajor "armnn${ARMNN_MAJOR_VERSION}")
+    install(TARGETS Arm_GpuAcc_backend
+            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${armnnMajor})
+
+
 else()
     list(APPEND armnnClBackend_sources
         ClBackendId.hpp
@@ -38,9 +60,3 @@ else()
     )
 endif()
 
-add_library(armnnClBackend OBJECT ${armnnClBackend_sources})
-target_include_directories(armnnClBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
-target_include_directories(armnnClBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
-target_include_directories(armnnClBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
-target_include_directories(armnnClBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
-target_include_directories(armnnClBackend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
--- armnn-20.08.orig/src/backends/cl/ClBackend.cpp
+++ armnn-20.08/src/backends/cl/ClBackend.cpp
@@ -9,6 +9,7 @@
 #include "ClBackendContext.hpp"
 #include "ClLayerSupport.hpp"
 #include "ClTensorHandleFactory.hpp"
+#include "ClBackendInternal.hpp"
 
 #include <armnn/BackendRegistry.hpp>
 
@@ -102,3 +103,27 @@ OptimizationViews ClBackend::OptimizeSub
 }
 
 } // namespace armnn
+
+
+const char* GetBackendId()
+{
+    return armnn::ClBackend::GetIdStatic().Get().c_str();
+}
+
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor)
+{
+    if (!outMajor || !outMinor)
+    {
+        return;
+    }
+
+    armnn::BackendVersion apiVersion = armnn::IBackendInternal::GetApiVersion();
+
+    *outMajor = apiVersion.m_Major;
+    *outMinor = apiVersion.m_Minor;
+}
+
+void* BackendFactory()
+{
+    return new armnn::ClBackend();
+}
--- armnn-20.08.orig/src/backends/cl/ClBackend.hpp
+++ armnn-20.08/src/backends/cl/ClBackend.hpp
@@ -6,38 +6,11 @@
 
 #include <armnn/backends/IBackendInternal.hpp>
 
-namespace armnn
-{
+#include <cstdint>
 
-class ClBackend : public IBackendInternal
+extern "C"
 {
-public:
-    ClBackend()  = default;
-    ~ClBackend() = default;
-
-    static const BackendId& GetIdStatic();
-    const BackendId& GetId() const override { return GetIdStatic(); }
-
-    IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override;
-
-    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
-        const IBackendInternal::IMemoryManagerSharedPtr& memoryManager = nullptr) const override;
-
-    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
-        TensorHandleFactoryRegistry& registry) const override;
-
-    std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override;
-
-    void RegisterTensorHandleFactories(TensorHandleFactoryRegistry& registry) override;
-
-    IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override;
-    IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(
-        const IRuntime::CreationOptions&, IBackendProfilingPtr& backendProfiling) override;
-
-    IBackendInternal::Optimizations GetOptimizations() const override;
-    IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override;
-
-    OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override;
-};
-
-} // namespace armnn
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+}
\ No newline at end of file
--- /dev/null
+++ armnn-20.08/src/backends/cl/ClBackendInternal.hpp
@@ -0,0 +1,44 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/backends/IBackendInternal.hpp>
+
+namespace armnn
+{
+
+class ClBackend : public IBackendInternal
+{
+
+public:
+    ClBackend()  = default;
+    ~ClBackend() = default;
+
+    static const BackendId& GetIdStatic();
+    const BackendId& GetId() const override { return GetIdStatic(); }
+
+    IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override;
+
+    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
+        const IBackendInternal::IMemoryManagerSharedPtr& memoryManager = nullptr) const override;
+
+    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
+        TensorHandleFactoryRegistry& registry) const override;
+
+    std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override;
+
+    void RegisterTensorHandleFactories(TensorHandleFactoryRegistry& registry) override;
+
+    IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override;
+    IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(
+        const IRuntime::CreationOptions&, IBackendProfilingPtr& backendProfiling) override;
+
+    IBackendInternal::Optimizations GetOptimizations() const override;
+    IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override;
+
+    OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override;
+};
+
+} // namespace armnn
--- armnn-20.08.orig/src/backends/cl/backend.cmake
+++ armnn-20.08/src/backends/cl/backend.cmake
@@ -4,11 +4,11 @@
 #
 
 add_subdirectory(${PROJECT_SOURCE_DIR}/src/backends/cl)
-list(APPEND armnnLibraries armnnClBackend)
+#list(APPEND armnnLibraries armnnClBackend)
 
 if(ARMCOMPUTECL)
-    list(APPEND armnnLibraries armnnClBackendWorkloads)
-    list(APPEND armnnUnitTestLibraries armnnClBackendUnitTests)
+#    list(APPEND armnnLibraries armnnClBackendWorkloads)
+#    list(APPEND armnnUnitTestLibraries armnnClBackendUnitTests)
 else()
     message(STATUS "CL backend is disabled")
 endif()
--- armnn-20.08.orig/src/backends/dynamic/reference/CMakeLists.txt
+++ armnn-20.08/src/backends/dynamic/reference/CMakeLists.txt
@@ -18,14 +18,14 @@ file(GLOB RefBackendWorloadFiles ${RefBa
 set(RefBackendFiles ${RefBackendBaseFiles} ${RefBackendWorloadFiles})
 
 # Remove the file that contains the static backend registration
-list(REMOVE_ITEM RefBackendFiles ${RefBackendPath}/RefRegistryInitializer.cpp)
+#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}/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)
-target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
-set_target_properties(Arm_CpuRef_backend PROPERTIES PREFIX "")
-target_link_libraries(Arm_CpuRef_backend armnn)
+#add_library(Arm_CpuRef_backend MODULE ${armnnRefDynamicBackend_sources} ${RefBackendFiles})
+#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)
+#target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+#set_target_properties(Arm_CpuRef_backend PROPERTIES PREFIX "")
+#target_link_libraries(Arm_CpuRef_backend armnn)
--- armnn-20.08.orig/src/backends/neon/CMakeLists.txt
+++ armnn-20.08/src/backends/neon/CMakeLists.txt
@@ -12,7 +12,7 @@ if(ARMCOMPUTENEON)
         NeonInterceptorScheduler.cpp
         NeonLayerSupport.cpp
         NeonLayerSupport.hpp
-        NeonRegistryInitializer.cpp
+        #NeonRegistryInitializer.cpp # Prevent static registration
         NeonTensorHandle.hpp
         NeonTensorHandleFactory.cpp
         NeonTensorHandleFactory.hpp
@@ -24,9 +24,26 @@ if(ARMCOMPUTENEON)
 
     add_subdirectory(workloads)
 
-    if(BUILD_UNIT_TESTS)
-        add_subdirectory(test)
-    endif()
+#    if(BUILD_UNIT_TESTS)
+#        add_subdirectory(test)
+#    endif()
+
+    # add workload object to backend module instead of adding to armnn
+    add_library(Arm_CpuAcc_backend MODULE ${armnnNeonBackend_sources} $<TARGET_OBJECTS:armnnNeonBackendWorkloads>)
+
+    target_include_directories(Arm_CpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+    target_include_directories(Arm_CpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
+    target_include_directories(Arm_CpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+    target_include_directories(Arm_CpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
+    target_include_directories(Arm_CpuAcc_backend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+    set_target_properties(Arm_CpuAcc_backend PROPERTIES PREFIX "")
+    target_link_libraries(Arm_CpuAcc_backend ${ARMCOMPUTE_LIBRARIES})
+    target_link_libraries(Arm_CpuAcc_backend armnn)
+    target_link_libraries(Arm_CpuAcc_backend armnnAclCommon)
+
+    set(armnnMajor "armnn${ARMNN_MAJOR_VERSION}")
+    install(TARGETS Arm_CpuAcc_backend
+            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${armnnMajor})
 
 else()
     list(APPEND armnnNeonBackend_sources
@@ -36,9 +53,3 @@ else()
     )
 endif()
 
-add_library(armnnNeonBackend OBJECT ${armnnNeonBackend_sources})
-target_include_directories(armnnNeonBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
-target_include_directories(armnnNeonBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
-target_include_directories(armnnNeonBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
-target_include_directories(armnnNeonBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
-target_include_directories(armnnNeonBackend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
--- armnn-20.08.orig/src/backends/neon/NeonBackend.cpp
+++ armnn-20.08/src/backends/neon/NeonBackend.cpp
@@ -8,6 +8,7 @@
 #include "NeonWorkloadFactory.hpp"
 #include "NeonLayerSupport.hpp"
 #include "NeonTensorHandleFactory.hpp"
+#include "NeonBackendInternal.hpp"
 
 #include <armnn/BackendRegistry.hpp>
 
@@ -106,3 +107,27 @@ void NeonBackend::RegisterTensorHandleFa
 }
 
 } // namespace armnn
+
+
+const char* GetBackendId()
+{
+    return armnn::NeonBackend::GetIdStatic().Get().c_str();
+}
+
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor)
+{
+    if (!outMajor || !outMinor)
+    {
+        return;
+    }
+
+    armnn::BackendVersion apiVersion = armnn::IBackendInternal::GetApiVersion();
+
+    *outMajor = apiVersion.m_Major;
+    *outMinor = apiVersion.m_Minor;
+}
+
+void* BackendFactory()
+{
+    return new armnn::NeonBackend();
+}
--- armnn-20.08.orig/src/backends/neon/NeonBackend.hpp
+++ armnn-20.08/src/backends/neon/NeonBackend.hpp
@@ -6,37 +6,11 @@
 
 #include <armnn/backends/IBackendInternal.hpp>
 
-namespace armnn
-{
+#include <cstdint>
 
-class NeonBackend : public IBackendInternal
+extern "C"
 {
-public:
-    NeonBackend()  = default;
-    ~NeonBackend() = default;
-
-    static const BackendId& GetIdStatic();
-    const BackendId& GetId() const override { return GetIdStatic(); }
-
-    IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override;
-
-    IWorkloadFactoryPtr CreateWorkloadFactory(
-        const IBackendInternal::IMemoryManagerSharedPtr& memoryManager = nullptr) const override;
-
-    IWorkloadFactoryPtr CreateWorkloadFactory(
-        class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry) const override;
-
-    IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override;
-    IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(
-        const IRuntime::CreationOptions&, IBackendProfilingPtr& backendProfiling) override;
-    IBackendInternal::Optimizations GetOptimizations() const override;
-    IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override;
-
-    OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override;
-
-    std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override;
-
-    void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) override;
-};
-
-} // namespace armnn
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+}
\ No newline at end of file
--- /dev/null
+++ armnn-20.08/src/backends/neon/NeonBackendInternal.hpp
@@ -0,0 +1,42 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/backends/IBackendInternal.hpp>
+
+namespace armnn
+{
+
+class NeonBackend : public IBackendInternal
+{
+public:
+    NeonBackend()  = default;
+    ~NeonBackend() = default;
+
+    static const BackendId& GetIdStatic();
+    const BackendId& GetId() const override { return GetIdStatic(); }
+
+    IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override;
+
+    IWorkloadFactoryPtr CreateWorkloadFactory(
+        const IBackendInternal::IMemoryManagerSharedPtr& memoryManager = nullptr) const override;
+
+    IWorkloadFactoryPtr CreateWorkloadFactory(
+        class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry) const override;
+
+    IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override;
+    IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(
+        const IRuntime::CreationOptions&, IBackendProfilingPtr& backendProfiling) override;
+    IBackendInternal::Optimizations GetOptimizations() const override;
+    IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override;
+
+    OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override;
+
+    std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override;
+
+    void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) override;
+};
+
+} // namespace armnn
--- armnn-20.08.orig/src/backends/neon/backend.cmake
+++ armnn-20.08/src/backends/neon/backend.cmake
@@ -4,11 +4,11 @@
 #
 
 add_subdirectory(${PROJECT_SOURCE_DIR}/src/backends/neon)
-list(APPEND armnnLibraries armnnNeonBackend)
+#list(APPEND armnnLibraries armnnNeonBackend)
 
 if(ARMCOMPUTENEON)
-    list(APPEND armnnLibraries armnnNeonBackendWorkloads)
-    list(APPEND armnnUnitTestLibraries armnnNeonBackendUnitTests)
+#    list(APPEND armnnLibraries armnnNeonBackendWorkloads)
+#    list(APPEND armnnUnitTestLibraries armnnNeonBackendUnitTests)
 else()
     message(STATUS "NEON backend is disabled")
 endif()
--- armnn-20.08.orig/src/backends/reference/CMakeLists.txt
+++ armnn-20.08/src/backends/reference/CMakeLists.txt
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: MIT
 #
 
-if(ARMNNREF)
+#if(ARMNNREF)
     list(APPEND armnnRefBackend_sources
         RefBackend.cpp
         RefBackend.hpp
@@ -14,30 +14,39 @@ if(ARMNNREF)
         RefLayerSupport.hpp
         RefMemoryManager.hpp
         RefMemoryManager.cpp
-        RefRegistryInitializer.cpp
+        #RefRegistryInitializer.cpp  # Prevent static registration
         RefWorkloadFactory.cpp
         RefWorkloadFactory.hpp
         RefTensorHandleFactory.cpp
         RefTensorHandleFactory.hpp
+        RefBackendInternal.hpp
     )
 
     add_subdirectory(workloads)
 
-    if(BUILD_UNIT_TESTS)
-        add_subdirectory(test)
-    endif()
+#    if(BUILD_UNIT_TESTS)
+#        add_subdirectory(test)
+#    endif()
 
-else()
-    list(APPEND armnnRefBackend_sources
-        RefBackendId.hpp
-        RefLayerSupport.cpp
-        RefLayerSupport.hpp
-    )
-endif()
+#else()
+#    list(APPEND armnnRefBackend_sources
+#        RefBackendId.hpp
+#        RefLayerSupport.cpp
+#        RefLayerSupport.hpp
+#    )
+#endif()
+
+# add workload object to backend module instead of adding to armnn
+add_library(Arm_CpuRef_backend MODULE ${armnnRefBackend_sources}  $<TARGET_OBJECTS:armnnRefBackendWorkloads>)
+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)
+target_include_directories(Arm_CpuRef_backend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+set_target_properties(Arm_CpuRef_backend PROPERTIES PREFIX "")
+
+target_link_libraries(Arm_CpuRef_backend armnn)
 
-add_library(armnnRefBackend OBJECT ${armnnRefBackend_sources})
-target_include_directories(armnnRefBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
-target_include_directories(armnnRefBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnnUtils)
-target_include_directories(armnnRefBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
-target_include_directories(armnnRefBackend PRIVATE ${PROJECT_SOURCE_DIR}/src/profiling)
-target_include_directories(armnnRefBackend PRIVATE ${PROJECT_SOURCE_DIR}/profiling/common/include)
+set(armnnMajor "armnn${ARMNN_MAJOR_VERSION}")
+install(TARGETS Arm_CpuRef_backend
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${armnnMajor})
--- armnn-20.08.orig/src/backends/reference/RefBackend.cpp
+++ armnn-20.08/src/backends/reference/RefBackend.cpp
@@ -8,6 +8,7 @@
 #include "RefWorkloadFactory.hpp"
 #include "RefLayerSupport.hpp"
 #include "RefTensorHandleFactory.hpp"
+#include "RefBackendInternal.hpp"
 
 #include <armnn/BackendRegistry.hpp>
 #include <armnn/backends/IBackendContext.hpp>
@@ -92,3 +93,27 @@ void RefBackend::RegisterTensorHandleFac
 }
 
 } // namespace armnn
+
+
+const char* GetBackendId()
+{
+    return armnn::RefBackend::GetIdStatic().Get().c_str();
+}
+
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor)
+{
+    if (!outMajor || !outMinor)
+    {
+        return;
+    }
+
+    armnn::BackendVersion apiVersion = armnn::IBackendInternal::GetApiVersion();
+
+    *outMajor = apiVersion.m_Major;
+    *outMinor = apiVersion.m_Minor;
+}
+
+void* BackendFactory()
+{
+    return new armnn::RefBackend();
+}
\ No newline at end of file
--- armnn-20.08.orig/src/backends/reference/RefBackend.hpp
+++ armnn-20.08/src/backends/reference/RefBackend.hpp
@@ -6,39 +6,12 @@
 
 #include <armnn/backends/IBackendInternal.hpp>
 
-namespace armnn
-{
+#include <cstdint>
 
-class RefBackend : public IBackendInternal
+extern "C"
 {
-public:
-    RefBackend()  = default;
-    ~RefBackend() = default;
-
-    static const BackendId& GetIdStatic();
-    const BackendId& GetId() const override { return GetIdStatic(); }
-
-    IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override;
-
-    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
-        const IBackendInternal::IMemoryManagerSharedPtr& memoryManager = nullptr) const override;
-
-    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
-        class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry) const override;
-
-    IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override;
-
-    IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(
-        const IRuntime::CreationOptions& creationOptions, IBackendProfilingPtr& backendProfiling) override;
-
-    IBackendInternal::Optimizations GetOptimizations() const override;
-    IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override;
-
-    OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override;
-
-    std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override;
-
-    void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) override;
-};
+const char* GetBackendId();
+void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
+void* BackendFactory();
+}
 
-} // namespace armnn
--- /dev/null
+++ armnn-20.08/src/backends/reference/RefBackendInternal.hpp
@@ -0,0 +1,46 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/backends/IBackendInternal.hpp>
+
+namespace armnn
+{
+
+class RefBackend : public IBackendInternal {
+public:
+    RefBackend() = default;
+
+    ~RefBackend() = default;
+
+    static const BackendId &GetIdStatic();
+
+    const BackendId &GetId() const override { return GetIdStatic(); }
+
+    IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override;
+
+    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
+            const IBackendInternal::IMemoryManagerSharedPtr &memoryManager = nullptr) const override;
+
+    IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory(
+            class TensorHandleFactoryRegistry &tensorHandleFactoryRegistry) const override;
+
+    IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions &) const override;
+
+    IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext(
+            const IRuntime::CreationOptions &creationOptions, IBackendProfilingPtr &backendProfiling) override;
+
+    IBackendInternal::Optimizations GetOptimizations() const override;
+
+    IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override;
+
+    OptimizationViews OptimizeSubgraphView(const SubgraphView &subgraph) const override;
+
+    std::vector <ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override;
+
+    void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry &registry) override;
+};
+
+}
\ No newline at end of file
--- armnn-20.08.orig/src/backends/reference/RefRegistryInitializer.cpp
+++ armnn-20.08/src/backends/reference/RefRegistryInitializer.cpp
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: MIT
 //
 
-#include "RefBackend.hpp"
+#include "RefBackendInternal.hpp"
 
 #include <armnn/BackendRegistry.hpp>
 
--- armnn-20.08.orig/src/backends/reference/backend.cmake
+++ armnn-20.08/src/backends/reference/backend.cmake
@@ -4,7 +4,7 @@
 #
 
 add_subdirectory(${PROJECT_SOURCE_DIR}/src/backends/reference)
-list(APPEND armnnLibraries armnnRefBackend)
+#list(APPEND armnnLibraries armnnRefBackend)
 
 if(ARMNNREF)
     list(APPEND armnnLibraries armnnRefBackendWorkloads)
