diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/armnn/Runtime.cpp | 27 | ||||
-rw-r--r-- | src/armnn/test/OptimizerTests.cpp | 346 | ||||
-rw-r--r-- | src/backends/backendsCommon/test/DynamicBackendTests.hpp | 2 | ||||
-rw-r--r-- | src/backends/cl/ClBackend.hpp | 17 |
4 files changed, 318 insertions, 74 deletions
diff --git a/src/armnn/Runtime.cpp b/src/armnn/Runtime.cpp index f16d186191..c2b748653d 100644 --- a/src/armnn/Runtime.cpp +++ b/src/armnn/Runtime.cpp @@ -6,6 +6,7 @@ #include <armnn/Version.hpp> #include <armnn/BackendRegistry.hpp> +#include <armnn/BackendHelper.hpp> #include <armnn/Logging.hpp> #include <armnn/utility/Timer.hpp> @@ -282,6 +283,32 @@ RuntimeImpl::RuntimeImpl(const IRuntime::CreationOptions& options) auto backend = factoryFun(); ARMNN_ASSERT(backend.get() != nullptr); + // If the runtime is created in protected mode only add backends that support this mode + if (options.m_ProtectedMode) + { + // check if backend supports ProtectedMode + using BackendCapability = BackendOptions::BackendOption; + BackendCapability protectedContentCapability {"ProtectedContentAllocation", true}; + if (!HasCapability(protectedContentCapability, id)) + { + // Protected Content Allocation is not supported by the backend + // backend should not be registered + ARMNN_LOG(warning) << "Backend " + << id + << " is not registered as does not support protected content allocation \n"; + continue; + } + std::string err; + if (!backend->UseCustomMemoryAllocator(err)) + { + ARMNN_LOG(error) << "The backend " + << id + << " reported an error when entering protected mode. Backend won't be used." + << " ErrorMsg: " << err; + continue; + } + } + auto context = backend->CreateBackendContext(options); // backends are allowed to return nullptrs if they diff --git a/src/armnn/test/OptimizerTests.cpp b/src/armnn/test/OptimizerTests.cpp index d4e2d499d5..19bd58193a 100644 --- a/src/armnn/test/OptimizerTests.cpp +++ b/src/armnn/test/OptimizerTests.cpp @@ -139,6 +139,153 @@ void CreateLSTMLayerHelper(Graph &graph, bool CifgEnabled) Connect(layer, output, lstmTensorInfo3, 3, 0); } + +class MockLayerSupport : public LayerSupportBase +{ +public: + bool IsInputSupported(const TensorInfo& /*input*/, + Optional<std::string&> /*reasonIfUnsupported = EmptyOptional()*/) const override + { + return true; + } + + bool IsOutputSupported(const TensorInfo& /*input*/, + Optional<std::string&> /*reasonIfUnsupported = EmptyOptional()*/) const override + { + return true; + } + + bool IsActivationSupported(const TensorInfo& /*input0*/, + const TensorInfo& /*output*/, + const ActivationDescriptor& /*descriptor*/, + Optional<std::string&> /*reasonIfUnsupported = EmptyOptional()*/) const override + { + return true; + } +}; + +template <typename NamePolicy> +class MockBackend : public IBackendInternal +{ +public: + MockBackend() : + m_BackendCapabilities(NamePolicy::GetIdStatic(), {{"NullCapability", false}}), + m_CustomAllocator(false) {}; + MockBackend(const BackendCapabilities& capabilities) : + m_BackendCapabilities(capabilities), + m_CustomAllocator(false) {}; + ~MockBackend() = default; + + static const BackendId& GetIdStatic() + { + return NamePolicy::GetIdStatic(); + } + const BackendId& GetId() const override + { + return GetIdStatic(); + } + + IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override + { + return nullptr; + }; + + IBackendInternal::IWorkloadFactoryPtr + CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr&) const override + { + return nullptr; + } + + IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override + { + return nullptr; + } + + IBackendInternal::Optimizations GetOptimizations() const override + { + return {}; + } + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override + { + return std::make_shared<MockLayerSupport>(); + } + + OptimizationViews OptimizeSubgraphView(const SubgraphView&) const override + { + return {}; + }; + + BackendCapabilities GetCapabilities() const override + { + return m_BackendCapabilities; + }; + + virtual bool UseCustomMemoryAllocator(armnn::Optional<std::string&> errMsg) override + { + IgnoreUnused(errMsg); + m_CustomAllocator = true; + return m_CustomAllocator; + } + + BackendCapabilities m_BackendCapabilities; + bool m_CustomAllocator; +}; + +template <typename NamePolicy> +class NoProtectedModeMockBackend : public IBackendInternal +{ +public: + NoProtectedModeMockBackend() : m_BackendCapabilities(NamePolicy::GetIdStatic(), {{"NullCapability", false}}) {}; + NoProtectedModeMockBackend(const BackendCapabilities& capabilities) : m_BackendCapabilities(capabilities) {}; + ~NoProtectedModeMockBackend() = default; + + static const BackendId& GetIdStatic() + { + return NamePolicy::GetIdStatic(); + } + const BackendId& GetId() const override + { + return GetIdStatic(); + } + + IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override + { + return nullptr; + }; + + IBackendInternal::IWorkloadFactoryPtr + CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr&) const override + { + return nullptr; + } + + IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override + { + return nullptr; + } + + IBackendInternal::Optimizations GetOptimizations() const override + { + return {}; + } + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override + { + return std::make_shared<MockLayerSupport>(); + } + + OptimizationViews OptimizeSubgraphView(const SubgraphView&) const override + { + return {}; + }; + + BackendCapabilities GetCapabilities() const override + { + return m_BackendCapabilities; + }; + + BackendCapabilities m_BackendCapabilities; +}; + } // namespace TEST_SUITE("Optimizer") @@ -543,77 +690,6 @@ TEST_CASE("DetectionPostProcessValidateTensorShapes") CHECK_NOTHROW(graph.InferTensorInfos()); } -class MockLayerSupport : public LayerSupportBase -{ -public: - bool IsInputSupported(const TensorInfo& /*input*/, - Optional<std::string&> /*reasonIfUnsupported = EmptyOptional()*/) const override - { - return true; - } - - bool IsOutputSupported(const TensorInfo& /*input*/, - Optional<std::string&> /*reasonIfUnsupported = EmptyOptional()*/) const override - { - return true; - } - - bool IsActivationSupported(const TensorInfo& /*input0*/, - const TensorInfo& /*output*/, - const ActivationDescriptor& /*descriptor*/, - Optional<std::string&> /*reasonIfUnsupported = EmptyOptional()*/) const override - { - return true; - } -}; - -template <typename NamePolicy> -class MockBackend : public IBackendInternal -{ -public: - MockBackend() = default; - ~MockBackend() = default; - - static const BackendId& GetIdStatic() - { - return NamePolicy::GetIdStatic(); - } - const BackendId& GetId() const override - { - return GetIdStatic(); - } - - IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager() const override - { - return nullptr; - }; - - IBackendInternal::IWorkloadFactoryPtr - CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr&) const override - { - return nullptr; - } - - IBackendInternal::IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const override - { - return nullptr; - } - - IBackendInternal::Optimizations GetOptimizations() const override - { - return {}; - } - IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override - { - return std::make_shared<MockLayerSupport>(); - } - - OptimizationViews OptimizeSubgraphView(const SubgraphView&) const override - { - return {}; - }; -}; - TEST_CASE("BackendCapabilityTest") { BackendId backendId = "MockBackend"; @@ -848,4 +924,132 @@ TEST_CASE("OptimizeForExclusiveConnectionsWithoutFuseTest") &IsLayerOfType<armnn::OutputLayer>, &IsLayerOfType<armnn::OutputLayer>)); } +} // Optimizer TestSuite + +TEST_SUITE("Runtime") +{ +// This test really belongs into RuntimeTests.cpp but it requires all sort of MockBackends which are +// already defined here +TEST_CASE("RuntimeProtectedModeOption") +{ + using namespace armnn; + + struct MockPolicy + { + static const BackendId& GetIdStatic() + { + static BackendId id = "MockBackend"; + return id; + } + }; + + struct ProtectedPolicy + { + static const BackendId& GetIdStatic() + { + static BackendId id = "MockBackendProtectedContent"; + return id; + } + }; + + struct SillyPolicy + { + static const BackendId& GetIdStatic() + { + static BackendId id = "SillyMockBackend"; + return id; + } + }; + + BackendCapabilities mockBackendCapabilities("MockBackend", + { + {"ProtectedContentAllocation", false} + }); + BackendCapabilities mockProtectedBackendCapabilities("MockBackendProtectedContent", + { + {"ProtectedContentAllocation", true} + }); + + auto& backendRegistry = BackendRegistryInstance(); + + // clean up from previous test runs + std::vector<BackendId> mockBackends = {"MockBackend", "MockBackendProtectedContent", "SillyMockBackend"}; + for (auto& backend : mockBackends) + { + backendRegistry.Deregister(backend); + } + + // Create a bunch of MockBackends with different capabilities + // 1. Doesn't support protected mode even though it knows about this capability + backendRegistry.Register("MockBackend", [mockBackendCapabilities]() + { + return std::make_unique<MockBackend<MockPolicy>>(mockBackendCapabilities); + }); + // 2. Supports protected mode and has it implemented correctly + backendRegistry.Register("MockBackendProtectedContent", [mockProtectedBackendCapabilities]() + { + return std::make_unique<MockBackend<ProtectedPolicy>>(mockProtectedBackendCapabilities); + }); + // 3. Claims to support protected mode but doesn't have the UseCustomMemoryAllocator function implemented + backendRegistry.Register("SillyMockBackend", [mockProtectedBackendCapabilities]() + { + return std::make_unique<NoProtectedModeMockBackend<SillyPolicy>>(mockProtectedBackendCapabilities); + }); + + // Creates a runtime that is not in protected mode + { + IRuntime::CreationOptions creationOptions; + creationOptions.m_ProtectedMode = false; + + IRuntimePtr run = IRuntime::Create(creationOptions); + + const armnn::BackendIdSet supportedDevices = run->GetDeviceSpec().GetSupportedBackends(); + // Both MockBackends that are registered should show up in the runtimes supported backends list + for (auto& backend : mockBackends) + { + CHECK(std::find(supportedDevices.cbegin(), supportedDevices.cend(), backend) != supportedDevices.cend()); + } + } + + // If the runtime is in protected mode only backends that support protected content should be added + { + IRuntime::CreationOptions creationOptions; + creationOptions.m_ProtectedMode = true; + + IRuntimePtr run = IRuntime::Create(creationOptions); + + const armnn::BackendIdSet supportedDevices = run->GetDeviceSpec().GetSupportedBackends(); + // Only the MockBackends that claims support for protected content should show up in the + // runtimes supported backends list + CHECK(std::find(supportedDevices.cbegin(), + supportedDevices.cend(), + "MockBackendProtectedContent") != supportedDevices.cend()); + CHECK(std::find(supportedDevices.cbegin(), + supportedDevices.cend(), + "MockBackend") == supportedDevices.cend()); + CHECK(std::find(supportedDevices.cbegin(), + supportedDevices.cend(), + "SillyMockBackend") == supportedDevices.cend()); + } + + // If the runtime is in protected mode only backends that support protected content should be added + { + IRuntime::CreationOptions creationOptions; + creationOptions.m_ProtectedMode = true; + + IRuntimePtr run = IRuntime::Create(creationOptions); + + const armnn::BackendIdSet supportedDevices = run->GetDeviceSpec().GetSupportedBackends(); + // Only the MockBackend that claims support for protected content should show up in the + // runtimes supported backends list + CHECK(std::find(supportedDevices.cbegin(), + supportedDevices.cend(), + "MockBackendProtectedContent") != supportedDevices.cend()); + + CHECK(std::find(supportedDevices.cbegin(), + supportedDevices.cend(), + "MockBackend") == supportedDevices.cend()); + } + +} } diff --git a/src/backends/backendsCommon/test/DynamicBackendTests.hpp b/src/backends/backendsCommon/test/DynamicBackendTests.hpp index cfcdf8e59c..f49c36e5b1 100644 --- a/src/backends/backendsCommon/test/DynamicBackendTests.hpp +++ b/src/backends/backendsCommon/test/DynamicBackendTests.hpp @@ -560,7 +560,7 @@ void CreateDynamicBackendObjectInvalidInterface6TestImpl() BackendVersion dynamicBackendVersion; CHECK_NOTHROW(dynamicBackendVersion = dynamicBackend->GetBackendVersion()); - CHECK((dynamicBackendVersion == BackendVersion({ 1, 0 }))); + CHECK((dynamicBackendVersion >= BackendVersion({ 1, 0 }))); IBackendInternalUniquePtr dynamicBackendInstance1; CHECK_THROWS_AS(dynamicBackendInstance1 = dynamicBackend->GetBackend(), RuntimeException); diff --git a/src/backends/cl/ClBackend.hpp b/src/backends/cl/ClBackend.hpp index db03cfeff0..c742c0b204 100644 --- a/src/backends/cl/ClBackend.hpp +++ b/src/backends/cl/ClBackend.hpp @@ -13,13 +13,14 @@ namespace armnn const BackendCapabilities gpuAccCapabilities("GpuAcc", { {"NonConstWeights", false}, - {"AsyncExecution", false} + {"AsyncExecution", false}, + {"ProtectedContentAllocation", true} }); class ClBackend : public IBackendInternal { public: - ClBackend() = default; + ClBackend() : m_EnableCustomAllocator(false) {}; ~ClBackend() = default; static const BackendId& GetIdStatic(); @@ -70,6 +71,18 @@ public: { return gpuAccCapabilities; }; + + virtual bool UseCustomMemoryAllocator(armnn::Optional<std::string&> errMsg) override + { + IgnoreUnused(errMsg); + + // Set flag to signal the backend to use a custom memory allocator + m_EnableCustomAllocator = true; + + return m_EnableCustomAllocator; + } + + bool m_EnableCustomAllocator; }; } // namespace armnn |