diff options
author | telsoa01 <telmo.soares@arm.com> | 2018-03-09 14:13:49 +0000 |
---|---|---|
committer | telsoa01 <telmo.soares@arm.com> | 2018-03-09 14:13:49 +0000 |
commit | 4fcda0101ec3d110c1d6d7bee5c83416b645528a (patch) | |
tree | c9a70aeb2887006160c1b3d265c27efadb7bdbae /src/armnn/backends/WorkloadFactory.cpp | |
download | armnn-4fcda0101ec3d110c1d6d7bee5c83416b645528a.tar.gz |
Release 18.02
Change-Id: Id3c11dc5ee94ef664374a988fcc6901e9a232fa6
Diffstat (limited to 'src/armnn/backends/WorkloadFactory.cpp')
-rw-r--r-- | src/armnn/backends/WorkloadFactory.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/src/armnn/backends/WorkloadFactory.cpp b/src/armnn/backends/WorkloadFactory.cpp new file mode 100644 index 0000000000..32634a6d0f --- /dev/null +++ b/src/armnn/backends/WorkloadFactory.cpp @@ -0,0 +1,214 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// See LICENSE file in the project root for full license information. +// +#include "WorkloadFactory.hpp" +#include "RefWorkloadFactory.hpp" +#include "NeonWorkloadFactory.hpp" +#include "ClWorkloadFactory.hpp" + +#include "armnn/Types.hpp" +#include "armnn/LayerSupport.hpp" +#include "Layer.hpp" +#include "Layers.hpp" +#include "CpuTensorHandle.hpp" + +#include <boost/cast.hpp> +#include <cstring> +#include <boost/iterator/transform_iterator.hpp> + +namespace armnn +{ + +bool IWorkloadFactory::IsLayerSupported(Compute compute, const Layer& layer, DataType dataType, + std::string& outReasonIfUnsupported) +{ + constexpr size_t reasonCapacity = 1024; + char reason[reasonCapacity]; + bool result; + switch(layer.GetType()) + { + case LayerType::Activation: + { + auto cLayer = boost::polymorphic_downcast<const ActivationLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsActivationSupported(compute, input, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Addition: + { + const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsAdditionSupported(compute, input0, input1, output, reason, reasonCapacity); + break; + } + case LayerType::BatchNormalization: + { + auto cLayer = boost::polymorphic_downcast<const BatchNormalizationLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsBatchNormalizationSupported(compute, input, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Constant: + { + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsConstantSupported(compute, output, reason, reasonCapacity); + break; + } + case LayerType::Convolution2d: + { + auto cLayer = boost::polymorphic_downcast<const Convolution2dLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsConvolution2dSupported(compute, input, cLayer->GetParameters(), + cLayer->m_Weight->GetTensorInfo(), reason, reasonCapacity); + break; + } + case LayerType::MemCopy: + { + // MemCopy supported for CpuRef, CpuAcc and GpuAcc backends + // (also treat Undefined as CpuRef to avoid breaking lots of Unit tests) + result = compute == Compute::CpuRef || compute == Compute::Undefined + || compute == Compute::CpuAcc || compute == Compute::GpuAcc; + strcpy(reason, "Unsupported backend type"); + break; + } + case LayerType::DepthwiseConvolution2d: + { + auto cLayer = boost::polymorphic_downcast<const DepthwiseConvolution2dLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsDepthwiseConvolutionSupported(compute, input, cLayer->GetParameters(), + cLayer->m_Weight->GetTensorInfo(), reason, reasonCapacity); + break; + } + case LayerType::FakeQuantization: + { + auto cLayer = boost::polymorphic_downcast<const FakeQuantizationLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsFakeQuantizationSupported(compute, input, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Floor: + { + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsFloorSupported(compute, input, output, reason, reasonCapacity); + break; + } + case LayerType::FullyConnected: + { + auto cLayer = boost::polymorphic_downcast<const FullyConnectedLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsFullyConnectedSupported(compute, input, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Input: + { + const TensorInfo& input = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsInputSupported(compute, input, reason, reasonCapacity); + break; + } + case LayerType::L2Normalization: + { + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsL2NormalizationSupported(compute, input, reason, reasonCapacity); + break; + } + case LayerType::Merger: + { + auto cLayer = boost::polymorphic_downcast<const MergerLayer*>(&layer); + + // Get vector of all inputs + auto getTensorInfo = [](const InputSlot& slot) + { + return &slot.GetConnectedOutputSlot()->GetTensorInfo(); + }; + auto begin = boost::make_transform_iterator(layer.GetInputSlots().begin(), getTensorInfo); + auto end = boost::make_transform_iterator(layer.GetInputSlots().end(), getTensorInfo); + + std::vector<const TensorInfo*> inputs(begin, end); + + result = IsMergerSupported(compute, inputs, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Multiplication: + { + const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo(); + result = IsMultiplicationSupported(compute, input0, input1, reason, reasonCapacity); + break; + } + case LayerType::Normalization: + { + auto cLayer = boost::polymorphic_downcast<const NormalizationLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsNormalizationSupported(compute, input, output, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Output: + { + const TensorInfo& output = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsOutputSupported(compute, output, reason, reasonCapacity); + break; + } + case LayerType::Permute: + { + auto cLayer = boost::polymorphic_downcast<const PermuteLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsPermuteSupported(compute, input, output, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Pooling2d: + { + auto cLayer = boost::polymorphic_downcast<const Pooling2dLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = IsPooling2dSupported(compute, input, output, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Reshape: + { + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsReshapeSupported(compute, input, reason, reasonCapacity); + break; + } + case LayerType::ResizeBilinear: + { + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsResizeBilinearSupported(compute, input, reason, reasonCapacity); + break; + } + case LayerType::Softmax: + { + auto cLayer = boost::polymorphic_downcast<const SoftmaxLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsSoftmaxSupported(compute, input, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + case LayerType::Splitter: + { + auto cLayer = boost::polymorphic_downcast<const SplitterLayer*>(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + result = IsSplitterSupported(compute, input, cLayer->GetParameters(), reason, reasonCapacity); + break; + } + default: + { + BOOST_ASSERT_MSG(false, "WorkloadFactory did not recognise type of layer."); + strcpy(reason, "Unrecognised layer type"); + result = false; + break; + } + } + outReasonIfUnsupported = reason; + return result; +} + +bool IWorkloadFactory::IsLayerSupported(const Layer& layer, DataType dataType, std::string& outReasonIfUnsupported) +{ + return IsLayerSupported(layer.GetComputeDevice(), layer, dataType, outReasonIfUnsupported); +} + +}
\ No newline at end of file |