diff options
Diffstat (limited to 'src/backends/neon')
-rw-r--r-- | src/backends/neon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/backends/neon/NeonBackend.cpp | 21 | ||||
-rw-r--r-- | src/backends/neon/NeonBackend.hpp | 4 | ||||
-rw-r--r-- | src/backends/neon/NeonBackendModelContext.cpp | 45 | ||||
-rw-r--r-- | src/backends/neon/NeonBackendModelContext.hpp | 23 | ||||
-rw-r--r-- | src/backends/neon/NeonLayerSupport.cpp | 30 | ||||
-rw-r--r-- | src/backends/neon/NeonLayerSupport.hpp | 10 | ||||
-rw-r--r-- | src/backends/neon/backend.mk | 1 | ||||
-rw-r--r-- | src/backends/neon/test/NeonOptimizedNetworkTests.cpp | 30 | ||||
-rw-r--r-- | src/backends/neon/workloads/NeonConvolution2dWorkload.cpp | 13 | ||||
-rw-r--r-- | src/backends/neon/workloads/NeonConvolution2dWorkload.hpp | 9 |
11 files changed, 177 insertions, 11 deletions
diff --git a/src/backends/neon/CMakeLists.txt b/src/backends/neon/CMakeLists.txt index 327276c5fc..4654de5cab 100644 --- a/src/backends/neon/CMakeLists.txt +++ b/src/backends/neon/CMakeLists.txt @@ -8,6 +8,8 @@ if(ARMCOMPUTENEON) NeonBackend.cpp NeonBackend.hpp NeonBackendId.hpp + NeonBackendModelContext.hpp + NeonBackendModelContext.cpp NeonInterceptorScheduler.hpp NeonInterceptorScheduler.cpp NeonLayerSupport.cpp diff --git a/src/backends/neon/NeonBackend.cpp b/src/backends/neon/NeonBackend.cpp index 01cc6d8119..31e08ceaf5 100644 --- a/src/backends/neon/NeonBackend.cpp +++ b/src/backends/neon/NeonBackend.cpp @@ -5,6 +5,7 @@ #include "NeonBackend.hpp" #include "NeonBackendId.hpp" +#include "NeonBackendModelContext.hpp" #include "NeonWorkloadFactory.hpp" #include "NeonLayerSupport.hpp" #include "NeonTensorHandleFactory.hpp" @@ -75,9 +76,27 @@ IBackendInternal::Optimizations NeonBackend::GetOptimizations() const return Optimizations{}; } +IBackendInternal::IBackendSpecificModelContextPtr NeonBackend::CreateBackendSpecificModelContext( + const ModelOptions& modelOptions) const +{ + return IBackendSpecificModelContextPtr{new NeonBackendModelContext{modelOptions}}; +} + IBackendInternal::ILayerSupportSharedPtr NeonBackend::GetLayerSupport() const { - static ILayerSupportSharedPtr layerSupport{new NeonLayerSupport}; + static ILayerSupportSharedPtr layerSupport + { + new NeonLayerSupport(IBackendInternal::IBackendSpecificModelContextPtr{}) + }; + return layerSupport; +} + +IBackendInternal::ILayerSupportSharedPtr NeonBackend::GetLayerSupport(const ModelOptions& modelOptions) const +{ + static ILayerSupportSharedPtr layerSupport + { + new NeonLayerSupport(CreateBackendSpecificModelContext(modelOptions)) + }; return layerSupport; } diff --git a/src/backends/neon/NeonBackend.hpp b/src/backends/neon/NeonBackend.hpp index ad4ac8dde2..6458eccb6b 100644 --- a/src/backends/neon/NeonBackend.hpp +++ b/src/backends/neon/NeonBackend.hpp @@ -31,12 +31,16 @@ public: const IRuntime::CreationOptions&, IBackendProfilingPtr& backendProfiling) override; IBackendInternal::Optimizations GetOptimizations() const override; IBackendInternal::ILayerSupportSharedPtr GetLayerSupport() const override; + IBackendInternal::ILayerSupportSharedPtr GetLayerSupport(const ModelOptions& modelOptions) const override; OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const override; std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const override; void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry) override; + + IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext( + const ModelOptions& modelOptions) const override; }; } // namespace armnn diff --git a/src/backends/neon/NeonBackendModelContext.cpp b/src/backends/neon/NeonBackendModelContext.cpp new file mode 100644 index 0000000000..2be71e5ded --- /dev/null +++ b/src/backends/neon/NeonBackendModelContext.cpp @@ -0,0 +1,45 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "NeonBackendModelContext.hpp" + +namespace +{ + +bool ParseBool(const armnn::BackendOptions::Var& value, bool defaultValue) +{ + if (value.IsBool()) + { + return value.AsBool(); + } + return defaultValue; +} + +} // namespace anonymous + +namespace armnn +{ + +NeonBackendModelContext::NeonBackendModelContext(const ModelOptions& modelOptions) + : m_IsFastMathEnabled(false) +{ + if (!modelOptions.empty()) + { + ParseOptions(modelOptions, "CpuAcc", [&](std::string name, const BackendOptions::Var& value) + { + if (name == "FastMathEnabled") + { + m_IsFastMathEnabled |= ParseBool(value, false); + } + }); + } +} + +bool NeonBackendModelContext::IsFastMathEnabled() const +{ + return m_IsFastMathEnabled; +} + +} // namespace armnn
\ No newline at end of file diff --git a/src/backends/neon/NeonBackendModelContext.hpp b/src/backends/neon/NeonBackendModelContext.hpp new file mode 100644 index 0000000000..938d8af1cd --- /dev/null +++ b/src/backends/neon/NeonBackendModelContext.hpp @@ -0,0 +1,23 @@ +// +// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include <armnn/backends/IBackendContext.hpp> + +namespace armnn +{ + +class NeonBackendModelContext : public IBackendModelContext +{ +public: + NeonBackendModelContext(const ModelOptions& modelOptions); + + bool IsFastMathEnabled() const; + +private: + bool m_IsFastMathEnabled; +}; + +} // namespace armnn
\ No newline at end of file diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp index 9dc8a01778..853a518b45 100644 --- a/src/backends/neon/NeonLayerSupport.cpp +++ b/src/backends/neon/NeonLayerSupport.cpp @@ -5,6 +5,7 @@ #include "NeonLayerSupport.hpp" #include "NeonBackendId.hpp" +#include "NeonBackendModelContext.hpp" #include <armnn/Descriptors.hpp> #include <armnn/Exceptions.hpp> @@ -15,6 +16,7 @@ #include <InternalTypes.hpp> #include <LayerSupportCommon.hpp> #include <armnn/utility/IgnoreUnused.hpp> +#include <armnn/utility/PolymorphicDowncast.hpp> #if defined(ARMCOMPUTENEON_ENABLED) #include <aclCommon/ArmComputeUtils.hpp> @@ -125,6 +127,16 @@ inline bool IsWorkloadSupported(FuncType& func, Optional<std::string&> reasonIfU #endif } // anonymous namespace +NeonLayerSupport::NeonLayerSupport(const IBackendInternal::IBackendSpecificModelContextPtr& modelContextPtr) + : m_ModelContextPtr(modelContextPtr) +{ +} + +NeonLayerSupport::NeonLayerSupport() + : m_ModelContextPtr(nullptr) +{ +} + bool NeonLayerSupport::IsAbsSupported(const TensorInfo& input, const TensorInfo& output, Optional<std::string&> reasonIfUnsupported) const @@ -311,13 +323,29 @@ bool NeonLayerSupport::IsConvolution2dSupported(const TensorInfo& input, const Optional<TensorInfo>& biases, Optional<std::string&> reasonIfUnsupported) const { + bool isFastMathEnabled = false; +#if defined(ARMCOMPUTENEON_ENABLED) + if (m_ModelContextPtr) + { + if (m_ModelContextPtr.get() != nullptr) + { + auto modelOptions = armnn::PolymorphicDowncast<NeonBackendModelContext*>(m_ModelContextPtr.get()); + if (modelOptions) + { + isFastMathEnabled = modelOptions->IsFastMathEnabled(); + } + } + } +#endif + FORWARD_WORKLOAD_VALIDATE_FUNC(NeonConvolution2dWorkloadValidate, reasonIfUnsupported, input, output, descriptor, weights, - biases); + biases, + isFastMathEnabled); } bool NeonLayerSupport::IsDepthToSpaceSupported(const TensorInfo& input, diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp index bdc905d17e..d477dcdd7c 100644 --- a/src/backends/neon/NeonLayerSupport.hpp +++ b/src/backends/neon/NeonLayerSupport.hpp @@ -4,6 +4,8 @@ // #pragma once +#include <armnn/backends/IBackendInternal.hpp> + #include <backendsCommon/LayerSupportBase.hpp> namespace armnn @@ -12,6 +14,11 @@ namespace armnn class NeonLayerSupport : public LayerSupportBase { public: + explicit NeonLayerSupport(const IBackendInternal::IBackendSpecificModelContextPtr& modelContextPtr); + NeonLayerSupport(); + + ~NeonLayerSupport() {} + ARMNN_DEPRECATED_MSG("Use IsElementwiseUnarySupported instead") bool IsAbsSupported(const TensorInfo& input, const TensorInfo& output, @@ -327,6 +334,9 @@ public: const TransposeDescriptor& descriptor, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; +private: + const IBackendInternal::IBackendSpecificModelContextPtr m_ModelContextPtr; + }; // class NeonLayerSupport } // namespace armnn diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk index aeee9154ad..9bd08a1033 100644 --- a/src/backends/neon/backend.mk +++ b/src/backends/neon/backend.mk @@ -15,6 +15,7 @@ ifeq ($(ARMNN_COMPUTE_NEON_ENABLED),1) BACKEND_SOURCES := \ NeonBackend.cpp \ + NeonBackendModelContext.cpp \ NeonInterceptorScheduler.cpp \ NeonLayerSupport.cpp \ NeonRegistryInitializer.cpp \ diff --git a/src/backends/neon/test/NeonOptimizedNetworkTests.cpp b/src/backends/neon/test/NeonOptimizedNetworkTests.cpp index d552c17509..4c27aca6c3 100644 --- a/src/backends/neon/test/NeonOptimizedNetworkTests.cpp +++ b/src/backends/neon/test/NeonOptimizedNetworkTests.cpp @@ -70,4 +70,34 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateDeviceNonSupportLayerNoFallback) BOOST_CHECK(!optNet); } +BOOST_AUTO_TEST_CASE(FastMathEnabledTestOnCpuAcc) +{ + armnn::INetworkPtr net(armnn::INetwork::Create()); + + armnn::IConnectableLayer* input = net->AddInputLayer(0); + armnn::IConnectableLayer* output = net->AddOutputLayer(0); + + input->GetOutputSlot(0).Connect(output->GetInputSlot(0)); + input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32)); + + armnn::IRuntime::CreationOptions options; + armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); + + std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc}; + armnn::OptimizerOptions optimizerOptions; + armnn::BackendOptions modelOptions("CpuAcc", {{"FastMathEnabled", true}}); + optimizerOptions.m_ModelOptions.push_back(modelOptions); + + armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize( + *net, backends, runtime->GetDeviceSpec(), optimizerOptions); + + BOOST_CHECK(optimizedNet); + + auto modelOptionsOut = static_cast<armnn::OptimizedNetwork*>(optimizedNet.get())->GetModelOptions(); + + BOOST_TEST(modelOptionsOut.size() == 1); + BOOST_TEST(modelOptionsOut[0].GetOption(0).GetName() == "FastMathEnabled"); + BOOST_TEST(modelOptionsOut[0].GetOption(0).GetValue().AsBool() == true); +} + BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/backends/neon/workloads/NeonConvolution2dWorkload.cpp b/src/backends/neon/workloads/NeonConvolution2dWorkload.cpp index 144baec0ca..83f761158a 100644 --- a/src/backends/neon/workloads/NeonConvolution2dWorkload.cpp +++ b/src/backends/neon/workloads/NeonConvolution2dWorkload.cpp @@ -21,10 +21,11 @@ namespace armnn using namespace armcomputetensorutils; arm_compute::Status NeonConvolution2dWorkloadValidate(const TensorInfo& input, - const TensorInfo& output, - const Convolution2dDescriptor& descriptor, - const TensorInfo& weights, - const Optional<TensorInfo>& biases) + const TensorInfo& output, + const Convolution2dDescriptor& descriptor, + const TensorInfo& weights, + const Optional<TensorInfo>& biases, + bool isFastMathEnabled) { const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout); const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout); @@ -52,7 +53,9 @@ arm_compute::Status NeonConvolution2dWorkloadValidate(const TensorInfo& input, &aclOutputInfo, layerInfo, arm_compute::WeightsInfo(), - aclDilationInfo); + aclDilationInfo, + arm_compute::ActivationLayerInfo(), + isFastMathEnabled); } NeonConvolution2dWorkload::NeonConvolution2dWorkload( diff --git a/src/backends/neon/workloads/NeonConvolution2dWorkload.hpp b/src/backends/neon/workloads/NeonConvolution2dWorkload.hpp index 3fb408dbaa..54e08a2042 100644 --- a/src/backends/neon/workloads/NeonConvolution2dWorkload.hpp +++ b/src/backends/neon/workloads/NeonConvolution2dWorkload.hpp @@ -17,10 +17,11 @@ namespace armnn { arm_compute::Status NeonConvolution2dWorkloadValidate(const TensorInfo& input, - const TensorInfo& output, - const Convolution2dDescriptor& descriptor, - const TensorInfo& weights, - const Optional<TensorInfo>& biases); + const TensorInfo& output, + const Convolution2dDescriptor& descriptor, + const TensorInfo& weights, + const Optional<TensorInfo>& biases, + bool isFastMathEnabled = false); class NeonConvolution2dWorkload : public BaseWorkload<Convolution2dQueueDescriptor> { |