aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Beck <david.beck@arm.com>2018-10-18 15:13:56 +0100
committerMatthew Bentham <matthew.bentham@arm.com>2018-10-22 16:57:54 +0100
commit33f0ae0d293f5048089f2a04985a8a8bfa1d75a6 (patch)
tree19f27463e524150c26ac75a2ea5c8e6c95f954c6
parentceae3aa1b619161d49fd2847d3c73d6a858b2b8c (diff)
downloadarmnn-33f0ae0d293f5048089f2a04985a8a8bfa1d75a6.tar.gz
IVGCVSW-2019 : replace Compute enum in the Layer object
Change-Id: I76551d511ef718eac36e5b8e5fe426ec3a402855
-rw-r--r--include/armnn/BackendId.hpp18
-rw-r--r--src/armnn/Graph.cpp8
-rw-r--r--src/armnn/Layer.cpp2
-rw-r--r--src/armnn/Layer.hpp6
-rw-r--r--src/armnn/LoadedNetwork.cpp32
-rw-r--r--src/armnn/Network.cpp10
-rw-r--r--src/armnn/layers/LayerCloneBase.hpp2
-rw-r--r--src/armnn/test/CreateWorkload.hpp2
-rw-r--r--src/armnn/test/GraphTests.cpp30
-rw-r--r--src/armnn/test/NetworkTests.cpp26
-rw-r--r--src/backends/WorkloadFactory.cpp142
-rw-r--r--src/backends/WorkloadFactory.hpp2
12 files changed, 144 insertions, 136 deletions
diff --git a/include/armnn/BackendId.hpp b/include/armnn/BackendId.hpp
index af3b7995eb..711833d64e 100644
--- a/include/armnn/BackendId.hpp
+++ b/include/armnn/BackendId.hpp
@@ -70,9 +70,12 @@ inline std::ostream& operator<<(std::ostream& os, const Compute& compute)
return os;
}
+struct UninitializedBackendId {};
+
class BackendId final
{
public:
+ BackendId(UninitializedBackendId) { GetComputeDeviceAsCString(Compute::Undefined); }
BackendId(const std::string& id) : m_Id{id} {}
BackendId(const char* id) : m_Id{id} {}
@@ -102,6 +105,21 @@ public:
return m_Id == other.m_Id;
}
+ // comparison against objects from which the
+ // BackendId can be constructed
+ template <typename O>
+ bool operator==(const O& other) const
+ {
+ BackendId temp{other};
+ return *this == temp;
+ }
+
+ template <typename O>
+ bool operator!=(const O& other) const
+ {
+ return !(*this == other);
+ }
+
bool operator<(const BackendId& other) const
{
return m_Id < other.m_Id;
diff --git a/src/armnn/Graph.cpp b/src/armnn/Graph.cpp
index 0ba2d0666a..83d82a5ffe 100644
--- a/src/armnn/Graph.cpp
+++ b/src/armnn/Graph.cpp
@@ -67,7 +67,7 @@ Status Graph::Print() const
for (auto&& it : TopologicalSort())
{
BOOST_LOG_TRIVIAL(info) << it->GetName() << ":" << GetLayerTypeAsCString(it->GetType())
- << ":" << GetComputeDeviceAsCString(it->GetComputeDevice());
+ << ":" << it->GetBackendId().Get();
}
BOOST_LOG_TRIVIAL(info) << "\n\n";
@@ -260,7 +260,7 @@ void Graph::AddCopyLayers()
auto MayNeedCopyLayer = [](const Layer& layer)
{
// All layers should have been associated with a valid compute device at this point.
- BOOST_ASSERT(layer.GetComputeDevice() != Compute::Undefined);
+ BOOST_ASSERT(layer.GetBackendId() != Compute::Undefined);
// Does not need another copy layer if a copy layer is already present.
return layer.GetType() != LayerType::MemCopy;
};
@@ -276,7 +276,7 @@ void Graph::AddCopyLayers()
for (auto&& dstInput : connectionCopy)
{
Layer& dstLayer = dstInput->GetOwningLayer();
- if (MayNeedCopyLayer(dstLayer) && (dstLayer.GetComputeDevice() != srcLayer->GetComputeDevice()))
+ if (MayNeedCopyLayer(dstLayer) && (dstLayer.GetBackendId() != srcLayer->GetBackendId()))
{
// A copy layer is needed in between the source and destination layers.
// Record the operation rather than attempting to modify the graph as we go.
@@ -288,7 +288,7 @@ void Graph::AddCopyLayers()
% dstInput->GetSlotIndex());
MemCopyLayer* const copyLayer = InsertNewLayer<MemCopyLayer>(*dstInput, copyLayerName.c_str());
- copyLayer->SetComputeDevice(dstLayer.GetComputeDevice());
+ copyLayer->SetBackendId(dstLayer.GetBackendId());
}
}
++srcOutputIndex;
diff --git a/src/armnn/Layer.cpp b/src/armnn/Layer.cpp
index d9229203ea..08a8bc3211 100644
--- a/src/armnn/Layer.cpp
+++ b/src/armnn/Layer.cpp
@@ -133,7 +133,7 @@ Layer::Layer(unsigned int numInputSlots,
, m_LayerName(name ? name : "")
, m_Type(type)
, m_DataLayout(layout)
-, m_ComputeDevice(Compute::Undefined)
+, m_BackendId(UninitializedBackendId())
, m_Guid(GenerateLayerGuid())
{
m_InputSlots.reserve(numInputSlots);
diff --git a/src/armnn/Layer.hpp b/src/armnn/Layer.hpp
index d897b255a6..a969607100 100644
--- a/src/armnn/Layer.hpp
+++ b/src/armnn/Layer.hpp
@@ -237,8 +237,8 @@ public:
DataLayout GetDataLayout() const { return m_DataLayout; }
- Compute GetComputeDevice() const { return m_ComputeDevice; }
- void SetComputeDevice(Compute device) { m_ComputeDevice = device; }
+ const BackendId& GetBackendId() const { return m_BackendId; }
+ void SetBackendId(const BackendId& id) { m_BackendId = id; }
// Virtuals
@@ -345,7 +345,7 @@ private:
const LayerType m_Type;
const DataLayout m_DataLayout;
- Compute m_ComputeDevice;
+ BackendId m_BackendId;
/// Used for sorting.
mutable LayerPriority m_Priority = 0;
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp
index ce9f76c986..4f73bda832 100644
--- a/src/armnn/LoadedNetwork.cpp
+++ b/src/armnn/LoadedNetwork.cpp
@@ -122,7 +122,7 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<OptimizedNetwork> net)
const char* const layerName = layer->GetNameStr().length() != 0 ? layer->GetName() : "<Unnamed>";
throw InvalidArgumentException(boost::str(
boost::format("No workload created for layer (name: '%1%' type: '%2%') (compute '%3%')")
- % layerName % static_cast<int>(layer->GetType()) % layer->GetComputeDevice()
+ % layerName % static_cast<int>(layer->GetType()) % layer->GetBackendId().Get()
));
}
@@ -176,27 +176,17 @@ const IWorkloadFactory& LoadedNetwork::GetWorkloadFactory(const Layer& layer) co
{
const IWorkloadFactory* workloadFactory = nullptr;
- switch (layer.GetComputeDevice())
+ if (layer.GetBackendId() == Compute::CpuAcc)
{
- case Compute::CpuAcc:
- {
- workloadFactory = &m_CpuAcc;
- break;
- }
- case Compute::GpuAcc:
- {
- workloadFactory = &m_GpuAcc;
- break;
- }
- case Compute::CpuRef:
- {
- workloadFactory = &m_CpuRef;
- break;
- }
- default:
- {
- break;
- }
+ workloadFactory = &m_CpuAcc;
+ }
+ else if (layer.GetBackendId() == Compute::GpuAcc)
+ {
+ workloadFactory = &m_GpuAcc;
+ }
+ else if (layer.GetBackendId() == Compute::CpuRef)
+ {
+ workloadFactory = &m_CpuRef;
}
BOOST_ASSERT_MSG(workloadFactory, "No workload factory");
diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp
index 51490e33c4..c43f336145 100644
--- a/src/armnn/Network.cpp
+++ b/src/armnn/Network.cpp
@@ -187,7 +187,7 @@ IOptimizedNetworkPtr Optimize(const INetwork& inNetwork,
{
// need to set the compute device on the layer
// before we can check if it is supported
- layer->SetComputeDevice(backend);
+ layer->SetBackendId(backend);
if (!IWorkloadFactory::IsLayerSupported(*layer, dataType, reasonIfUnsupported))
{
if (dataType == DataType::Float16)
@@ -211,7 +211,7 @@ IOptimizedNetworkPtr Optimize(const INetwork& inNetwork,
std::string reasonIfUnsupported;
// Try preferred backend first
- layer->SetComputeDevice(preferredBackend);
+ layer->SetBackendId(preferredBackend);
if (IWorkloadFactory::IsLayerSupported(*layer, boost::none, reasonIfUnsupported))
{
supportedBackendFound = true;
@@ -226,7 +226,7 @@ IOptimizedNetworkPtr Optimize(const INetwork& inNetwork,
continue;
}
- layer->SetComputeDevice(backend);
+ layer->SetBackendId(backend);
if (IWorkloadFactory::IsLayerSupported(*layer, boost::none, reasonIfUnsupported))
{
supportedBackendFound = true;
@@ -260,7 +260,7 @@ IOptimizedNetworkPtr Optimize(const INetwork& inNetwork,
}
std::stringstream warningMsg;
warningMsg << "WARNING: Layer of type " << GetLayerTypeAsCString(layer->GetType())
- << " is not supported on requested backend " << layer->GetComputeDevice()
+ << " is not supported on requested backend " << layer->GetBackendId().Get()
<< " for data type " << GetDataTypeName(dataType)
<< " (reason: " << reasonIfUnsupported
<< "), falling back to the next backend.";
@@ -287,7 +287,7 @@ IOptimizedNetworkPtr Optimize(const INetwork& inNetwork,
layerType == armnn::LayerType::Constant ||
layerType == armnn::LayerType::Permute))
{
- layer->SetComputeDevice(armnn::Compute::CpuRef);
+ layer->SetBackendId(armnn::Compute::CpuRef);
}
else
{
diff --git a/src/armnn/layers/LayerCloneBase.hpp b/src/armnn/layers/LayerCloneBase.hpp
index 9b9e1eaea3..3671d6642a 100644
--- a/src/armnn/layers/LayerCloneBase.hpp
+++ b/src/armnn/layers/LayerCloneBase.hpp
@@ -15,7 +15,7 @@ LayerType* Layer::CloneBase(Graph& graph, Params&& ... params) const
{
LayerType* const layer = graph.AddLayer<LayerType>(std::forward<Params>(params)...);
- layer->SetComputeDevice(m_ComputeDevice);
+ layer->SetBackendId(GetBackendId());
layer->SetGuid(GetGuid());
return layer;
diff --git a/src/armnn/test/CreateWorkload.hpp b/src/armnn/test/CreateWorkload.hpp
index 21385d7a99..db1773a0ce 100644
--- a/src/armnn/test/CreateWorkload.hpp
+++ b/src/armnn/test/CreateWorkload.hpp
@@ -32,7 +32,7 @@ std::unique_ptr<Workload> MakeAndCheckWorkload(Layer& layer, Graph& graph, const
BOOST_TEST(workload.get() == boost::polymorphic_downcast<Workload*>(workload.get()),
"Cannot convert to derived class");
std::string reasonIfUnsupported;
- layer.SetComputeDevice(factory.GetCompute());
+ layer.SetBackendId(factory.GetCompute());
BOOST_TEST(factory.IsLayerSupported(layer, layer.GetDataType(), reasonIfUnsupported));
return std::unique_ptr<Workload>(static_cast<Workload*>(workload.release()));
}
diff --git a/src/armnn/test/GraphTests.cpp b/src/armnn/test/GraphTests.cpp
index b297a74785..e99cb153fc 100644
--- a/src/armnn/test/GraphTests.cpp
+++ b/src/armnn/test/GraphTests.cpp
@@ -336,7 +336,7 @@ static void TestGraphAfterAddingCopyLayers(const armnn::Graph& graph, const armn
// Both layers must have the same compute device.
if (srcLayer && dstLayer)
{
- BOOST_TEST((srcLayer->GetComputeDevice() == dstLayer->GetComputeDevice()));
+ BOOST_TEST((srcLayer->GetBackendId() == dstLayer->GetBackendId()));
}
// Marks edge in original graph as observed (by deleting it).
@@ -418,7 +418,7 @@ static void TestGraphAfterAddingCopyLayers(const armnn::Graph& graph, const armn
}
// Both layers must have different compute devices.
- BOOST_TEST((nonCopyLayer->GetComputeDevice() != adjLayer->GetComputeDevice()));
+ BOOST_TEST((nonCopyLayer->GetBackendId() != adjLayer->GetBackendId()));
// There must exist an edge connecting both layers directly in the original graph.
{
@@ -453,40 +453,40 @@ struct CopyLayersFixture
using namespace std;
Layer* const inputLayer = AddLayer<InputLayer>(0, "input");
- inputLayer->SetComputeDevice(Compute::CpuRef);
+ inputLayer->SetBackendId(Compute::CpuRef);
Convolution2dDescriptor convolutionDefaults;
Layer* const convLayer1 = AddLayer<Convolution2dLayer>(convolutionDefaults, "conv1");
- convLayer1->SetComputeDevice(Compute::CpuRef);
+ convLayer1->SetBackendId(Compute::CpuRef);
inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
Layer* const convLayer2 = AddLayer<Convolution2dLayer>(convolutionDefaults, "conv2");
- convLayer2->SetComputeDevice(Compute::CpuRef);
+ convLayer2->SetBackendId(Compute::CpuRef);
convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
armnn::OriginsDescriptor mergerDefaults(2);
Layer* const mergerLayer = AddLayer<MergerLayer>(mergerDefaults, "merger");
- mergerLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ mergerLayer->SetBackendId(armnn::Compute::CpuRef);
convLayer1->GetOutputSlot(0).Connect(mergerLayer->GetInputSlot(0));
convLayer2->GetOutputSlot(0).Connect(mergerLayer->GetInputSlot(1));
armnn::ActivationDescriptor activationDefaults;
Layer* const actLayer = AddLayer<ActivationLayer>(activationDefaults, "act");
- actLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ actLayer->SetBackendId(armnn::Compute::CpuRef);
mergerLayer->GetOutputSlot(0).Connect(actLayer->GetInputSlot(0));
armnn::SoftmaxDescriptor softmaxDefaults;
Layer* const softmaxLayer = AddLayer<SoftmaxLayer>(softmaxDefaults, "softmax");
- softmaxLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ softmaxLayer->SetBackendId(armnn::Compute::CpuRef);
actLayer->GetOutputSlot(0).Connect(softmaxLayer->GetInputSlot(0));
Layer* const outputLayer = AddLayer<OutputLayer>(0, "output");
- outputLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ outputLayer->SetBackendId(armnn::Compute::CpuRef);
softmaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
}
@@ -537,17 +537,17 @@ BOOST_AUTO_TEST_CASE(CopyLayersAddedBetweenSameLayersHaveDifferentNames)
armnn::Graph graph;
armnn::InputLayer* const inputLayer = graph.AddLayer<armnn::InputLayer>(0, "input");
- inputLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ inputLayer->SetBackendId(armnn::Compute::CpuRef);
armnn::ViewsDescriptor splitterDesc(2);
armnn::SplitterLayer* const splitterLayer = graph.AddLayer<armnn::SplitterLayer>(splitterDesc, "splitter");
- splitterLayer->SetComputeDevice(armnn::Compute::GpuAcc);
+ splitterLayer->SetBackendId(armnn::Compute::GpuAcc);
armnn::AdditionLayer* const additionLayer = graph.AddLayer<armnn::AdditionLayer>("addition");
- additionLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ additionLayer->SetBackendId(armnn::Compute::CpuRef);
armnn::OutputLayer* const outputLayer = graph.AddLayer<armnn::OutputLayer>(0, "output");
- outputLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ outputLayer->SetBackendId(armnn::Compute::CpuRef);
inputLayer->GetOutputSlot(0).Connect(splitterLayer->GetInputSlot(0));
splitterLayer->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(0));
@@ -568,10 +568,10 @@ BOOST_AUTO_TEST_CASE(DuplicateLayerNames)
armnn::Graph graph;
armnn::InputLayer* const inputLayer = graph.AddLayer<armnn::InputLayer>(0, "layer");
- inputLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ inputLayer->SetBackendId(armnn::Compute::CpuRef);
armnn::OutputLayer* const outputLayer = graph.AddLayer<armnn::OutputLayer>(0, "layer");
- outputLayer->SetComputeDevice(armnn::Compute::CpuRef);
+ outputLayer->SetBackendId(armnn::Compute::CpuRef);
inputLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
diff --git a/src/armnn/test/NetworkTests.cpp b/src/armnn/test/NetworkTests.cpp
index f1319464fc..3b426fa8ab 100644
--- a/src/armnn/test/NetworkTests.cpp
+++ b/src/armnn/test/NetworkTests.cpp
@@ -510,7 +510,7 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateCpuAccDeviceSupportLayerNoFallback)
armnn::NeonWorkloadFactory fact;
for (auto&& layer : static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph())
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuAcc, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuAcc);
BOOST_CHECK_NO_THROW(
layer->CreateWorkload(static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph(), fact));
}
@@ -541,7 +541,7 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateGpuDeviceSupportLayerNoFallback)
armnn::ClWorkloadFactory fact;
for (auto&& layer : static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph())
{
- BOOST_CHECK_EQUAL(armnn::Compute::GpuAcc, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::GpuAcc);
BOOST_CHECK_NO_THROW(
layer->CreateWorkload(static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph(), fact));
}
@@ -609,14 +609,14 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateDeviceNonSupportLayerWithFallback)
#if ARMCOMPUTENEON_ENABLED
if (layer->GetType() == armnn::LayerType::Input || layer->GetType() == armnn::LayerType::Output)
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuAcc, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuAcc);
}
else if (layer->GetType() == armnn::LayerType::Normalization)
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
}
#else
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
#endif
}
}
@@ -747,7 +747,7 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateWorkloadsUndefinedComputeDeviceWithFallback
armnn::RefWorkloadFactory fact;
for (auto&& layer : static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph())
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
BOOST_CHECK_NO_THROW(
layer->CreateWorkload(static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph(), fact));
}
@@ -791,23 +791,23 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateWorkloadsDuplicateComputeDeviceWithFallback
#if ARMCOMPUTENEON_ENABLED
if (layer->GetType() == armnn::LayerType::Input || layer->GetType() == armnn::LayerType::Output)
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuAcc, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuAcc);
}
else if (layer->GetType() == armnn::LayerType::Normalization)
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
}
#elif ARMCOMPUTECL_ENABLED
if (layer->GetType() == armnn::LayerType::Input || layer->GetType() == armnn::LayerType::Output)
{
- BOOST_CHECK_EQUAL(armnn::Compute::GpuAcc, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::GpuAcc);
}
else if (layer->GetType() == armnn::LayerType::Normalization)
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
}
#else
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
#endif
}
}
@@ -841,7 +841,7 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateWorkloadsCpuRefPermuteLayer)
for (auto&& layer : static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph())
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
}
}
@@ -874,7 +874,7 @@ BOOST_AUTO_TEST_CASE(OptimizeValidateWorkloadsCpuRefMeanLayer)
for (auto&& layer : static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph())
{
- BOOST_CHECK_EQUAL(armnn::Compute::CpuRef, layer->GetComputeDevice());
+ BOOST_CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
}
}
diff --git a/src/backends/WorkloadFactory.cpp b/src/backends/WorkloadFactory.cpp
index 05919d6d95..e7dec49db4 100644
--- a/src/backends/WorkloadFactory.cpp
+++ b/src/backends/WorkloadFactory.cpp
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: MIT
//
#include <backends/WorkloadFactory.hpp>
+#include <backends/LayerSupportRegistry.hpp>
#include <backends/reference/RefWorkloadFactory.hpp>
#include <backends/neon/NeonWorkloadFactory.hpp>
@@ -54,16 +55,19 @@ namespace
}
}
-bool IWorkloadFactory::IsLayerSupported(Compute compute,
+bool IWorkloadFactory::IsLayerSupported(const BackendId& backendId,
const IConnectableLayer& connectableLayer,
boost::optional<DataType> dataType,
std::string& outReasonIfUnsupported)
{
- constexpr size_t reasonCapacity = 1024;
- char reason[reasonCapacity];
+ Optional<std::string&> reason = outReasonIfUnsupported;
bool result;
const Layer& layer = *(boost::polymorphic_downcast<const Layer*>(&connectableLayer));
+ auto const& layerSupportRegistry = LayerSupportRegistryInstance();
+ auto layerSupportFactory = layerSupportRegistry.GetFactory(backendId);
+ auto layerSupportObject = layerSupportFactory();
+
switch(layer.GetType())
{
case LayerType::Activation:
@@ -71,12 +75,11 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
auto cLayer = boost::polymorphic_downcast<const ActivationLayer*>(&layer);
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsActivationSupported(compute,
+ result = layerSupportObject->IsActivationSupported(
OverrideDataType(input, dataType),
OverrideDataType(output, dataType),
cLayer->GetParameters(),
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Addition:
@@ -84,12 +87,11 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
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,
+ result = layerSupportObject->IsAdditionSupported(
OverrideDataType(input0, dataType),
OverrideDataType(input1, dataType),
OverrideDataType(output, dataType),
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::BatchNormalization:
@@ -101,7 +103,7 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
const TensorInfo& var = cLayer->m_Variance->GetTensorInfo();
const TensorInfo& beta = cLayer->m_Beta->GetTensorInfo();
const TensorInfo& gamma = cLayer->m_Gamma->GetTensorInfo();
- result = IsBatchNormalizationSupported(compute,
+ result = layerSupportObject->IsBatchNormalizationSupported(
OverrideDataType(input, dataType),
OverrideDataType(output, dataType),
OverrideDataType(mean, dataType),
@@ -109,27 +111,27 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
OverrideDataType(beta, dataType),
OverrideDataType(gamma, dataType),
cLayer->GetParameters(),
- reason, reasonCapacity);
+ reason);
break;
}
case LayerType::Constant:
{
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsConstantSupported(compute, OverrideDataType(output, dataType), reason, reasonCapacity);
+ result = layerSupportObject->IsConstantSupported(OverrideDataType(output, dataType), reason);
break;
}
case LayerType::ConvertFp16ToFp32:
{
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsConvertFp16ToFp32Supported(compute, input, output, reason, reasonCapacity);
+ result = layerSupportObject->IsConvertFp16ToFp32Supported(input, output, reason);
break;
}
case LayerType::ConvertFp32ToFp16:
{
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsConvertFp32ToFp16Supported(compute, input, output, reason, reasonCapacity);
+ result = layerSupportObject->IsConvertFp32ToFp16Supported(input, output, reason);
break;
}
case LayerType::Convolution2d:
@@ -151,23 +153,22 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
OverrideDataType(cLayer->m_Bias->GetTensorInfo(), GetBiasTypeFromWeightsType(dataType));
}
- result = IsConvolution2dSupported(compute,
+ result = layerSupportObject->IsConvolution2dSupported(
input,
output,
descriptor,
OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType),
biases,
- reason,
- reasonCapacity);
+ reason);
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");
+ result = backendId == Compute::CpuRef || backendId == Compute::Undefined
+ || backendId == Compute::CpuAcc || backendId == Compute::GpuAcc;
+ reason.value() = "Unsupported backend type";
break;
}
case LayerType::DepthwiseConvolution2d:
@@ -188,30 +189,31 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
OverrideDataType(cLayer->m_Bias->GetTensorInfo(), GetBiasTypeFromWeightsType(dataType));
}
- result = IsDepthwiseConvolutionSupported(compute,
+ result = layerSupportObject->IsDepthwiseConvolutionSupported(
input,
output,
descriptor,
OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType),
biases,
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::FakeQuantization:
{
auto cLayer = boost::polymorphic_downcast<const FakeQuantizationLayer*>(&layer);
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
- result = IsFakeQuantizationSupported(compute, OverrideDataType(input, dataType), cLayer->GetParameters(),
- reason, reasonCapacity);
+ result = layerSupportObject->IsFakeQuantizationSupported(OverrideDataType(input, dataType),
+ cLayer->GetParameters(),
+ reason);
break;
}
case LayerType::Floor:
{
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsFloorSupported(compute, OverrideDataType(input, dataType), OverrideDataType(output, dataType),
- reason, reasonCapacity);
+ result = layerSupportObject->IsFloorSupported(OverrideDataType(input, dataType),
+ OverrideDataType(output, dataType),
+ reason);
break;
}
case LayerType::FullyConnected:
@@ -261,20 +263,19 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
}
}
- result = IsFullyConnectedSupported(compute,
+ result = layerSupportObject->IsFullyConnectedSupported(
OverrideDataType(input, dataType),
OverrideDataType(output, dataType),
OverrideDataType(cLayer->m_Weight->GetTensorInfo(), dataType),
*biasInfoPtr,
descriptor,
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Input:
{
const TensorInfo& input = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsInputSupported(compute, OverrideDataType(input, dataType), reason, reasonCapacity);
+ result = layerSupportObject->IsInputSupported(OverrideDataType(input, dataType), reason);
break;
}
case LayerType::L2Normalization:
@@ -285,12 +286,11 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsL2NormalizationSupported(compute,
+ result = layerSupportObject->IsL2NormalizationSupported(
OverrideDataType(input, dataType),
OverrideDataType(output, dataType),
descriptor,
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Lstm:
@@ -393,7 +393,7 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
cellToOutputWeights = &optCellToOutputWeights;
}
- result = IsLstmSupported(compute,
+ result = layerSupportObject->IsLstmSupported(
input,
outputStateIn,
cellStateIn,
@@ -419,8 +419,7 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
projectionBias,
cellToForgetWeights,
cellToOutputWeights,
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Merger:
@@ -444,7 +443,7 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
auto endPtr = boost::make_transform_iterator(inputs.end(), getTensorInfoPtr);
std::vector<const TensorInfo*> inputPtrs(beginPtr, endPtr);
- result = IsMergerSupported(compute, inputPtrs, cLayer->GetParameters(), reason, reasonCapacity);
+ result = layerSupportObject->IsMergerSupported(inputPtrs, cLayer->GetParameters(), reason);
break;
}
case LayerType::Multiplication:
@@ -452,12 +451,11 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsMultiplicationSupported(compute,
+ result = layerSupportObject->IsMultiplicationSupported(
OverrideDataType(input0, dataType),
OverrideDataType(input1, dataType),
OverrideDataType(output, dataType),
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Normalization:
@@ -465,15 +463,16 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
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, OverrideDataType(input, dataType),
- OverrideDataType(output, dataType), cLayer->GetParameters(), reason,
- reasonCapacity);
+ result = layerSupportObject->IsNormalizationSupported(OverrideDataType(input, dataType),
+ OverrideDataType(output, dataType),
+ cLayer->GetParameters(),
+ reason);
break;
}
case LayerType::Output:
{
const TensorInfo& output = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
- result = IsOutputSupported(compute, OverrideDataType(output, dataType), reason, reasonCapacity);
+ result = layerSupportObject->IsOutputSupported(OverrideDataType(output, dataType), reason);
break;
}
case LayerType::Permute:
@@ -481,8 +480,10 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
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, OverrideDataType(input, dataType), OverrideDataType(output, dataType),
- cLayer->GetParameters(), reason, reasonCapacity);
+ result = layerSupportObject->IsPermuteSupported(OverrideDataType(input, dataType),
+ OverrideDataType(output, dataType),
+ cLayer->GetParameters(),
+ reason);
break;
}
case LayerType::Pad:
@@ -490,12 +491,11 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
auto cLayer = boost::polymorphic_downcast<const PadLayer*>(&layer);
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsPadSupported(compute,
+ result = layerSupportObject->IsPadSupported(
OverrideDataType(input, dataType),
OverrideDataType(output, dataType),
cLayer->GetParameters(),
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Pooling2d:
@@ -503,9 +503,10 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
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, OverrideDataType(input, dataType),
- OverrideDataType(output, dataType), cLayer->GetParameters(), reason,
- reasonCapacity);
+ result = layerSupportObject->IsPooling2dSupported(OverrideDataType(input, dataType),
+ OverrideDataType(output, dataType),
+ cLayer->GetParameters(),
+ reason);
break;
}
case LayerType::Division:
@@ -513,24 +514,23 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsDivisionSupported(compute,
+ result = layerSupportObject->IsDivisionSupported(
OverrideDataType(input0, dataType),
OverrideDataType(input1, dataType),
OverrideDataType(output, dataType),
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Reshape:
{
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
- result = IsReshapeSupported(compute, OverrideDataType(input, dataType), reason, reasonCapacity);
+ result = layerSupportObject->IsReshapeSupported(OverrideDataType(input, dataType), reason);
break;
}
case LayerType::ResizeBilinear:
{
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
- result = IsResizeBilinearSupported(compute, OverrideDataType(input, dataType), reason, reasonCapacity);
+ result = layerSupportObject->IsResizeBilinearSupported(OverrideDataType(input, dataType), reason);
break;
}
case LayerType::Softmax:
@@ -538,16 +538,19 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
auto cLayer = boost::polymorphic_downcast<const SoftmaxLayer*>(&layer);
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsSoftmaxSupported(compute, OverrideDataType(input, dataType), OverrideDataType(output, dataType),
- cLayer->GetParameters(), reason, reasonCapacity);
+ result = layerSupportObject->IsSoftmaxSupported(OverrideDataType(input, dataType),
+ OverrideDataType(output, dataType),
+ cLayer->GetParameters(),
+ reason);
break;
}
case LayerType::Splitter:
{
auto cLayer = boost::polymorphic_downcast<const SplitterLayer*>(&layer);
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
- result = IsSplitterSupported(compute, OverrideDataType(input, dataType), cLayer->GetParameters(), reason,
- reasonCapacity);
+ result = layerSupportObject->IsSplitterSupported(OverrideDataType(input, dataType),
+ cLayer->GetParameters(),
+ reason);
break;
}
case LayerType::Subtraction:
@@ -555,12 +558,11 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsSubtractionSupported(compute,
+ result = layerSupportObject->IsSubtractionSupported(
OverrideDataType(input0, dataType),
OverrideDataType(input1, dataType),
OverrideDataType(output, dataType),
- reason,
- reasonCapacity);
+ reason);
break;
}
case LayerType::Mean:
@@ -568,23 +570,21 @@ bool IWorkloadFactory::IsLayerSupported(Compute compute,
auto cLayer = boost::polymorphic_downcast<const MeanLayer*>(&layer);
const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
- result = IsMeanSupported(compute,
+ result = layerSupportObject->IsMeanSupported(
OverrideDataType(input, dataType),
OverrideDataType(output, dataType),
cLayer->GetParameters(),
- reason,
- reasonCapacity);
+ reason);
break;
}
default:
{
BOOST_ASSERT_MSG(false, "WorkloadFactory did not recognise type of layer.");
- strcpy(reason, "Unrecognised layer type");
+ reason.value() = "Unrecognised layer type";
result = false;
break;
}
}
- outReasonIfUnsupported = reason;
return result;
}
@@ -593,7 +593,7 @@ bool IWorkloadFactory::IsLayerSupported(const IConnectableLayer& connectableLaye
std::string& outReasonIfUnsupported)
{
auto layer = boost::polymorphic_downcast<const Layer*>(&connectableLayer);
- return IsLayerSupported(layer->GetComputeDevice(), connectableLayer, dataType, outReasonIfUnsupported);
+ return IsLayerSupported(layer->GetBackendId(), connectableLayer, dataType, outReasonIfUnsupported);
}
}
diff --git a/src/backends/WorkloadFactory.hpp b/src/backends/WorkloadFactory.hpp
index 38448ca378..41d6741ae7 100644
--- a/src/backends/WorkloadFactory.hpp
+++ b/src/backends/WorkloadFactory.hpp
@@ -32,7 +32,7 @@ public:
/// Inform the memory manager to acquire memory
virtual void Acquire() { }
- static bool IsLayerSupported(Compute compute,
+ static bool IsLayerSupported(const BackendId& backendId,
const IConnectableLayer& layer,
boost::optional<DataType> dataType,
std::string& outReasonIfUnsupported);