aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Martincigh <matteo.martincigh@arm.com>2019-08-08 13:46:32 +0100
committerMatteo Martincigh <matteo.martincigh@arm.com>2019-08-12 15:43:42 +0100
commit4e73b429ddfebef9beb64872d3e54a14bceccb29 (patch)
tree4df1460ac6fa836af5202ece84184bab136fb94d
parent1fa19197a5673c57058efe19d94db223a93bc206 (diff)
downloadarmnn-4e73b429ddfebef9beb64872d3e54a14bceccb29.tar.gz
IVGCVSW-3546 Create a reference dynamic backend to use for testing and as
an example in the docs * Wrapped the reference backend into a dynamic backend * Moved the static registration code to a separate file, so that it is possible to create the reference dynamic backend that does not register statically into armnn * Added unit test Change-Id: I1074d21b020820f9ac8c7178388be773b447555a Signed-off-by: Matteo Martincigh <matteo.martincigh@arm.com>
-rw-r--r--src/backends/backends.cmake8
-rw-r--r--src/backends/backendsCommon/BackendRegistry.cpp2
-rw-r--r--src/backends/backendsCommon/test/DynamicBackendTests.cpp2
-rw-r--r--src/backends/backendsCommon/test/DynamicBackendTests.hpp114
-rw-r--r--src/backends/dynamic/reference/CMakeLists.txt28
-rw-r--r--src/backends/dynamic/reference/RefDynamicBackend.cpp33
-rw-r--r--src/backends/dynamic/reference/RefDynamicBackend.hpp15
-rw-r--r--src/backends/reference/CMakeLists.txt1
-rw-r--r--src/backends/reference/RefBackend.cpp15
-rw-r--r--src/backends/reference/RefRegistryInitializer.cpp25
-rw-r--r--src/backends/reference/backend.mk1
11 files changed, 226 insertions, 18 deletions
diff --git a/src/backends/backends.cmake b/src/backends/backends.cmake
index 438fda3664..473de48030 100644
--- a/src/backends/backends.cmake
+++ b/src/backends/backends.cmake
@@ -19,3 +19,11 @@ foreach(includeFile ${backendIncludes})
message("Including backend into the build: ${includeFile}")
include(${includeFile})
endforeach()
+
+# parse dynamic backend sub-directories
+file(GLOB dynamicBackendDirs ${PROJECT_SOURCE_DIR}/src/backends/dynamic/*)
+foreach(dynamicBackendDir ${dynamicBackendDirs})
+ if (EXISTS ${dynamicBackendDir} AND IS_DIRECTORY ${dynamicBackendDir})
+ add_subdirectory(${dynamicBackendDir})
+ endif()
+endforeach()
diff --git a/src/backends/backendsCommon/BackendRegistry.cpp b/src/backends/backendsCommon/BackendRegistry.cpp
index 80ab01ce1b..7078304599 100644
--- a/src/backends/backendsCommon/BackendRegistry.cpp
+++ b/src/backends/backendsCommon/BackendRegistry.cpp
@@ -17,7 +17,7 @@ BackendRegistry& BackendRegistryInstance()
void BackendRegistry::Register(const BackendId& id, BackendRegistry::FactoryFunction factory)
{
- if (m_Factories.count(id) > 0)
+ if (m_Factories.find(id) != m_Factories.end())
{
throw InvalidArgumentException(
std::string(id) + " already registered as IBackend factory",
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
index f13c961eaf..e42a08adc7 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.cpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp
@@ -61,4 +61,6 @@ ARMNN_SIMPLE_TEST_CASE(RuntimeDuplicateDynamicBackends, RuntimeDuplicateDynamicB
ARMNN_SIMPLE_TEST_CASE(RuntimeInvalidDynamicBackends, RuntimeInvalidDynamicBackendsTestImpl);
ARMNN_SIMPLE_TEST_CASE(RuntimeInvalidOverridePath, RuntimeInvalidOverridePathTestImpl);
+ARMNN_SIMPLE_TEST_CASE(CreateReferenceDynamicBackend, CreateReferenceDynamicBackendTestImpl);
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
index 3a44f506d6..74ef6f1ba7 100644
--- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp
+++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp
@@ -7,6 +7,12 @@
#include <backendsCommon/DynamicBackend.hpp>
#include <backendsCommon/DynamicBackendUtils.hpp>
+#include <backendsCommon/BackendRegistry.hpp>
+#include <backendsCommon/CpuTensorHandle.hpp>
+
+#include <armnn/ILayerSupport.hpp>
+
+#include <reference/workloads/RefConvolution2dWorkload.hpp>
#include <Runtime.hpp>
@@ -54,6 +60,10 @@ static std::string g_TestDynamicBackendsSubDir7 = "backendsTestPath7/";
static std::string g_TestDynamicBackendsSubDir8 = "backendsTestPath8/";
static std::string g_TestDynamicBackendsSubDir9 = "backendsTestPath9/";
+static std::string g_DynamicBackendsBaseDir = "src/backends/dynamic";
+static std::string g_ReferenceDynamicBackendSubDir = "reference/";
+static std::string g_ReferenceBackendFileName = "Arm_CpuRef_backend.so";
+
// DynamicBackendUtils wrapper class used for testing (allows to directly invoke the protected methods)
class TestDynamicBackendUtils : public armnn::DynamicBackendUtils
{
@@ -94,17 +104,27 @@ private:
FactoryStorage m_TempStorage;
};
-std::string GetTestDirectoryBasePath()
+std::string GetBasePath(const std::string& basePath)
{
using namespace boost::filesystem;
path programLocation = boost::dll::program_location().parent_path();
- path sharedObjectPath = programLocation.append(g_TestBaseDir);
+ path sharedObjectPath = programLocation.append(basePath);
BOOST_CHECK(exists(sharedObjectPath));
return sharedObjectPath.string();
}
+std::string GetTestDirectoryBasePath()
+{
+ return GetBasePath(g_TestBaseDir);
+}
+
+std::string GetDynamicBackendsBasePath()
+{
+ return GetBasePath(g_DynamicBackendsBaseDir);
+}
+
std::string GetTestSubDirectory(const std::string& subdir)
{
using namespace boost::filesystem;
@@ -117,6 +137,17 @@ std::string GetTestSubDirectory(const std::string& subdir)
return testDynamicBackendsSubDir.string();
}
+std::string GetTestSubDirectory(const std::string& basePath, const std::string& subdir)
+{
+ using namespace boost::filesystem;
+
+ path testDynamicBackendsBasePath(basePath);
+ path testDynamicBackendsSubDir = testDynamicBackendsBasePath.append(subdir);
+ // Do not check that the sub-directory exists because for testing reasons we may use non-existing paths
+
+ return testDynamicBackendsSubDir.string();
+}
+
std::string GetTestFilePath(const std::string& directory, const std::string& fileName)
{
using namespace boost::filesystem;
@@ -1268,3 +1299,82 @@ void RuntimeInvalidOverridePathTestImpl()
const BackendRegistry& backendRegistry = BackendRegistryInstance();
BOOST_TEST(backendRegistry.Size() == 0);
}
+
+void CreateReferenceDynamicBackendTestImpl()
+{
+ using namespace armnn;
+ using namespace boost::filesystem;
+
+ // Swapping the backend registry storage for testing
+ TestBackendRegistry testBackendRegistry;
+
+ // This directory contains the reference dynamic backend
+ std::string dynamicBackendsBaseDir = GetDynamicBackendsBasePath();
+ std::string referenceDynamicBackendSubDir = GetTestSubDirectory(dynamicBackendsBaseDir,
+ g_ReferenceDynamicBackendSubDir);
+ BOOST_CHECK(exists(referenceDynamicBackendSubDir));
+
+ // Check that the reference dynamic backend file exists
+ std::string referenceBackendFilePath = GetTestFilePath(referenceDynamicBackendSubDir,
+ g_ReferenceBackendFileName);
+ BOOST_CHECK(exists(referenceBackendFilePath));
+
+ // Using the path override in CreationOptions to load the reference dynamic backend
+ IRuntime::CreationOptions creationOptions;
+ creationOptions.m_DynamicBackendsPath = referenceDynamicBackendSubDir;
+ IRuntimePtr runtime = IRuntime::Create(creationOptions);
+
+ const BackendRegistry& backendRegistry = BackendRegistryInstance();
+ BOOST_TEST(backendRegistry.Size() == 1);
+
+ BackendIdSet backendIds = backendRegistry.GetBackendIds();
+ BOOST_TEST((backendIds.find("CpuRef") != backendIds.end()));
+
+ // Get the factory function
+ auto referenceDynamicBackendFactoryFunction = backendRegistry.GetFactory("CpuRef");
+ BOOST_TEST((referenceDynamicBackendFactoryFunction != nullptr));
+
+ // Use the factory function to create an instance of the reference backend
+ IBackendInternalUniquePtr referenceDynamicBackend = referenceDynamicBackendFactoryFunction();
+ BOOST_TEST((referenceDynamicBackend != nullptr));
+ BOOST_TEST((referenceDynamicBackend->GetId() == "CpuRef"));
+
+ // Test the backend instance by querying the layer support
+ IBackendInternal::ILayerSupportSharedPtr referenceLayerSupport = referenceDynamicBackend->GetLayerSupport();
+ BOOST_TEST((referenceLayerSupport != nullptr));
+
+ TensorShape inputShape { 1, 16, 16, 16 };
+ TensorShape outputShape{ 1, 16, 16, 16 };
+ TensorShape weightShape{ 16, 1, 1, 16 };
+ TensorInfo inputInfo (inputShape, DataType::Float32);
+ TensorInfo outputInfo(outputShape, DataType::Float32);
+ TensorInfo weightInfo(weightShape, DataType::Float32);
+ Convolution2dDescriptor convolution2dDescriptor;
+ bool referenceConvolution2dSupported =
+ referenceLayerSupport->IsConvolution2dSupported(inputInfo,
+ outputInfo,
+ convolution2dDescriptor,
+ weightInfo,
+ EmptyOptional());
+ BOOST_TEST(referenceConvolution2dSupported);
+
+ // Test the backend instance by creating a workload
+ IBackendInternal::IWorkloadFactoryPtr referenceWorkloadFactory = referenceDynamicBackend->CreateWorkloadFactory();
+ BOOST_TEST((referenceWorkloadFactory != nullptr));
+
+ // Create dummy settings for the workload
+ Convolution2dQueueDescriptor convolution2dQueueDescriptor;
+ WorkloadInfo workloadInfo
+ {
+ { inputInfo },
+ { outputInfo }
+ };
+ convolution2dQueueDescriptor.m_Inputs.push_back(nullptr);
+ auto weights = std::make_unique<ScopedCpuTensorHandle>(weightInfo);
+ convolution2dQueueDescriptor.m_Weight = weights.get();
+
+ // Create a convolution workload with the dummy settings
+ auto workload = referenceWorkloadFactory->CreateConvolution2d(convolution2dQueueDescriptor, workloadInfo);
+ BOOST_TEST((workload != nullptr));
+ BOOST_TEST(workload.get() == boost::polymorphic_downcast<RefConvolution2dWorkload*>(workload.get()));
+}
diff --git a/src/backends/dynamic/reference/CMakeLists.txt b/src/backends/dynamic/reference/CMakeLists.txt
new file mode 100644
index 0000000000..e9a94af2fc
--- /dev/null
+++ b/src/backends/dynamic/reference/CMakeLists.txt
@@ -0,0 +1,28 @@
+#
+# Copyright © 2017 Arm Ltd. All rights reserved.
+# SPDX-License-Identifier: MIT
+#
+
+# 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)
+set(RefBackendFiles ${RefBackendBaseFiles})
+
+# 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}/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)
+set_target_properties(Arm_CpuRef_backend PROPERTIES PREFIX "")
+target_link_libraries(Arm_CpuRef_backend armnn)
diff --git a/src/backends/dynamic/reference/RefDynamicBackend.cpp b/src/backends/dynamic/reference/RefDynamicBackend.cpp
new file mode 100644
index 0000000000..592043268b
--- /dev/null
+++ b/src/backends/dynamic/reference/RefDynamicBackend.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright © 2017 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/backends/dynamic/reference/RefDynamicBackend.hpp b/src/backends/dynamic/reference/RefDynamicBackend.hpp
new file mode 100644
index 0000000000..b058cd206c
--- /dev/null
+++ b/src/backends/dynamic/reference/RefDynamicBackend.hpp
@@ -0,0 +1,15 @@
+//
+// Copyright © 2017 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();
+}
diff --git a/src/backends/reference/CMakeLists.txt b/src/backends/reference/CMakeLists.txt
index 281e91628f..963e64379d 100644
--- a/src/backends/reference/CMakeLists.txt
+++ b/src/backends/reference/CMakeLists.txt
@@ -13,6 +13,7 @@ list(APPEND armnnRefBackend_sources
RefLayerSupport.hpp
RefMemoryManager.hpp
RefMemoryManager.cpp
+ RefRegistryInitializer.cpp
RefWorkloadFactory.cpp
RefWorkloadFactory.hpp
)
diff --git a/src/backends/reference/RefBackend.cpp b/src/backends/reference/RefBackend.cpp
index 3680831fb3..41438b0151 100644
--- a/src/backends/reference/RefBackend.cpp
+++ b/src/backends/reference/RefBackend.cpp
@@ -20,21 +20,6 @@
namespace armnn
{
-namespace
-{
-
-static BackendRegistry::StaticRegistryInitializer g_RegisterHelper
-{
- BackendRegistryInstance(),
- RefBackend::GetIdStatic(),
- []()
- {
- return IBackendInternalUniquePtr(new RefBackend);
- }
-};
-
-}
-
const BackendId& RefBackend::GetIdStatic()
{
static const BackendId s_Id{RefBackendId()};
diff --git a/src/backends/reference/RefRegistryInitializer.cpp b/src/backends/reference/RefRegistryInitializer.cpp
new file mode 100644
index 0000000000..427c7f01ab
--- /dev/null
+++ b/src/backends/reference/RefRegistryInitializer.cpp
@@ -0,0 +1,25 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "RefBackend.hpp"
+
+#include <backendsCommon/BackendRegistry.hpp>
+
+namespace
+{
+
+using namespace armnn;
+
+static BackendRegistry::StaticRegistryInitializer g_RegisterHelper
+{
+ BackendRegistryInstance(),
+ RefBackend::GetIdStatic(),
+ []()
+ {
+ return IBackendInternalUniquePtr(new RefBackend);
+ }
+};
+
+} // Anonymous namespace
diff --git a/src/backends/reference/backend.mk b/src/backends/reference/backend.mk
index 6e1360a1db..b212995ad1 100644
--- a/src/backends/reference/backend.mk
+++ b/src/backends/reference/backend.mk
@@ -13,6 +13,7 @@ BACKEND_SOURCES := \
RefMemoryManager.cpp \
RefTensorHandle.cpp \
RefWorkloadFactory.cpp \
+ RefRegistryInitializer.cpp \
workloads/Activation.cpp \
workloads/BatchNormImpl.cpp \
workloads/BatchToSpaceNd.cpp \