From 111b5d94d7e854c21377f8d2c0b4234317a903f6 Mon Sep 17 00:00:00 2001 From: David Beck Date: Mon, 12 Nov 2018 14:59:37 +0000 Subject: IVGCVSW-2125 : Consolidate backend registries into one Change-Id: I56da4780f8f5fcef7ff01d232d5d61bf299364bf --- src/armnn/LayerSupport.cpp | 24 ++++- src/backends/backendsCommon/BackendRegistry.cpp | 69 ++++++++++++ src/backends/backendsCommon/BackendRegistry.hpp | 50 +++++++-- src/backends/backendsCommon/CMakeLists.txt | 3 - src/backends/backendsCommon/IBackendInternal.hpp | 3 + .../backendsCommon/LayerSupportRegistry.cpp | 17 --- .../backendsCommon/LayerSupportRegistry.hpp | 23 ---- src/backends/backendsCommon/RegistryCommon.hpp | 120 --------------------- src/backends/backendsCommon/WorkloadFactory.cpp | 22 +++- src/backends/backendsCommon/common.mk | 1 - .../backendsCommon/test/BackendRegistryTests.cpp | 2 +- src/backends/cl/ClBackend.cpp | 9 +- src/backends/cl/ClBackend.hpp | 1 + src/backends/cl/ClLayerSupport.cpp | 17 +-- src/backends/neon/NeonBackend.cpp | 9 +- src/backends/neon/NeonBackend.hpp | 1 + src/backends/neon/NeonLayerSupport.cpp | 17 +-- src/backends/reference/RefBackend.cpp | 10 +- src/backends/reference/RefBackend.hpp | 1 + src/backends/reference/RefLayerSupport.cpp | 17 +-- 20 files changed, 184 insertions(+), 232 deletions(-) delete mode 100644 src/backends/backendsCommon/LayerSupportRegistry.cpp delete mode 100644 src/backends/backendsCommon/LayerSupportRegistry.hpp delete mode 100644 src/backends/backendsCommon/RegistryCommon.hpp diff --git a/src/armnn/LayerSupport.cpp b/src/armnn/LayerSupport.cpp index 5d2d205534..78a184a7ce 100644 --- a/src/armnn/LayerSupport.cpp +++ b/src/armnn/LayerSupport.cpp @@ -4,8 +4,10 @@ // #include #include +#include -#include +#include +#include #include @@ -39,10 +41,22 @@ void CopyErrorMessage(char* truncatedString, const char* fullString, size_t maxL std::string reasonIfUnsupportedFull; \ bool isSupported; \ try { \ - auto factoryFunc = LayerSupportRegistryInstance().GetFactory(backendId); \ - auto layerSupportObject = factoryFunc(); \ - isSupported = layerSupportObject->func(__VA_ARGS__, Optional(reasonIfUnsupportedFull)); \ - CopyErrorMessage(reasonIfUnsupported, reasonIfUnsupportedFull.c_str(), reasonIfUnsupportedMaxLength); \ + auto const& backendRegistry = BackendRegistryInstance(); \ + if (!backendRegistry.IsBackendRegistered(backendId)) \ + { \ + std::stringstream ss; \ + ss << __func__ << " is not supported on " << backendId << " because this backend is not registered."; \ + reasonIfUnsupportedFull = ss.str(); \ + isSupported = false; \ + } \ + else \ + { \ + auto factoryFunc = backendRegistry.GetFactory(backendId); \ + auto backendObject = factoryFunc(); \ + auto layerSupportObject = backendObject->GetLayerSupport(); \ + isSupported = layerSupportObject->func(__VA_ARGS__, Optional(reasonIfUnsupportedFull)); \ + CopyErrorMessage(reasonIfUnsupported, reasonIfUnsupportedFull.c_str(), reasonIfUnsupportedMaxLength); \ + } \ } catch (InvalidArgumentException e) { \ /* re-throwing with more context information */ \ throw InvalidArgumentException(e, "Failed to check layer support", CHECK_LOCATION()); \ diff --git a/src/backends/backendsCommon/BackendRegistry.cpp b/src/backends/backendsCommon/BackendRegistry.cpp index e9361210f2..80ab01ce1b 100644 --- a/src/backends/backendsCommon/BackendRegistry.cpp +++ b/src/backends/backendsCommon/BackendRegistry.cpp @@ -4,6 +4,7 @@ // #include "BackendRegistry.hpp" +#include namespace armnn { @@ -14,4 +15,72 @@ BackendRegistry& BackendRegistryInstance() return instance; } +void BackendRegistry::Register(const BackendId& id, BackendRegistry::FactoryFunction factory) +{ + if (m_Factories.count(id) > 0) + { + throw InvalidArgumentException( + std::string(id) + " already registered as IBackend factory", + CHECK_LOCATION()); + } + + m_Factories[id] = factory; +} + +bool BackendRegistry::IsBackendRegistered(const BackendId& id) const +{ + return (m_Factories.find(id) != m_Factories.end()); +} + +BackendRegistry::FactoryFunction BackendRegistry::GetFactory(const BackendId& id) const +{ + auto it = m_Factories.find(id); + if (it == m_Factories.end()) + { + throw InvalidArgumentException( + std::string(id) + " has no IBackend factory registered", + CHECK_LOCATION()); + } + + return it->second; +} + +size_t BackendRegistry::Size() const +{ + return m_Factories.size(); +} + +BackendIdSet BackendRegistry::GetBackendIds() const +{ + BackendIdSet result; + for (const auto& it : m_Factories) + { + result.insert(it.first); + } + return result; +} + +std::string BackendRegistry::GetBackendIdsAsString() const +{ + static const std::string delimitator = ", "; + + std::stringstream output; + for (auto& backendId : GetBackendIds()) + { + if (output.tellp() != std::streampos(0)) + { + output << delimitator; + } + output << backendId; + } + + return output.str(); +} + +void BackendRegistry::Swap(BackendRegistry& instance, BackendRegistry::FactoryStorage& other) +{ + std::swap(instance.m_Factories, other); +} + + } // namespace armnn diff --git a/src/backends/backendsCommon/BackendRegistry.hpp b/src/backends/backendsCommon/BackendRegistry.hpp index 4b20cacbe0..2a52e24238 100644 --- a/src/backends/backendsCommon/BackendRegistry.hpp +++ b/src/backends/backendsCommon/BackendRegistry.hpp @@ -4,21 +4,57 @@ // #pragma once -#include "RegistryCommon.hpp" #include +#include + +#include +#include namespace armnn { + class IBackendInternal; using IBackendInternalUniquePtr = std::unique_ptr; -using BackendRegistry = RegistryCommon; - -BackendRegistry& BackendRegistryInstance(); -template <> -struct RegisteredTypeName +class BackendRegistry { - static const char * Name() { return "IBackend"; } +public: + using PointerType = IBackendInternalUniquePtr; + using FactoryFunction = std::function; + + void Register(const BackendId& id, FactoryFunction factory); + bool IsBackendRegistered(const BackendId& id) const; + FactoryFunction GetFactory(const BackendId& id) const; + size_t Size() const; + BackendIdSet GetBackendIds() const; + std::string GetBackendIdsAsString() const; + + BackendRegistry() {} + virtual ~BackendRegistry() {} + + struct StaticRegistryInitializer + { + StaticRegistryInitializer(BackendRegistry& instance, + const BackendId& id, + FactoryFunction factory) + { + instance.Register(id, factory); + } + }; + +protected: + using FactoryStorage = std::unordered_map; + + // For testing only + static void Swap(BackendRegistry& instance, FactoryStorage& other); + +private: + BackendRegistry(const BackendRegistry&) = delete; + BackendRegistry& operator=(const BackendRegistry&) = delete; + + FactoryStorage m_Factories; }; +BackendRegistry& BackendRegistryInstance(); + } // namespace armnn \ No newline at end of file diff --git a/src/backends/backendsCommon/CMakeLists.txt b/src/backends/backendsCommon/CMakeLists.txt index f4ab45f8b4..e6ac01c0ac 100644 --- a/src/backends/backendsCommon/CMakeLists.txt +++ b/src/backends/backendsCommon/CMakeLists.txt @@ -13,14 +13,11 @@ list(APPEND armnnBackendsCommon_sources IBackendContext.hpp ILayerSupport.cpp ITensorHandle.hpp - LayerSupportRegistry.cpp - LayerSupportRegistry.hpp MakeWorkloadHelper.hpp MemCopyWorkload.cpp MemCopyWorkload.hpp OutputHandler.cpp OutputHandler.hpp - RegistryCommon.hpp StringMapping.cpp StringMapping.hpp WorkloadDataCollector.hpp diff --git a/src/backends/backendsCommon/IBackendInternal.hpp b/src/backends/backendsCommon/IBackendInternal.hpp index 9c54b821e7..9d649fcfe2 100644 --- a/src/backends/backendsCommon/IBackendInternal.hpp +++ b/src/backends/backendsCommon/IBackendInternal.hpp @@ -13,6 +13,7 @@ namespace armnn class IWorkloadFactory; class IBackendContext; class Optimization; +class ILayerSupport; class IBackendInternal : public IBackend { @@ -30,10 +31,12 @@ public: using IBackendContextPtr = std::unique_ptr; using OptimizationPtr = std::unique_ptr; using Optimizations = std::vector; + using ILayerSupportSharedPtr = std::shared_ptr; virtual IWorkloadFactoryPtr CreateWorkloadFactory() const = 0; virtual IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const = 0; virtual Optimizations GetOptimizations() const = 0; + virtual ILayerSupportSharedPtr GetLayerSupport() const = 0; }; using IBackendInternalUniquePtr = std::unique_ptr; diff --git a/src/backends/backendsCommon/LayerSupportRegistry.cpp b/src/backends/backendsCommon/LayerSupportRegistry.cpp deleted file mode 100644 index 63b4da7337..0000000000 --- a/src/backends/backendsCommon/LayerSupportRegistry.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "LayerSupportRegistry.hpp" - -namespace armnn -{ - -LayerSupportRegistry& LayerSupportRegistryInstance() -{ - static LayerSupportRegistry instance; - return instance; -} - -} // namespace armnn diff --git a/src/backends/backendsCommon/LayerSupportRegistry.hpp b/src/backends/backendsCommon/LayerSupportRegistry.hpp deleted file mode 100644 index a5efad05ef..0000000000 --- a/src/backends/backendsCommon/LayerSupportRegistry.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include "RegistryCommon.hpp" -#include - -namespace armnn -{ - -using LayerSupportRegistry = RegistryCommon; - -LayerSupportRegistry& LayerSupportRegistryInstance(); - -template <> -struct RegisteredTypeName -{ - static const char * Name() { return "ILayerSupport"; } -}; - -} // namespace armnn diff --git a/src/backends/backendsCommon/RegistryCommon.hpp b/src/backends/backendsCommon/RegistryCommon.hpp deleted file mode 100644 index 03bd338090..0000000000 --- a/src/backends/backendsCommon/RegistryCommon.hpp +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// -#pragma once - -#include -#include - -#include -#include -#include -#include -#include - -namespace armnn -{ - -template -struct RegisteredTypeName -{ - static const char * Name() { return "UNKNOWN"; } -}; - -template -class RegistryCommon -{ -public: - using FactoryFunction = std::function; - - void Register(const BackendId& id, FactoryFunction factory) - { - if (m_Factories.count(id) > 0) - { - throw InvalidArgumentException( - std::string(id) + " already registered as " + RegisteredTypeName::Name() + " factory", - CHECK_LOCATION()); - } - - m_Factories[id] = factory; - } - - FactoryFunction GetFactory(const BackendId& id) const - { - auto it = m_Factories.find(id); - if (it == m_Factories.end()) - { - throw InvalidArgumentException( - std::string(id) + " has no " + RegisteredTypeName::Name() + " factory registered", - CHECK_LOCATION()); - } - - return it->second; - } - - size_t Size() const - { - return m_Factories.size(); - } - - BackendIdSet GetBackendIds() const - { - BackendIdSet result; - for (const auto& it : m_Factories) - { - result.insert(it.first); - } - return result; - } - - std::string GetBackendIdsAsString() const - { - static const std::string delimitator = ", "; - - std::stringstream output; - for (auto& backendId : GetBackendIds()) - { - if (output.tellp() != std::streampos(0)) - { - output << delimitator; - } - output << backendId; - } - - return output.str(); - } - - RegistryCommon() {} - virtual ~RegistryCommon() {} - -protected: - using FactoryStorage = std::unordered_map; - - // For testing only - static void Swap(RegistryCommon& instance, FactoryStorage& other) - { - std::swap(instance.m_Factories, other); - } - -private: - RegistryCommon(const RegistryCommon&) = delete; - RegistryCommon& operator=(const RegistryCommon&) = delete; - - FactoryStorage m_Factories; -}; - -template -struct StaticRegistryInitializer -{ - using FactoryFunction = typename RegistryType::FactoryFunction; - - StaticRegistryInitializer(RegistryType& instance, - const BackendId& id, - FactoryFunction factory) - { - instance.Register(id, factory); - } -}; - -} // namespace armnn diff --git a/src/backends/backendsCommon/WorkloadFactory.cpp b/src/backends/backendsCommon/WorkloadFactory.cpp index ec30f34880..bb63b336e9 100644 --- a/src/backends/backendsCommon/WorkloadFactory.cpp +++ b/src/backends/backendsCommon/WorkloadFactory.cpp @@ -10,14 +10,17 @@ #include #include +#include -#include +#include #include +#include #include #include #include +#include namespace armnn { @@ -66,9 +69,20 @@ bool IWorkloadFactory::IsLayerSupported(const BackendId& backendId, bool result; const Layer& layer = *(boost::polymorphic_downcast(&connectableLayer)); - auto const& layerSupportRegistry = LayerSupportRegistryInstance(); - auto layerSupportFactory = layerSupportRegistry.GetFactory(backendId); - auto layerSupportObject = layerSupportFactory(); + auto const& backendRegistry = BackendRegistryInstance(); + if (!backendRegistry.IsBackendRegistered(backendId)) + { + std::stringstream ss; + ss << connectableLayer.GetName() << " is not supported on " << backendId + << " because this backend is not registered."; + + outReasonIfUnsupported = ss.str(); + return false; + } + + auto backendFactory = backendRegistry.GetFactory(backendId); + auto backendObject = backendFactory(); + auto layerSupportObject = backendObject->GetLayerSupport(); switch(layer.GetType()) { diff --git a/src/backends/backendsCommon/common.mk b/src/backends/backendsCommon/common.mk index b1583b987e..8d29316599 100644 --- a/src/backends/backendsCommon/common.mk +++ b/src/backends/backendsCommon/common.mk @@ -12,7 +12,6 @@ COMMON_SOURCES := \ CpuTensorHandle.cpp \ ILayerSupport.cpp \ MemCopyWorkload.cpp \ - LayerSupportRegistry.cpp \ OutputHandler.cpp \ StringMapping.cpp \ WorkloadData.cpp \ diff --git a/src/backends/backendsCommon/test/BackendRegistryTests.cpp b/src/backends/backendsCommon/test/BackendRegistryTests.cpp index 26175e015f..283caafaf9 100644 --- a/src/backends/backendsCommon/test/BackendRegistryTests.cpp +++ b/src/backends/backendsCommon/test/BackendRegistryTests.cpp @@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(TestRegistryHelper) bool called = false; - StaticRegistryInitializer factoryHelper( + BackendRegistry::StaticRegistryInitializer factoryHelper( BackendRegistryInstance(), "HelloWorld", [&called]() diff --git a/src/backends/cl/ClBackend.cpp b/src/backends/cl/ClBackend.cpp index 8209a109a4..4ef8d90dfc 100644 --- a/src/backends/cl/ClBackend.cpp +++ b/src/backends/cl/ClBackend.cpp @@ -7,6 +7,7 @@ #include "ClBackendId.hpp" #include "ClWorkloadFactory.hpp" #include "ClBackendContext.hpp" +#include "ClLayerSupport.hpp" #include #include @@ -18,7 +19,7 @@ namespace armnn namespace { -static StaticRegistryInitializer g_RegisterHelper +static BackendRegistry::StaticRegistryInitializer g_RegisterHelper { BackendRegistryInstance(), ClBackend::GetIdStatic(), @@ -52,4 +53,10 @@ IBackendInternal::Optimizations ClBackend::GetOptimizations() const return Optimizations{}; } +IBackendInternal::ILayerSupportSharedPtr ClBackend::GetLayerSupport() const +{ + static ILayerSupportSharedPtr layerSupport{new ClLayerSupport}; + return layerSupport; +} + } // namespace armnn diff --git a/src/backends/cl/ClBackend.hpp b/src/backends/cl/ClBackend.hpp index ad84e8a159..7ee85980a3 100644 --- a/src/backends/cl/ClBackend.hpp +++ b/src/backends/cl/ClBackend.hpp @@ -21,6 +21,7 @@ public: IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory() const override; IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override; IBackendInternal::Optimizations GetOptimizations() const override; + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override; }; } // namespace armnn \ No newline at end of file diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp index f4e14c24d0..039f1c24f0 100644 --- a/src/backends/cl/ClLayerSupport.cpp +++ b/src/backends/cl/ClLayerSupport.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include @@ -44,21 +44,6 @@ namespace armnn namespace { -ILayerSupportSharedPtr GetLayerSupportPointer() -{ - static ILayerSupportSharedPtr instance{new ClLayerSupport}; - return instance; -} - -static StaticRegistryInitializer g_RegisterHelper{ - LayerSupportRegistryInstance(), - ClBackendId(), - []() - { - return GetLayerSupportPointer(); - } -}; - template bool IsMatchingSize2d(const TensorInfo& weightInfo) { diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp index 9e079f38ce..4d57eda877 100644 --- a/src/backends/neon/NeonBackend.cpp +++ b/src/backends/neon/NeonBackend.cpp @@ -6,6 +6,7 @@ #include "NeonBackend.hpp" #include "NeonBackendId.hpp" #include "NeonWorkloadFactory.hpp" +#include "NeonLayerSupport.hpp" #include #include @@ -19,7 +20,7 @@ namespace armnn namespace { -static StaticRegistryInitializer g_RegisterHelper +static BackendRegistry::StaticRegistryInitializer g_RegisterHelper { BackendRegistryInstance(), NeonBackend::GetIdStatic(), @@ -52,4 +53,10 @@ IBackendInternal::Optimizations NeonBackend::GetOptimizations() const return Optimizations{}; } +IBackendInternal::ILayerSupportSharedPtr NeonBackend::GetLayerSupport() const +{ + static ILayerSupportSharedPtr layerSupport{new NeonLayerSupport}; + return layerSupport; +} + } // namespace armnn \ No newline at end of file diff --git a/src/backends/neon/NeonBackend.hpp b/src/backends/neon/NeonBackend.hpp index e0017d92c8..d83710d22c 100644 --- a/src/backends/neon/NeonBackend.hpp +++ b/src/backends/neon/NeonBackend.hpp @@ -21,6 +21,7 @@ public: IWorkloadFactoryPtr CreateWorkloadFactory() const override; IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override; IBackendInternal::Optimizations GetOptimizations() const override; + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override; }; } // namespace armnn \ No newline at end of file diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp index a4a6b67c0b..165e0677b7 100644 --- a/src/backends/neon/NeonLayerSupport.cpp +++ b/src/backends/neon/NeonLayerSupport.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include @@ -40,21 +40,6 @@ namespace armnn namespace { -ILayerSupportSharedPtr GetLayerSupportPointer() -{ - static ILayerSupportSharedPtr instance{new NeonLayerSupport}; - return instance; -} - -static StaticRegistryInitializer g_RegisterHelper{ - LayerSupportRegistryInstance(), - NeonBackendId(), - []() - { - return GetLayerSupportPointer(); - } -}; - bool IsNeonBackendSupported(Optional reasonIfUnsupported) { #if ARMCOMPUTENEON_ENABLED diff --git a/src/backends/reference/RefBackend.cpp b/src/backends/reference/RefBackend.cpp index 2f5ec8032c..7c9240479b 100644 --- a/src/backends/reference/RefBackend.cpp +++ b/src/backends/reference/RefBackend.cpp @@ -6,9 +6,11 @@ #include "RefBackend.hpp" #include "RefBackendId.hpp" #include "RefWorkloadFactory.hpp" +#include "RefLayerSupport.hpp" #include #include + #include #include @@ -19,7 +21,7 @@ namespace armnn namespace { -static StaticRegistryInitializer g_RegisterHelper +static BackendRegistry::StaticRegistryInitializer g_RegisterHelper { BackendRegistryInstance(), RefBackend::GetIdStatic(), @@ -52,4 +54,10 @@ IBackendInternal::Optimizations RefBackend::GetOptimizations() const return Optimizations{}; } +IBackendInternal::ILayerSupportSharedPtr RefBackend::GetLayerSupport() const +{ + static ILayerSupportSharedPtr layerSupport{new RefLayerSupport}; + return layerSupport; +} + } // namespace armnn \ No newline at end of file diff --git a/src/backends/reference/RefBackend.hpp b/src/backends/reference/RefBackend.hpp index be71f356f3..12d56ffab4 100644 --- a/src/backends/reference/RefBackend.hpp +++ b/src/backends/reference/RefBackend.hpp @@ -21,6 +21,7 @@ public: IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory() const override; IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override; IBackendInternal::Optimizations GetOptimizations() const override; + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override; }; } // namespace armnn \ No newline at end of file diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp index b057370459..d6c1e66626 100644 --- a/src/backends/reference/RefLayerSupport.cpp +++ b/src/backends/reference/RefLayerSupport.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include @@ -22,21 +22,6 @@ namespace armnn namespace { -ILayerSupportSharedPtr GetLayerSupportPointer() -{ - static ILayerSupportSharedPtr instance{new RefLayerSupport}; - return instance; -} - -static StaticRegistryInitializer g_RegisterHelper{ - LayerSupportRegistryInstance(), - RefBackendId(), - []() - { - return GetLayerSupportPointer(); - } -}; - template bool IsSupportedForDataTypeRef(Optional reasonIfUnsupported, DataType dataType, -- cgit v1.2.1