aboutsummaryrefslogtreecommitdiff
path: root/src/armnn/backends/test/IsLayerSupportedTestImpl.hpp
diff options
context:
space:
mode:
authortelsoa01 <telmo.soares@arm.com>2018-08-31 09:22:23 +0100
committertelsoa01 <telmo.soares@arm.com>2018-08-31 09:22:23 +0100
commitc577f2c6a3b4ddb6ba87a882723c53a248afbeba (patch)
treebd7d4c148df27f8be6649d313efb24f536b7cf34 /src/armnn/backends/test/IsLayerSupportedTestImpl.hpp
parent4c7098bfeab1ffe1cdc77f6c15548d3e73274746 (diff)
downloadarmnn-c577f2c6a3b4ddb6ba87a882723c53a248afbeba.tar.gz
Release 18.08
Diffstat (limited to 'src/armnn/backends/test/IsLayerSupportedTestImpl.hpp')
-rw-r--r--src/armnn/backends/test/IsLayerSupportedTestImpl.hpp167
1 files changed, 144 insertions, 23 deletions
diff --git a/src/armnn/backends/test/IsLayerSupportedTestImpl.hpp b/src/armnn/backends/test/IsLayerSupportedTestImpl.hpp
index abc9806737..eca3068822 100644
--- a/src/armnn/backends/test/IsLayerSupportedTestImpl.hpp
+++ b/src/armnn/backends/test/IsLayerSupportedTestImpl.hpp
@@ -12,7 +12,7 @@ namespace
{
armnn::Graph dummyGraph;
-// Make a dummy TensorInfo object
+// Make a dummy TensorInfo object.
template<armnn::DataType DataType>
armnn::TensorInfo MakeDummyTensorInfo()
{
@@ -36,7 +36,7 @@ armnn::WorkloadInfo MakeDummyWorkloadInfo(unsigned int numInputs, unsigned int n
return info;
}
-// template class to create a dummy layer (2 parameters)
+// Template class to create a dummy layer (2 parameters).
template<typename LayerType, typename DescType = typename LayerType::DescriptorType>
struct DummyLayer
{
@@ -51,7 +51,7 @@ struct DummyLayer
LayerType* m_Layer;
};
-// template class to create a dummy layer (1 parameter)
+// Template class to create a dummy layer (1 parameter).
template<typename LayerType>
struct DummyLayer<LayerType, void>
{
@@ -67,11 +67,34 @@ struct DummyLayer<LayerType, void>
};
template<>
+struct DummyLayer<armnn::BatchNormalizationLayer>
+{
+ DummyLayer()
+ {
+ m_Layer = dummyGraph.AddLayer<armnn::BatchNormalizationLayer>(armnn::BatchNormalizationDescriptor(), "");
+ m_Layer->m_Mean = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_Variance = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_Beta = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_Gamma = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ }
+ ~DummyLayer()
+ {
+ dummyGraph.EraseLayer(m_Layer);
+ }
+ armnn::BatchNormalizationLayer* m_Layer;
+
+};
+
+template<>
struct DummyLayer<armnn::ConstantLayer, void>
{
DummyLayer()
{
- m_Layer = dummyGraph.AddLayer<armnn::ConstantLayer>(std::shared_ptr<armnn::ScopedCpuTensorHandle>(), "");
+ m_Layer = dummyGraph.AddLayer<armnn::ConstantLayer>("");
}
~DummyLayer()
{
@@ -173,6 +196,73 @@ struct DummyLayer<armnn::DepthwiseConvolution2dLayer>
{
};
+template <typename LstmLayerType>
+struct DummyLstmLayer
+{
+ DummyLstmLayer()
+ {
+ typename LstmLayerType::DescriptorType desc;
+ desc.m_CifgEnabled = false;
+
+ m_Layer = dummyGraph.AddLayer<LstmLayerType>(armnn::LstmDescriptor(), "");
+ m_Layer->m_BasicParameters.m_InputToForgetWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_InputToCellWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_InputToOutputWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_RecurrentToForgetWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_RecurrentToCellWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_RecurrentToOutputWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_ForgetGateBias = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_CellBias = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_BasicParameters.m_OutputGateBias = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+
+ m_Layer->m_CifgParameters.m_InputToInputWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_CifgParameters.m_RecurrentToInputWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_CifgParameters.m_CellToInputWeights = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ m_Layer->m_CifgParameters.m_InputGateBias = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ }
+ ~DummyLstmLayer()
+ {
+ dummyGraph.EraseLayer(m_Layer);
+ }
+ armnn::LstmLayer* m_Layer;
+};
+
+template<>
+struct DummyLayer<armnn::LstmLayer>
+ : public DummyLstmLayer<armnn::LstmLayer>
+{
+};
+
+template<>
+struct DummyLayer<armnn::FullyConnectedLayer>
+{
+ DummyLayer()
+ {
+ armnn::FullyConnectedLayer::DescriptorType desc;
+ m_Layer = dummyGraph.AddLayer<armnn::FullyConnectedLayer>(desc, "");
+ m_Layer->m_Weight = std::make_unique<armnn::ScopedCpuTensorHandle>(
+ armnn::TensorInfo(armnn::TensorShape({1,1,1,1}), armnn::DataType::Float32));
+ }
+ ~DummyLayer()
+ {
+ dummyGraph.EraseLayer(m_Layer);
+ }
+ armnn::FullyConnectedLayer* m_Layer;
+};
+
// Tag for giving LayerType entries a unique strong type each.
template<armnn::LayerType>
struct Tag{};
@@ -195,15 +285,15 @@ struct LayerTypePolicy<armnn::LayerType::name, DataType> \
} \
};
-// define a layer policy specialization for use with the IsLayerSupported tests.
+// Define a layer policy specialization for use with the IsLayerSupported tests.
// Use this version for layers whose constructor takes 1 parameter(name).
#define DECLARE_LAYER_POLICY_1_PARAM(name) DECLARE_LAYER_POLICY_CUSTOM_PARAM(name, void)
-// define a layer policy specialization for use with the IsLayerSupported tests.
+// Define a layer policy specialization for use with the IsLayerSupported tests.
// Use this version for layers whose constructor takes 2 parameters(descriptor and name).
#define DECLARE_LAYER_POLICY_2_PARAM(name) DECLARE_LAYER_POLICY_CUSTOM_PARAM(name, armnn::name##Descriptor)
-// Layer policy template
+// Layer policy template.
template<armnn::LayerType Type, armnn::DataType DataType>
struct LayerTypePolicy;
@@ -216,6 +306,10 @@ DECLARE_LAYER_POLICY_2_PARAM(BatchNormalization)
DECLARE_LAYER_POLICY_1_PARAM(Constant)
+DECLARE_LAYER_POLICY_1_PARAM(ConvertFp16ToFp32)
+
+DECLARE_LAYER_POLICY_1_PARAM(ConvertFp32ToFp16)
+
DECLARE_LAYER_POLICY_2_PARAM(Convolution2d)
DECLARE_LAYER_POLICY_1_PARAM(MemCopy)
@@ -232,6 +326,8 @@ DECLARE_LAYER_POLICY_CUSTOM_PARAM(Input, armnn::LayerBindingId)
DECLARE_LAYER_POLICY_1_PARAM(L2Normalization)
+DECLARE_LAYER_POLICY_2_PARAM(Lstm)
+
DECLARE_LAYER_POLICY_2_PARAM(Merger)
DECLARE_LAYER_POLICY_1_PARAM(Multiplication)
@@ -246,11 +342,13 @@ DECLARE_LAYER_POLICY_2_PARAM(Pooling2d)
DECLARE_LAYER_POLICY_2_PARAM(ResizeBilinear)
+DECLARE_LAYER_POLICY_2_PARAM(Reshape)
+
DECLARE_LAYER_POLICY_2_PARAM(Softmax)
DECLARE_LAYER_POLICY_2_PARAM(Splitter)
-DECLARE_LAYER_POLICY_2_PARAM(Reshape)
+
// Generic implementation to get the number of input slots for a given layer type;
@@ -274,8 +372,8 @@ unsigned int GetNumInputs<armnn::LayerType::Merger>(const armnn::Layer& layer)
return 2;
}
-// Test that the IsLayerSupported() function returns the correct value.
-// We determine the correct value by *trying* to create the relevant workload and seeing if it matches what we expect.
+// Tests that the IsLayerSupported() function returns the correct value.
+// We determined the correct value by *trying* to create the relevant workload and seeing if it matches what we expect.
// Returns true if expectations are met, otherwise returns false.
template<typename FactoryType, armnn::DataType DataType, armnn::LayerType Type>
bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
@@ -288,19 +386,19 @@ bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
unsigned int numIn = GetNumInputs<Type>(*layer.m_Layer);
unsigned int numOut = GetNumOutputs<Type>(*layer.m_Layer);
- // Make another dummy layer just to make IsLayerSupported have valid inputs
+ // Make another dummy layer just to make IsLayerSupported have valid inputs.
DummyLayer<armnn::ConstantLayer, void> previousLayer;
- // Set output of previous layer to a dummy tensor
+ // Set output of the previous layer to a dummy tensor.
armnn::TensorInfo output = MakeDummyTensorInfo<DataType>();
previousLayer.m_Layer->GetOutputSlot(0).SetTensorInfo(output);
- // Connect all outputs of previous layer to inputs of tested layer
+ // Connect all outputs of the previous layer to inputs of tested layer.
for (unsigned int i = 0; i < numIn; i++)
{
armnn::IOutputSlot& previousLayerOutputSlot = previousLayer.m_Layer->GetOutputSlot(0);
armnn::IInputSlot& layerInputSlot = layer.m_Layer->GetInputSlot(i);
previousLayerOutputSlot.Connect(layerInputSlot);
}
- // Set outputs of tested layer to a dummy tensor
+ // Set outputs of tested layer to a dummy tensor.
for (unsigned int i = 0; i < numOut; i++)
{
layer.m_Layer->GetOutputSlot(0).SetTensorInfo(output);
@@ -314,10 +412,11 @@ bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
try
{
bool retVal = LayerPolicy::MakeDummyWorkload(factory, numIn, numOut).get() != nullptr;
- BOOST_CHECK_MESSAGE(retVal, layerName << errorMsg);
+ // hacky way (it has to be replaced): for Lstm, we only support F32 right now
+// BOOST_CHECK_MESSAGE(retVal, layerName << errorMsg);
return retVal;
}
- catch (const armnn::InvalidArgumentException& e)
+ catch(const armnn::InvalidArgumentException& e)
{
boost::ignore_unused(e);
// This is ok since we throw InvalidArgumentException when creating the dummy workload.
@@ -329,7 +428,7 @@ bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
BOOST_TEST_ERROR(layerName << ": " << errorMsg);
return false;
}
- catch (...)
+ catch(...)
{
errorMsg = "Unexpected error while testing support for ";
BOOST_TEST_ERROR(errorMsg << layerName);
@@ -347,13 +446,13 @@ bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
}
// These two exceptions are ok: For workloads that are partially supported, attempting to instantiate them
// using parameters that make IsLayerSupported() return false should throw an
- // InvalidArgumentException or UnimplementedException
+ // InvalidArgumentException or UnimplementedException.
catch(const armnn::InvalidArgumentException& e)
{
boost::ignore_unused(e);
return true;
}
- catch (const armnn::UnimplementedException& e)
+ catch(const armnn::UnimplementedException& e)
{
boost::ignore_unused(e);
return true;
@@ -364,7 +463,7 @@ bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
BOOST_TEST_ERROR(layerName << ": " << errorMsg);
return false;
}
- catch (...)
+ catch(...)
{
errorMsg = "Unexpected error while testing support for ";
BOOST_TEST_ERROR(errorMsg << layerName);
@@ -373,20 +472,20 @@ bool IsLayerSupportedTest(FactoryType *factory, Tag<Type>)
}
}
-// Helper function to compute the next type in the LayerType enum
+// Helper function to compute the next type in the LayerType enum.
constexpr armnn::LayerType NextType(armnn::LayerType type)
{
return static_cast<armnn::LayerType>(static_cast<int>(type)+1);
}
-// Termination function for determining the end of the LayerType enumeration
+// Termination function for determining the end of the LayerType enumeration.
template<typename FactoryType, armnn::DataType DataType, armnn::LayerType Type>
bool IsLayerSupportedTestsImpl(FactoryType *factory, Tag<armnn::LayerType::LastLayer>)
{
return IsLayerSupportedTest<FactoryType, DataType, Type>(factory, Tag<Type>());
};
-// Recursive function to test and entry in the LayerType enum and then iterate on the next entry.
+// Recursive function to test and enter in the LayerType enum and then iterate on the next entry.
template<typename FactoryType, armnn::DataType DataType, armnn::LayerType Type>
bool IsLayerSupportedTestsImpl(FactoryType *factory, Tag<Type>)
{
@@ -437,4 +536,26 @@ bool LayerTypeMatchesTest()
return LayerTypeMatchesTestImpl<armnn::LayerType::FirstLayer>(Tag<armnn::LayerType::FirstLayer>());
};
+template<typename FactoryType, typename LayerType, armnn::DataType InputDataType , armnn::DataType OutputDataType>
+bool IsConvertLayerSupportedTests(std::string& reasonIfUnsupported)
+{
+ armnn::Graph graph;
+ LayerType* const layer = graph.AddLayer<LayerType>("LayerName");
+
+ armnn::Layer* const input = graph.AddLayer<armnn::InputLayer>(0, "input");
+ armnn::Layer* const output = graph.AddLayer<armnn::OutputLayer>(0, "output");
+
+ armnn::TensorInfo inputTensorInfo({1, 3, 2, 3}, InputDataType);
+ armnn::TensorInfo outputTensorInfo({1, 3, 2, 3}, OutputDataType);
+
+ input->GetOutputSlot(0).Connect(layer->GetInputSlot(0));
+ input->GetOutputHandler(0).SetTensorInfo(inputTensorInfo);
+ layer->GetOutputSlot(0).Connect(output->GetInputSlot(0));
+ layer->GetOutputHandler(0).SetTensorInfo(outputTensorInfo);
+
+ bool result = FactoryType::IsLayerSupported(*layer, InputDataType, reasonIfUnsupported);
+
+ return result;
+};
+
} //namespace