From ac60d28414041774d7a4c8b6b5c4b0991712ef0f Mon Sep 17 00:00:00 2001 From: Matteo Martincigh Date: Thu, 25 Jul 2019 15:25:44 +0100 Subject: IVGCVSW-3543 Implement the backend versioning algorithm * Added version structure for backends, with comparisons operators * Added version to IBackendInternal * Added version utility function to DynamicBackendUtils class Signed-off-by: Matteo Martincigh Change-Id: I3697469675c27f79f7cfb296cfa69ec7e06375e5 --- .../backendsCommon/DynamicBackendUtils.cpp | 14 +++++ .../backendsCommon/DynamicBackendUtils.hpp | 8 +++ src/backends/backendsCommon/IBackendInternal.hpp | 41 ++++++++++++++- src/backends/backendsCommon/test/CMakeLists.txt | 2 + .../backendsCommon/test/DynamicBackendTests.cpp | 12 +++++ .../backendsCommon/test/DynamicBackendTests.hpp | 61 ++++++++++++++++++++++ 6 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/backends/backendsCommon/test/DynamicBackendTests.cpp create mode 100644 src/backends/backendsCommon/test/DynamicBackendTests.hpp diff --git a/src/backends/backendsCommon/DynamicBackendUtils.cpp b/src/backends/backendsCommon/DynamicBackendUtils.cpp index 9a47654477..0ab02d7c98 100644 --- a/src/backends/backendsCommon/DynamicBackendUtils.cpp +++ b/src/backends/backendsCommon/DynamicBackendUtils.cpp @@ -34,6 +34,20 @@ void DynamicBackendUtils::CloseHandle(const void* sharedObjectHandle) dlclose(const_cast(sharedObjectHandle)); } +bool DynamicBackendUtils::IsBackendCompatible(const BackendVersion &backendVersion) +{ + BackendVersion backendApiVersion = IBackendInternal::GetApiVersion(); + + return IsBackendCompatibleImpl(backendApiVersion, backendVersion); +} + +bool DynamicBackendUtils::IsBackendCompatibleImpl(const BackendVersion &backendApiVersion, + const BackendVersion &backendVersion) +{ + return backendVersion.m_Major == backendApiVersion.m_Major && + backendVersion.m_Minor <= backendApiVersion.m_Minor; +} + std::string DynamicBackendUtils::GetDlError() { const char* errorMessage = dlerror(); diff --git a/src/backends/backendsCommon/DynamicBackendUtils.hpp b/src/backends/backendsCommon/DynamicBackendUtils.hpp index 011a82373a..0a2d428fd3 100644 --- a/src/backends/backendsCommon/DynamicBackendUtils.hpp +++ b/src/backends/backendsCommon/DynamicBackendUtils.hpp @@ -5,6 +5,8 @@ #pragma once +#include "IBackendInternal.hpp" + #include #include @@ -24,6 +26,12 @@ public: template static EntryPointType GetEntryPoint(const void* sharedObjectHandle, const char* symbolName); + static bool IsBackendCompatible(const BackendVersion& backendVersion); + +protected: + /// Protected for testing purposes + static bool IsBackendCompatibleImpl(const BackendVersion& backendApiVersion, const BackendVersion& backendVersion); + private: static std::string GetDlError(); diff --git a/src/backends/backendsCommon/IBackendInternal.hpp b/src/backends/backendsCommon/IBackendInternal.hpp index a0d6569949..c548683e3e 100644 --- a/src/backends/backendsCommon/IBackendInternal.hpp +++ b/src/backends/backendsCommon/IBackendInternal.hpp @@ -25,6 +25,42 @@ class IWorkloadFactory; class IMemoryManager; class ILayerSupport; +struct BackendVersion +{ + uint32_t m_Major; + uint32_t m_Minor; + + BackendVersion() + : m_Major(0) + , m_Minor(0) + {} + BackendVersion(uint32_t major, uint32_t minor) + : m_Major(major) + , m_Minor(minor) + {} + + bool operator==(const BackendVersion& other) const + { + return this == &other || + (this->m_Major == other.m_Major && + this->m_Minor == other.m_Minor); + } + + bool operator<=(const BackendVersion& other) const + { + return this->m_Major < other.m_Major || + (this->m_Major == other.m_Major && + this->m_Minor <= other.m_Minor); + } +}; + +inline std::ostream& operator<<(std::ostream& os, const BackendVersion& backendVersion) +{ + os << "[" << backendVersion.m_Major << "." << backendVersion.m_Minor << "]"; + + return os; +} + class IBackendInternal : public IBackend { protected: @@ -79,7 +115,7 @@ public: virtual IMemoryManagerUniquePtr CreateMemoryManager() const { return IMemoryManagerUniquePtr(); - }; + } virtual IWorkloadFactoryPtr CreateWorkloadFactory( const IMemoryManagerSharedPtr& memoryManager = nullptr) const = 0; @@ -142,6 +178,9 @@ public: /// Either this method or CreateMemoryManager() and /// IWorkloadFactory::CreateTensor()/IWorkloadFactory::CreateSubtensor() methods must be implemented. virtual void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) {} + + /// Returns the version of the Backend API + static BackendVersion GetApiVersion() { return { 1, 0 }; } }; using IBackendInternalUniquePtr = std::unique_ptr; diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index 7c2d0ebfa8..3ddaaaf162 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -19,6 +19,8 @@ list(APPEND armnnBackendsCommonUnitTests_sources DequantizeEndToEndTestImpl.hpp DetectionPostProcessLayerTestImpl.hpp DetectionPostProcessTestImpl.hpp + DynamicBackendTests.cpp + DynamicBackendTests.hpp EndToEndTestImpl.hpp FullyConnectedTestImpl.hpp GatherTestImpl.hpp diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.cpp b/src/backends/backendsCommon/test/DynamicBackendTests.cpp new file mode 100644 index 0000000000..5104d0663d --- /dev/null +++ b/src/backends/backendsCommon/test/DynamicBackendTests.cpp @@ -0,0 +1,12 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "DynamicBackendTests.hpp" + +BOOST_AUTO_TEST_SUITE(DynamicBackendTests) + +ARMNN_SIMPLE_TEST_CASE(BackendVersioning, BackendVersioningTestImpl); + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp new file mode 100644 index 0000000000..3b0c95b00f --- /dev/null +++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp @@ -0,0 +1,61 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include + +#include + +#include + +void BackendVersioningTestImpl() +{ + class TestDynamicBackendUtils : public armnn::DynamicBackendUtils + { + public: + static bool IsBackendCompatibleTest(const armnn::BackendVersion& backendApiVersion, + const armnn::BackendVersion& backendVersion) + { + return IsBackendCompatibleImpl(backendApiVersion, backendVersion); + } + }; + + // The backend API version used for the tests + armnn::BackendVersion backendApiVersion{ 2, 4 }; + + // Same backend and backend API versions are compatible with the backend API + armnn::BackendVersion sameBackendVersion{ 2, 4 }; + BOOST_TEST(sameBackendVersion == backendApiVersion); + BOOST_TEST(sameBackendVersion <= backendApiVersion); + BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, sameBackendVersion) == true); + + // Backend versions that differ from the backend API version by major revision are not compatible + // with the backend API + armnn::BackendVersion laterMajorBackendVersion{ 3, 4 }; + BOOST_TEST(!(laterMajorBackendVersion == backendApiVersion)); + BOOST_TEST(!(laterMajorBackendVersion <= backendApiVersion)); + BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMajorBackendVersion) == false); + + armnn::BackendVersion earlierMajorBackendVersion{ 1, 4 }; + BOOST_TEST(!(earlierMajorBackendVersion == backendApiVersion)); + BOOST_TEST(earlierMajorBackendVersion <= backendApiVersion); + BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, + earlierMajorBackendVersion) == false); + + // Backend versions with the same major revision but later minor revision than + // the backend API version are not compatible with the backend API + armnn::BackendVersion laterMinorBackendVersion{ 2, 5 }; + BOOST_TEST(!(laterMinorBackendVersion == backendApiVersion)); + BOOST_TEST(!(laterMinorBackendVersion <= backendApiVersion)); + BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, laterMinorBackendVersion) == false); + + // Backend versions with the same major revision but earlier minor revision than + // the backend API version are compatible with the backend API + armnn::BackendVersion earlierMinorBackendVersion{ 2, 3 }; + BOOST_TEST(!(earlierMinorBackendVersion == backendApiVersion)); + BOOST_TEST(earlierMinorBackendVersion <= backendApiVersion); + BOOST_TEST(TestDynamicBackendUtils::IsBackendCompatibleTest(backendApiVersion, earlierMinorBackendVersion) == true); +} -- cgit v1.2.1