aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Martincigh <matteo.martincigh@arm.com>2019-08-05 14:12:11 +0100
committerMatteo Martincigh <matteo.martincigh@arm.com>2019-08-09 08:49:22 +0100
commit0c2b2897cb65b562b97014ae748e91d8b9a3d3b4 (patch)
treef4833fedc412ab4c434ca3c4181389f54b6487d2
parente54aa06ec19813b737513ecb8224285d98e871ba (diff)
downloadarmnn-0c2b2897cb65b562b97014ae748e91d8b9a3d3b4.tar.gz
IVGCVSW-3596 Register the dynamic backends in the BackendRegistry
* Added getter for the factory function in the DynamicBackend class * Added new RegisterDynamicBackends method in utils class * Added dynamic backend registration process in the Runtime class * Added new dummy dynamic backend objects for testing * Added unit tests for dynamic backend registration * Added convenience methods to BackendId Change-Id: I01e147d1d6f01bf56747ad946f73f867af5770c4 Signed-off-by: Matteo Martincigh <matteo.martincigh@arm.com>
-rw-r--r--include/armnn/BackendId.hpp3
-rw-r--r--src/armnn/Runtime.cpp6
-rw-r--r--src/armnn/Runtime.hpp8
-rw-r--r--src/backends/backendsCommon/DynamicBackend.cpp34
-rw-r--r--src/backends/backendsCommon/DynamicBackend.hpp6
-rw-r--r--src/backends/backendsCommon/DynamicBackendUtils.cpp68
-rw-r--r--src/backends/backendsCommon/DynamicBackendUtils.hpp3
-rw-r--r--src/backends/backendsCommon/test/CMakeLists.txt24
-rw-r--r--src/backends/backendsCommon/test/DynamicBackendTests.cpp5
-rw-r--r--src/backends/backendsCommon/test/DynamicBackendTests.hpp447
-rw-r--r--src/backends/backendsCommon/test/TestDynamicBackend.cpp15
-rw-r--r--src/backends/backendsCommon/test/TestDynamicBackend.hpp15
12 files changed, 564 insertions, 70 deletions
diff --git a/include/armnn/BackendId.hpp b/include/armnn/BackendId.hpp
index 7dd1460bc1..59d4ac1d45 100644
--- a/include/armnn/BackendId.hpp
+++ b/include/armnn/BackendId.hpp
@@ -129,6 +129,9 @@ public:
const std::string& Get() const { return m_Id; }
+ bool IsEmpty() const { return m_Id.empty(); }
+ bool IsUndefined() const { return m_Id == GetComputeDeviceAsCString(Compute::Undefined); }
+
private:
std::string m_Id;
};
diff --git a/src/armnn/Runtime.cpp b/src/armnn/Runtime.cpp
index 3505030273..ddfa6b4ffd 100644
--- a/src/armnn/Runtime.cpp
+++ b/src/armnn/Runtime.cpp
@@ -9,7 +9,6 @@
#include <backendsCommon/BackendRegistry.hpp>
#include <backendsCommon/IBackendContext.hpp>
#include <backendsCommon/DynamicBackendUtils.hpp>
-#include <backendsCommon/DynamicBackend.hpp>
#include <iostream>
@@ -253,7 +252,10 @@ void Runtime::LoadDynamicBackends(const std::string& overrideBackendPath)
std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
// Create a list of dynamic backends
- DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
+ m_DynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
+
+ // Register the dynamic backends in the backend registry
+ DynamicBackendUtils::RegisterDynamicBackends(m_DynamicBackends);
}
} // namespace armnn
diff --git a/src/armnn/Runtime.hpp b/src/armnn/Runtime.hpp
index 624304ec0a..35684f1f78 100644
--- a/src/armnn/Runtime.hpp
+++ b/src/armnn/Runtime.hpp
@@ -6,11 +6,14 @@
#include "LoadedNetwork.hpp"
#include "DeviceSpec.hpp"
+
#include <armnn/INetwork.hpp>
#include <armnn/IRuntime.hpp>
#include <armnn/Tensor.hpp>
#include <armnn/BackendId.hpp>
+#include <backendsCommon/DynamicBackend.hpp>
+
#include <mutex>
#include <unordered_map>
@@ -100,6 +103,9 @@ private:
int m_NetworkIdCounter;
DeviceSpec m_DeviceSpec;
+
+ /// List of dynamic backends loaded in the runtime
+ std::vector<DynamicBackendPtr> m_DynamicBackends;
};
-}
+} // namespace armnn
diff --git a/src/backends/backendsCommon/DynamicBackend.cpp b/src/backends/backendsCommon/DynamicBackend.cpp
index 06d819b9a7..c576199e1f 100644
--- a/src/backends/backendsCommon/DynamicBackend.cpp
+++ b/src/backends/backendsCommon/DynamicBackend.cpp
@@ -70,18 +70,22 @@ BackendVersion DynamicBackend::GetBackendVersion()
IBackendInternalUniquePtr DynamicBackend::GetBackend()
{
+ // This call throws in case of error
+ return CreateBackend();
+}
+
+BackendRegistry::FactoryFunction DynamicBackend::GetFactoryFunction()
+{
if (m_BackendFactoryFunction == nullptr)
{
- throw RuntimeException("GetBackend error: invalid function pointer");
+ throw RuntimeException("GetFactoryFunction error: invalid function pointer");
}
- auto backendPointer = reinterpret_cast<IBackendInternal*>(m_BackendFactoryFunction());
- if (backendPointer == nullptr)
+ return [this]() -> IBackendInternalUniquePtr
{
- throw RuntimeException("GetBackend error: backend instance must not be null");
- }
-
- return std::unique_ptr<IBackendInternal>(backendPointer);
+ // This call throws in case of error
+ return CreateBackend();
+ };
}
template<typename BackendFunctionType>
@@ -108,4 +112,20 @@ BackendFunctionType DynamicBackend::SetFunctionPointer(const std::string& backen
return functionPointer;
}
+IBackendInternalUniquePtr DynamicBackend::CreateBackend()
+{
+ if (m_BackendFactoryFunction == nullptr)
+ {
+ throw RuntimeException("CreateBackend error: invalid function pointer");
+ }
+
+ auto backendPointer = reinterpret_cast<IBackendInternal*>(m_BackendFactoryFunction());
+ if (backendPointer == nullptr)
+ {
+ throw RuntimeException("CreateBackend error: backend instance must not be null");
+ }
+
+ return std::unique_ptr<IBackendInternal>(backendPointer);
+}
+
} // namespace armnn
diff --git a/src/backends/backendsCommon/DynamicBackend.hpp b/src/backends/backendsCommon/DynamicBackend.hpp
index b202309c31..34c001958d 100644
--- a/src/backends/backendsCommon/DynamicBackend.hpp
+++ b/src/backends/backendsCommon/DynamicBackend.hpp
@@ -6,6 +6,7 @@
#pragma once
#include "IBackendInternal.hpp"
+#include "BackendRegistry.hpp"
#include <functional>
#include <memory>
@@ -13,7 +14,7 @@
namespace armnn
{
-class DynamicBackend
+class DynamicBackend final
{
public:
using HandleCloser = std::function<void(const void*)>;
@@ -25,10 +26,13 @@ public:
BackendId GetBackendId();
BackendVersion GetBackendVersion();
IBackendInternalUniquePtr GetBackend();
+ BackendRegistry::FactoryFunction GetFactoryFunction();
private:
+ /// Private utility functions
template<typename BackendFunctionType>
BackendFunctionType SetFunctionPointer(const std::string& backendFunctionName);
+ IBackendInternalUniquePtr CreateBackend();
/// Backend function pointer types
using IdFunctionType = const char*(*)();
diff --git a/src/backends/backendsCommon/DynamicBackendUtils.cpp b/src/backends/backendsCommon/DynamicBackendUtils.cpp
index 57a605608c..38ac5ad6af 100644
--- a/src/backends/backendsCommon/DynamicBackendUtils.cpp
+++ b/src/backends/backendsCommon/DynamicBackendUtils.cpp
@@ -281,7 +281,6 @@ std::vector<DynamicBackendPtr> DynamicBackendUtils::CreateDynamicBackends(const
{
BOOST_LOG_TRIVIAL(warning) << "Invalid dynamic backend object for the shared object file \""
<< sharedObject << "\"";
-
continue;
}
@@ -292,4 +291,71 @@ std::vector<DynamicBackendPtr> DynamicBackendUtils::CreateDynamicBackends(const
return dynamicBackends;
}
+void DynamicBackendUtils::RegisterDynamicBackends(const std::vector<DynamicBackendPtr>& dynamicBackends)
+{
+ // Get a reference of the backend registry
+ BackendRegistry& backendRegistry = BackendRegistryInstance();
+
+ // Register the dynamic backends in the backend registry
+ RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
+}
+
+void DynamicBackendUtils::RegisterDynamicBackendsImpl(BackendRegistry& backendRegistry,
+ const std::vector<DynamicBackendPtr>& dynamicBackends)
+{
+ // Register the dynamic backends in the backend registry
+ for (const DynamicBackendPtr& dynamicBackend : dynamicBackends)
+ {
+ BackendId dynamicBackendId;
+ try
+ {
+ dynamicBackendId = dynamicBackend->GetBackendId();
+ }
+ catch (const RuntimeException& e)
+ {
+ BOOST_LOG_TRIVIAL(warning) << "Cannot register dynamic backend, "
+ << "an error has occurred when getting the backend id: " << e.what();
+ continue;
+ }
+ if (dynamicBackendId.IsEmpty() ||
+ dynamicBackendId.IsUndefined())
+ {
+ BOOST_LOG_TRIVIAL(warning) << "Cannot register dynamic backend, invalid backend id: " << dynamicBackendId;
+ continue;
+ }
+
+ // Check whether the dynamic backend is already registered
+ bool backendAlreadyRegistered = backendRegistry.IsBackendRegistered(dynamicBackendId);
+ if (backendAlreadyRegistered)
+ {
+ BOOST_LOG_TRIVIAL(warning) << "Cannot register dynamic backend \"" << dynamicBackendId
+ << "\": backend already registered";
+ continue;
+ }
+
+ // Get the dynamic backend factory function
+ BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
+ try
+ {
+ dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction();
+ }
+ catch (const RuntimeException& e)
+ {
+ BOOST_LOG_TRIVIAL(warning) << "Cannot register dynamic backend \"" << dynamicBackendId
+ << "\": an error has occurred when getting the backend factory function: "
+ << e.what();
+ continue;
+ }
+ if (dynamicBackendFactoryFunction == nullptr)
+ {
+ BOOST_LOG_TRIVIAL(warning) << "Cannot register dynamic backend \"" << dynamicBackendId
+ << "\": invalid backend factory function";
+ continue;
+ }
+
+ // Register the dynamic backend
+ backendRegistry.Register(dynamicBackendId, dynamicBackendFactoryFunction);
+ }
+}
+
} // namespace armnn
diff --git a/src/backends/backendsCommon/DynamicBackendUtils.hpp b/src/backends/backendsCommon/DynamicBackendUtils.hpp
index 9c10df7efc..187b0b1eab 100644
--- a/src/backends/backendsCommon/DynamicBackendUtils.hpp
+++ b/src/backends/backendsCommon/DynamicBackendUtils.hpp
@@ -39,11 +39,14 @@ public:
static std::vector<std::string> GetSharedObjects(const std::vector<std::string>& backendPaths);
static std::vector<DynamicBackendPtr> CreateDynamicBackends(const std::vector<std::string>& sharedObjects);
+ static void RegisterDynamicBackends(const std::vector<DynamicBackendPtr>& dynamicBackends);
protected:
/// Protected methods for testing purposes
static bool IsBackendCompatibleImpl(const BackendVersion& backendApiVersion, const BackendVersion& backendVersion);
static std::vector<std::string> GetBackendPathsImpl(const std::string& backendPaths);
+ static void RegisterDynamicBackendsImpl(BackendRegistry& backendRegistry,
+ const std::vector<DynamicBackendPtr>& dynamicBackends);
private:
static std::string GetDlError();
diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt
index 6714a20122..f5173564f2 100644
--- a/src/backends/backendsCommon/test/CMakeLists.txt
+++ b/src/backends/backendsCommon/test/CMakeLists.txt
@@ -215,6 +215,14 @@ target_link_libraries(Arm_TestValid4_backend armnn)
set_target_properties(Arm_TestValid4_backend PROPERTIES PREFIX "")
set_target_properties(Arm_TestValid4_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/backendsTestPath6)
+add_library_ex(Arm_TestValid5_backend MODULE ${testDynamicBackend_sources})
+target_compile_definitions(Arm_TestValid5_backend PRIVATE -DVALID_TEST_DYNAMIC_BACKEND_5)
+target_include_directories(Arm_TestValid5_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(Arm_TestValid5_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+target_link_libraries(Arm_TestValid5_backend armnn)
+set_target_properties(Arm_TestValid5_backend PROPERTIES PREFIX "")
+set_target_properties(Arm_TestValid5_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/backendsTestPath6)
+
add_library_ex(Arm_TestInvalid9_backend MODULE ${testDynamicBackend_sources})
target_compile_definitions(Arm_TestInvalid9_backend PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_9)
target_include_directories(Arm_TestInvalid9_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
@@ -223,4 +231,20 @@ target_link_libraries(Arm_TestInvalid9_backend armnn)
set_target_properties(Arm_TestInvalid9_backend PROPERTIES PREFIX "")
set_target_properties(Arm_TestInvalid9_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/backendsTestPath6)
+add_library_ex(Arm_TestInvalid10_backend MODULE ${testDynamicBackend_sources})
+target_compile_definitions(Arm_TestInvalid10_backend PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_10)
+target_include_directories(Arm_TestInvalid10_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(Arm_TestInvalid10_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+target_link_libraries(Arm_TestInvalid10_backend armnn)
+set_target_properties(Arm_TestInvalid10_backend PROPERTIES PREFIX "")
+set_target_properties(Arm_TestInvalid10_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/backendsTestPath9)
+
+add_library_ex(Arm_TestInvalid11_backend MODULE ${testDynamicBackend_sources})
+target_compile_definitions(Arm_TestInvalid11_backend PRIVATE -DINVALID_TEST_DYNAMIC_BACKEND_11)
+target_include_directories(Arm_TestInvalid11_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/armnn)
+target_include_directories(Arm_TestInvalid11_backend PRIVATE ${PROJECT_SOURCE_DIR}/src/backends)
+target_link_libraries(Arm_TestInvalid11_backend armnn)
+set_target_properties(Arm_TestInvalid11_backend PROPERTIES PREFIX "")
+set_target_properties(Arm_TestInvalid11_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/backendsTestPath9)
+
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/backendsTestPath7)
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
index b5d159ab13..21ce2dbde4 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
@@ -50,4 +50,9 @@ ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendsNoPaths, CreateDynamicBackendsNoPath
ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendsAllInvalid, CreateDynamicBackendsAllInvalidTestImpl);
ARMNN_SIMPLE_TEST_CASE(CreateDynamicBackendsMixedTypes, CreateDynamicBackendsMixedTypesTestImpl);
+ARMNN_SIMPLE_TEST_CASE(RegisterSingleDynamicBackend, RegisterSingleDynamicBackendTestImpl);
+ARMNN_SIMPLE_TEST_CASE(RegisterMultipleDynamicBackends, RegisterMultipleDynamicBackendsTestImpl);
+ARMNN_SIMPLE_TEST_CASE(RegisterMultipleInvalidDynamicBackends, RegisterMultipleInvalidDynamicBackendsTestImpl);
+ARMNN_SIMPLE_TEST_CASE(RegisterMixedDynamicBackends, RegisterMixedDynamicBackendsTestImpl);
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
index e3fbe311bc..ae922bc26d 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
@@ -36,17 +36,43 @@ static std::string g_TestInvalidTestDynamicBackend7FileName = "libInvalidTestDyn
static std::string g_TestValidBackend2FileName = "Arm_TestValid2_backend.so";
static std::string g_TestValidBackend3FileName = "Arm_TestValid3_backend.so";
static std::string g_TestValidBackend4FileName = "Arm_TestValid4_backend.so";
+static std::string g_TestValidBackend5FileName = "Arm_TestValid5_backend.so";
static std::string g_TestInvalidBackend8FileName = "Arm_TestInvalid8_backend.so";
static std::string g_TestInvalidBackend9FileName = "Arm_TestInvalid9_backend.so";
+static std::string g_TestInvalidBackend10FileName = "Arm_TestInvalid10_backend.so";
+static std::string g_TestInvalidBackend11FileName = "Arm_TestInvalid11_backend.so";
+
+static std::string g_TestDynamicBackendsSubDir1 = "backendsTestPath1/";
+static std::string g_TestDynamicBackendsSubDir2 = "backendsTestPath2/";
+static std::string g_TestDynamicBackendsSubDir3 = "backendsTestPath3/";
+static std::string g_TestDynamicBackendsSubDir4 = "backendsTestPath4/";
+static std::string g_TestDynamicBackendsSubDir5 = "backendsTestPath5/";
+static std::string g_TestDynamicBackendsSubDir6 = "backendsTestPath6/";
+static std::string g_TestDynamicBackendsSubDir7 = "backendsTestPath7/";
+static std::string g_TestDynamicBackendsSubDir8 = "backendsTestPath8/";
+static std::string g_TestDynamicBackendsSubDir9 = "backendsTestPath9/";
+
+// Wrapper class used for testing
+class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
+{
+public:
+ static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion,
+ const armnn::BackendVersion& backendVersion)
+ {
+ return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
+ }
-static std::string g_TestDynamicBackendsFileParsingSubDir1 = "backendsTestPath1/";
-static std::string g_TestDynamicBackendsFileParsingSubDir2 = "backendsTestPath2/";
-static std::string g_TestDynamicBackendsFileParsingSubDir3 = "backendsTestPath3/";
-static std::string g_TestDynamicBackendsFileParsingSubDir4 = "backendsTestPath4/";
-static std::string g_TestDynamicBackendsFileParsingSubDir5 = "backendsTestPath5/";
-static std::string g_TestDynamicBackendsFileParsingSubDir6 = "backendsTestPath6/";
-static std::string g_TestDynamicBackendsFileParsingSubDir7 = "backendsTestPath7/";
-static std::string g_TestDynamicBackendsFileParsingSubDir8 = "backendsTestPath8/";
+ static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
+ {
+ return GetBackendPathsImpl(path);
+ }
+
+ static void RegisterDynamicBackendsImplTest(armnn::BackendRegistry& backendRegistry,
+ const std::vector<armnn::DynamicBackendPtr>& dynamicBackends)
+ {
+ RegisterDynamicBackendsImpl(backendRegistry, dynamicBackends);
+ }
+};
std::string GetTestDirectoryBasePath()
{
@@ -222,16 +248,6 @@ void BackendVersioningTestImpl()
{
using namespace armnn;
- class TestDynamicBackendUtils : public DynamicBackendUtils
- {
- public:
- static bool IsBackendCompatibleTest(const BackendVersion& backendApiVersion,
- const BackendVersion& backendVersion)
- {
- return IsBackendCompatibleImpl(backendApiVersion, backendVersion);
- }
- };
-
// The backend API version used for the tests
BackendVersion backendApiVersion{ 2, 4 };
@@ -297,11 +313,20 @@ void CreateValidDynamicBackendObjectTestImpl()
BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
BOOST_TEST((dynamicBackendVersion == IBackendInternal::GetApiVersion()));
- IBackendInternalUniquePtr dynamicBackendInstance;
- BOOST_CHECK_NO_THROW(dynamicBackendInstance = dynamicBackend->GetBackend());
- BOOST_TEST((dynamicBackendInstance != nullptr));
+ IBackendInternalUniquePtr dynamicBackendInstance1;
+ BOOST_CHECK_NO_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend());
+ BOOST_TEST((dynamicBackendInstance1 != nullptr));
+
+ BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
+ BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
+ BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
+
+ IBackendInternalUniquePtr dynamicBackendInstance2;
+ BOOST_CHECK_NO_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction());
+ BOOST_TEST((dynamicBackendInstance2 != nullptr));
- BOOST_TEST((dynamicBackendInstance->GetId() == "ValidTestDynamicBackend"));
+ BOOST_TEST((dynamicBackendInstance1->GetId() == "ValidTestDynamicBackend"));
+ BOOST_TEST((dynamicBackendInstance2->GetId() == "ValidTestDynamicBackend"));
}
void CreateDynamicBackendObjectInvalidHandleTestImpl()
@@ -444,9 +469,17 @@ void CreateDynamicBackendObjectInvalidInterface6TestImpl()
BOOST_CHECK_NO_THROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion());
BOOST_TEST((dynamicBackendVersion == BackendVersion({ 1, 0 })));
- IBackendInternalUniquePtr dynamicBackendInstance;
- BOOST_CHECK_THROW(dynamicBackendInstance = dynamicBackend->GetBackend(), RuntimeException);
- BOOST_TEST((dynamicBackendInstance == nullptr));
+ IBackendInternalUniquePtr dynamicBackendInstance1;
+ BOOST_CHECK_THROW(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException);
+ BOOST_TEST((dynamicBackendInstance1 == nullptr));
+
+ BackendRegistry::FactoryFunction dynamicBackendFactoryFunction = nullptr;
+ BOOST_CHECK_NO_THROW(dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction());
+ BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
+
+ IBackendInternalUniquePtr dynamicBackendInstance2;
+ BOOST_CHECK_THROW(dynamicBackendInstance2 = dynamicBackendFactoryFunction(), RuntimeException);
+ BOOST_TEST((dynamicBackendInstance2 == nullptr));
}
void CreateDynamicBackendObjectInvalidInterface7TestImpl()
@@ -482,25 +515,16 @@ void GetBackendPathsTestImpl()
// ├─ backendsTestPath3/ -> exists, but empty
// └─ backendsTestPath4/ -> does not exist
- std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir1);
- std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir2);
- std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir3);
- std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir4);
+ std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
+ std::string subDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
+ std::string subDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
+ std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
BOOST_CHECK(exists(subDir1));
BOOST_CHECK(exists(subDir2));
BOOST_CHECK(exists(subDir3));
BOOST_CHECK(!exists(subDir4));
- class TestDynamicBackendUtils : public DynamicBackendUtils
- {
- public:
- static std::vector<std::string> GetBackendPathsImplTest(const std::string& path)
- {
- return GetBackendPathsImpl(path);
- }
- };
-
// No path
BOOST_TEST(TestDynamicBackendUtils::GetBackendPathsImplTest("").empty());
@@ -564,8 +588,8 @@ void GetBackendPathsOverrideTestImpl()
using namespace armnn;
using namespace boost::filesystem;
- std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir1);
- std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir4);
+ std::string subDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
+ std::string subDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
BOOST_CHECK(exists(subDir1));
BOOST_CHECK(!exists(subDir4));
@@ -629,10 +653,10 @@ void GetSharedObjectsTestImpl()
//
// Arm_GpuAcc_backend.so -> valid (but duplicated from backendsTestPath1/)
- std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir1);
- std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir2);
- std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir3);
- std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir4);
+ std::string testDynamicBackendsSubDir1 = GetTestSubDirectory(g_TestDynamicBackendsSubDir1);
+ std::string testDynamicBackendsSubDir2 = GetTestSubDirectory(g_TestDynamicBackendsSubDir2);
+ std::string testDynamicBackendsSubDir3 = GetTestSubDirectory(g_TestDynamicBackendsSubDir3);
+ std::string testDynamicBackendsSubDir4 = GetTestSubDirectory(g_TestDynamicBackendsSubDir4);
BOOST_CHECK(exists(testDynamicBackendsSubDir1));
BOOST_CHECK(exists(testDynamicBackendsSubDir2));
BOOST_CHECK(exists(testDynamicBackendsSubDir3));
@@ -676,7 +700,7 @@ void CreateDynamicBackendsTestImpl()
using namespace armnn;
using namespace boost::filesystem;
- // The test covers three directories:
+ // The test covers four directories:
// <unit test path>/src/backends/backendsCommon/test/
// ├─ backendsTestPath5/ -> exists, contains files
// ├─ backendsTestPath6/ -> exists, contains files
@@ -695,14 +719,15 @@ void CreateDynamicBackendsTestImpl()
// Arm_TestValid4_backend.so -> valid (it has a different filename,
// but it has the same backend id of Arm_TestValid2_backend.so
// and the same version)
+ // Arm_TestValid5_backend.so -> valid (basic backend name)
// Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
// but it has the same backend id of Arm_TestValid2_backend.so
// and a version incompatible with the Backend API)
- std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir5);
- std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir6);
- std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir7);
- std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir8);
+ std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
+ std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
+ std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
+ std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
BOOST_CHECK(exists(testDynamicBackendsSubDir5));
BOOST_CHECK(exists(testDynamicBackendsSubDir6));
BOOST_CHECK(exists(testDynamicBackendsSubDir7));
@@ -718,17 +743,19 @@ void CreateDynamicBackendsTestImpl()
std::vector<std::string> sharedObjects = DynamicBackendUtils::GetSharedObjects(backendPaths);
std::vector<DynamicBackendPtr> dynamicBackends = DynamicBackendUtils::CreateDynamicBackends(sharedObjects);
- BOOST_TEST(dynamicBackends.size() == 4);
+ BOOST_TEST(dynamicBackends.size() == 5);
BOOST_TEST((dynamicBackends[0] != nullptr));
BOOST_TEST((dynamicBackends[1] != nullptr));
BOOST_TEST((dynamicBackends[2] != nullptr));
BOOST_TEST((dynamicBackends[3] != nullptr));
+ BOOST_TEST((dynamicBackends[4] != nullptr));
// Duplicates are allowed here, they will be skipped later during the backend registration
BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
BOOST_TEST((dynamicBackends[1]->GetBackendId() == "TestValid3"));
BOOST_TEST((dynamicBackends[2]->GetBackendId() == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
BOOST_TEST((dynamicBackends[3]->GetBackendId() == "TestValid2")); // From Arm_TestValid4_backend.so
+ BOOST_TEST((dynamicBackends[4]->GetBackendId() == "TestValid5"));
}
void CreateDynamicBackendsNoPathsTestImpl()
@@ -760,8 +787,8 @@ void CreateDynamicBackendsMixedTypesTestImpl()
using namespace armnn;
using namespace boost::filesystem;
- std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir5);
- std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsFileParsingSubDir6);
+ std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
+ std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
BOOST_CHECK(exists(testDynamicBackendsSubDir5));
BOOST_CHECK(exists(testDynamicBackendsSubDir6));
@@ -788,3 +815,319 @@ void CreateDynamicBackendsMixedTypesTestImpl()
BOOST_TEST((dynamicBackends[0] != nullptr));
BOOST_TEST((dynamicBackends[0]->GetBackendId() == "TestValid2"));
}
+
+void RegisterSingleDynamicBackendTestImpl()
+{
+ using namespace armnn;
+ using namespace boost::filesystem;
+
+ // Register one valid dynamic backend
+
+ // Dummy registry used for testing
+ BackendRegistry backendRegistry;
+ BOOST_TEST(backendRegistry.Size() == 0);
+
+ std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
+ BOOST_CHECK(exists(testDynamicBackendsSubDir5));
+
+ std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
+ BOOST_CHECK(exists(testValidBackend2FilePath));
+
+ std::vector<std::string> sharedObjects{ testValidBackend2FilePath };
+ std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
+
+ BOOST_TEST(dynamicBackends.size() == 1);
+ BOOST_TEST((dynamicBackends[0] != nullptr));
+
+ BackendId dynamicBackendId = dynamicBackends[0]->GetBackendId();
+ BOOST_TEST((dynamicBackendId == "TestValid2"));
+
+ BackendVersion dynamicBackendVersion = dynamicBackends[0]->GetBackendVersion();
+ BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
+
+ TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
+ BOOST_TEST(backendRegistry.Size() == 1);
+
+ BackendIdSet backendIds = backendRegistry.GetBackendIds();
+ BOOST_TEST(backendIds.size() == 1);
+ BOOST_TEST((backendIds.find(dynamicBackendId) != backendIds.end()));
+
+ auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
+ BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
+
+ IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
+ BOOST_TEST((dynamicBackend != nullptr));
+ BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
+}
+
+void RegisterMultipleDynamicBackendsTestImpl()
+{
+ using namespace armnn;
+ using namespace boost::filesystem;
+
+ // Register many valid dynamic backends
+
+ std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
+ std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
+ BOOST_CHECK(exists(testDynamicBackendsSubDir5));
+ BOOST_CHECK(exists(testDynamicBackendsSubDir6));
+
+ std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
+ std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
+ std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
+ BOOST_CHECK(exists(testValidBackend2FilePath));
+ BOOST_CHECK(exists(testValidBackend3FilePath));
+ BOOST_CHECK(exists(testValidBackend5FilePath));
+
+ std::vector<std::string> sharedObjects
+ {
+ testValidBackend2FilePath,
+ testValidBackend3FilePath,
+ testValidBackend5FilePath
+ };
+ std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
+
+ BOOST_TEST(dynamicBackends.size() == 3);
+ BOOST_TEST((dynamicBackends[0] != nullptr));
+ BOOST_TEST((dynamicBackends[1] != nullptr));
+ BOOST_TEST((dynamicBackends[2] != nullptr));
+
+ BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
+ BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
+ BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
+ BOOST_TEST((dynamicBackendId1 == "TestValid2"));
+ BOOST_TEST((dynamicBackendId2 == "TestValid3"));
+ BOOST_TEST((dynamicBackendId3 == "TestValid5"));
+
+ for (size_t i = 0; i < dynamicBackends.size(); i++)
+ {
+ BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
+ BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
+ }
+
+ // Dummy registry used for testing
+ BackendRegistry backendRegistry;
+ BOOST_TEST(backendRegistry.Size() == 0);
+
+ TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
+ BOOST_TEST(backendRegistry.Size() == 3);
+
+ BackendIdSet backendIds = backendRegistry.GetBackendIds();
+ BOOST_TEST(backendIds.size() == 3);
+ BOOST_TEST((backendIds.find(dynamicBackendId1) != backendIds.end()));
+ BOOST_TEST((backendIds.find(dynamicBackendId2) != backendIds.end()));
+ BOOST_TEST((backendIds.find(dynamicBackendId3) != backendIds.end()));
+
+ for (size_t i = 0; i < dynamicBackends.size(); i++)
+ {
+ BackendId dynamicBackendId = dynamicBackends[i]->GetBackendId();
+
+ auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(dynamicBackendId);
+ BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
+
+ IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
+ BOOST_TEST((dynamicBackend != nullptr));
+ BOOST_TEST((dynamicBackend->GetId() == dynamicBackendId));
+ }
+}
+
+void RegisterMultipleInvalidDynamicBackendsTestImpl()
+{
+ using namespace armnn;
+ using namespace boost::filesystem;
+
+ // Try to register many invalid dynamic backends
+
+ // The test covers one directory:
+ // <unit test path>/src/backends/backendsCommon/test/
+ // └─ backendsTestPath9/ -> exists, contains files
+ //
+ // The test sub-directory backendsTestPath9/ contains the following test files:
+ //
+ // Arm_TestInvalid10_backend.so -> not valid (invalid backend id)
+ // Arm_TestInvalid11_backend.so -> not valid (invalid backend id)
+
+ std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
+ BOOST_CHECK(exists(testDynamicBackendsSubDir9));
+
+ std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
+ g_TestInvalidBackend10FileName);
+ std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
+ g_TestInvalidBackend11FileName);
+ BOOST_CHECK(exists(testInvalidBackend10FilePath));
+ BOOST_CHECK(exists(testInvalidBackend11FilePath));
+
+ std::vector<std::string> sharedObjects
+ {
+ testInvalidBackend10FilePath,
+ testInvalidBackend11FilePath,
+ "InvalidSharedObject"
+ };
+ std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
+
+ BOOST_TEST(dynamicBackends.size() == 2);
+ BOOST_TEST((dynamicBackends[0] != nullptr));
+ BOOST_TEST((dynamicBackends[1] != nullptr));
+
+ BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
+ BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
+ BOOST_TEST((dynamicBackendId1 == ""));
+ BOOST_TEST((dynamicBackendId2 == "Unknown"));
+
+ for (size_t i = 0; i < dynamicBackends.size(); i++)
+ {
+ BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
+ BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
+ }
+
+ // Dummy registry used for testing
+ BackendRegistry backendRegistry;
+ BOOST_TEST(backendRegistry.Size() == 0);
+
+ // Check that no dynamic backend got registered
+ TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
+ BOOST_TEST(backendRegistry.Size() == 0);
+}
+
+void RegisterMixedDynamicBackendsTestImpl()
+{
+ using namespace armnn;
+ using namespace boost::filesystem;
+
+ // The test covers five directories:
+ // <unit test path>/src/backends/backendsCommon/test/
+ // ├─ backendsTestPath5/ -> exists, contains files
+ // ├─ backendsTestPath6/ -> exists, contains files
+ // ├─ backendsTestPath7/ -> exists, but empty
+ // ├─ backendsTestPath8/ -> does not exist
+ // └─ backendsTestPath9/ -> exists, contains files
+ //
+ // The test sub-directory backendsTestPath5/ contains the following test files:
+ //
+ // Arm_TestValid2_backend.so -> valid (basic backend name)
+ // Arm_TestValid3_backend.so -> valid (basic backend name)
+ // Arm_TestInvalid8_backend.so -> not valid (invalid backend id)
+ //
+ // The test sub-directory backendsTestPath6/ contains the following test files:
+ //
+ // Arm_TestValid2_backend.so -> valid (but duplicated from backendsTestPath5/)
+ // Arm_TestValid4_backend.so -> valid (it has a different filename,
+ // but it has the same backend id of Arm_TestValid2_backend.so
+ // and the same version)
+ // Arm_TestValid5_backend.so -> valid (basic backend name)
+ // Arm_TestInvalid9_backend.so -> not valid (it has a different filename,
+ // but it has the same backend id of Arm_TestValid2_backend.so
+ // and a version incompatible with the Backend API)
+ //
+ // The test sub-directory backendsTestPath9/ contains the following test files:
+ //
+ // Arm_TestInvalid10_backend.so -> not valid (empty backend id)
+ // Arm_TestInvalid11_backend.so -> not valid ("Unknown" backend id)
+
+ std::string testDynamicBackendsSubDir5 = GetTestSubDirectory(g_TestDynamicBackendsSubDir5);
+ std::string testDynamicBackendsSubDir6 = GetTestSubDirectory(g_TestDynamicBackendsSubDir6);
+ std::string testDynamicBackendsSubDir7 = GetTestSubDirectory(g_TestDynamicBackendsSubDir7);
+ std::string testDynamicBackendsSubDir8 = GetTestSubDirectory(g_TestDynamicBackendsSubDir8);
+ std::string testDynamicBackendsSubDir9 = GetTestSubDirectory(g_TestDynamicBackendsSubDir9);
+ BOOST_CHECK(exists(testDynamicBackendsSubDir5));
+ BOOST_CHECK(exists(testDynamicBackendsSubDir6));
+ BOOST_CHECK(exists(testDynamicBackendsSubDir7));
+ BOOST_CHECK(!exists(testDynamicBackendsSubDir8));
+ BOOST_CHECK(exists(testDynamicBackendsSubDir9));
+
+ std::string testValidBackend2FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend2FileName);
+ std::string testValidBackend3FilePath = GetTestFilePath(testDynamicBackendsSubDir5, g_TestValidBackend3FileName);
+ std::string testValidBackend2DupFilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend2FileName);
+ std::string testValidBackend4FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend4FileName);
+ std::string testValidBackend5FilePath = GetTestFilePath(testDynamicBackendsSubDir6, g_TestValidBackend5FileName);
+ std::string testInvalidBackend8FilePath = GetTestFilePath(testDynamicBackendsSubDir5,
+ g_TestInvalidBackend8FileName);
+ std::string testInvalidBackend9FilePath = GetTestFilePath(testDynamicBackendsSubDir6,
+ g_TestInvalidBackend9FileName);
+ std::string testInvalidBackend10FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
+ g_TestInvalidBackend10FileName);
+ std::string testInvalidBackend11FilePath = GetTestFilePath(testDynamicBackendsSubDir9,
+ g_TestInvalidBackend11FileName);
+ BOOST_CHECK(exists(testValidBackend2FilePath));
+ BOOST_CHECK(exists(testValidBackend3FilePath));
+ BOOST_CHECK(exists(testValidBackend2DupFilePath));
+ BOOST_CHECK(exists(testValidBackend4FilePath));
+ BOOST_CHECK(exists(testValidBackend5FilePath));
+ BOOST_CHECK(exists(testInvalidBackend8FilePath));
+ BOOST_CHECK(exists(testInvalidBackend9FilePath));
+ BOOST_CHECK(exists(testInvalidBackend10FilePath));
+ BOOST_CHECK(exists(testInvalidBackend11FilePath));
+
+ std::vector<std::string> sharedObjects
+ {
+ testValidBackend2FilePath,
+ testValidBackend3FilePath,
+ testValidBackend2DupFilePath,
+ testValidBackend4FilePath,
+ testValidBackend5FilePath,
+ testInvalidBackend8FilePath,
+ testInvalidBackend9FilePath,
+ testInvalidBackend10FilePath,
+ testInvalidBackend11FilePath,
+ "InvalidSharedObject"
+ };
+ std::vector<DynamicBackendPtr> dynamicBackends = TestDynamicBackendUtils::CreateDynamicBackends(sharedObjects);
+
+ BOOST_TEST(dynamicBackends.size() == 7);
+ BOOST_TEST((dynamicBackends[0] != nullptr));
+ BOOST_TEST((dynamicBackends[1] != nullptr));
+ BOOST_TEST((dynamicBackends[2] != nullptr));
+ BOOST_TEST((dynamicBackends[3] != nullptr));
+ BOOST_TEST((dynamicBackends[4] != nullptr));
+ BOOST_TEST((dynamicBackends[5] != nullptr));
+ BOOST_TEST((dynamicBackends[6] != nullptr));
+
+ BackendId dynamicBackendId1 = dynamicBackends[0]->GetBackendId();
+ BackendId dynamicBackendId2 = dynamicBackends[1]->GetBackendId();
+ BackendId dynamicBackendId3 = dynamicBackends[2]->GetBackendId();
+ BackendId dynamicBackendId4 = dynamicBackends[3]->GetBackendId();
+ BackendId dynamicBackendId5 = dynamicBackends[4]->GetBackendId();
+ BackendId dynamicBackendId6 = dynamicBackends[5]->GetBackendId();
+ BackendId dynamicBackendId7 = dynamicBackends[6]->GetBackendId();
+ BOOST_TEST((dynamicBackendId1 == "TestValid2"));
+ BOOST_TEST((dynamicBackendId2 == "TestValid3"));
+ BOOST_TEST((dynamicBackendId3 == "TestValid2")); // From duplicate Arm_TestValid2_backend.so
+ BOOST_TEST((dynamicBackendId4 == "TestValid2")); // From Arm_TestValid4_backend.so
+ BOOST_TEST((dynamicBackendId5 == "TestValid5"));
+ BOOST_TEST((dynamicBackendId6 == ""));
+ BOOST_TEST((dynamicBackendId7 == "Unknown"));
+
+ for (size_t i = 0; i < dynamicBackends.size(); i++)
+ {
+ BackendVersion dynamicBackendVersion = dynamicBackends[i]->GetBackendVersion();
+ BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatible(dynamicBackendVersion));
+ }
+
+ // Dummy registry used for testing
+ BackendRegistry backendRegistry;
+ BOOST_TEST(backendRegistry.Size() == 0);
+
+ std::vector<BackendId> expectedRegisteredbackendIds
+ {
+ "TestValid2",
+ "TestValid3",
+ "TestValid5"
+ };
+
+ TestDynamicBackendUtils::RegisterDynamicBackendsImplTest(backendRegistry, dynamicBackends);
+ BOOST_TEST(backendRegistry.Size() == expectedRegisteredbackendIds.size());
+
+ BackendIdSet backendIds = backendRegistry.GetBackendIds();
+ BOOST_TEST(backendIds.size() == expectedRegisteredbackendIds.size());
+ for (const BackendId& expectedRegisteredbackendId : expectedRegisteredbackendIds)
+ {
+ BOOST_TEST((backendIds.find(expectedRegisteredbackendId) != backendIds.end()));
+
+ auto dynamicBackendFactoryFunction = backendRegistry.GetFactory(expectedRegisteredbackendId);
+ BOOST_TEST((dynamicBackendFactoryFunction != nullptr));
+
+ IBackendInternalUniquePtr dynamicBackend = dynamicBackendFactoryFunction();
+ BOOST_TEST((dynamicBackend != nullptr));
+ BOOST_TEST((dynamicBackend->GetId() == expectedRegisteredbackendId));
+ }
+}
diff --git a/src/backends/backendsCommon/test/TestDynamicBackend.cpp b/src/backends/backendsCommon/test/TestDynamicBackend.cpp
index bdbc174e5b..7230702984 100644
--- a/src/backends/backendsCommon/test/TestDynamicBackend.cpp
+++ b/src/backends/backendsCommon/test/TestDynamicBackend.cpp
@@ -28,6 +28,21 @@ constexpr const char* TestDynamicBackendId()
// The test dynamic backend 3 is a different backend than the test dynamic backend 2
return "TestValid3";
+#elif defined(VALID_TEST_DYNAMIC_BACKEND_5)
+
+ // The test dynamic backend 5 is a different backend than the test dynamic backend 2
+ return "TestValid5";
+
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_10)
+
+ // Empty backend id
+ return "";
+
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_11)
+
+ // "Unknown" backend id, "Unknown" is a reserved id in ArmNN
+ return "Unknown";
+
#else
return "InvalidTestDynamicBackend";
diff --git a/src/backends/backendsCommon/test/TestDynamicBackend.hpp b/src/backends/backendsCommon/test/TestDynamicBackend.hpp
index 74ab91b20c..61a6eaf572 100644
--- a/src/backends/backendsCommon/test/TestDynamicBackend.hpp
+++ b/src/backends/backendsCommon/test/TestDynamicBackend.hpp
@@ -10,7 +10,8 @@
#if defined(VALID_TEST_DYNAMIC_BACKEND_1) || \
defined(VALID_TEST_DYNAMIC_BACKEND_2) || \
defined(VALID_TEST_DYNAMIC_BACKEND_3) || \
- defined(VALID_TEST_DYNAMIC_BACKEND_4)
+ defined(VALID_TEST_DYNAMIC_BACKEND_4) || \
+ defined(VALID_TEST_DYNAMIC_BACKEND_5)
// Correct dynamic backend interface
extern "C"
@@ -50,11 +51,13 @@ void* BackendFactory();
const char* GetBackendId();
void GetVersion(uint32_t* outMajor, uint32_t* outMinor);
-#elif defined(INVALID_TEST_DYNAMIC_BACKEND_5) || \
- defined(INVALID_TEST_DYNAMIC_BACKEND_6) || \
- defined(INVALID_TEST_DYNAMIC_BACKEND_7) || \
- defined(INVALID_TEST_DYNAMIC_BACKEND_8) || \
- defined(INVALID_TEST_DYNAMIC_BACKEND_9)
+#elif defined(INVALID_TEST_DYNAMIC_BACKEND_5) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_6) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_7) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_8) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_9) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_10) || \
+ defined(INVALID_TEST_DYNAMIC_BACKEND_11)
// The interface is correct, the corresponding invalid changes are in the TestDynamicBackend.cpp file
const char* GetBackendId();