aboutsummaryrefslogtreecommitdiff
path: root/src/armnnDeserializeParser
diff options
context:
space:
mode:
authorSaoirse Stewart <saoirse.stewart@arm.com>2019-02-18 15:24:53 +0000
committerAron Virginas-Tar <aron.virginas-tar@arm.com>2019-02-19 11:52:27 +0000
commit3166c3edeb64d834ba27031ddd39b5b1f940b604 (patch)
tree2789010d0878d64442f51ba0edbd8f159d1a32a0 /src/armnnDeserializeParser
parenta6b504a8925174739f5a064cf77d1563cca38708 (diff)
downloadarmnn-3166c3edeb64d834ba27031ddd39b5b1f940b604.tar.gz
IVGCVSW-2645 Add Serializer & Deserializer for Pooling2d
Change-Id: Iba41da3cccd539a0175f2ed0ff9a8b6a23c5fb6f Signed-off-by: Aron Virginas-Tar <Aron.Virginas-Tar@arm.com> Signed-off-by: Saoirse Stewart <saoirse.stewart@arm.com>
Diffstat (limited to 'src/armnnDeserializeParser')
-rw-r--r--src/armnnDeserializeParser/DeserializeParser.cpp125
-rw-r--r--src/armnnDeserializeParser/DeserializeParser.hpp5
-rw-r--r--src/armnnDeserializeParser/test/DeserializePooling2d.cpp162
3 files changed, 287 insertions, 5 deletions
diff --git a/src/armnnDeserializeParser/DeserializeParser.cpp b/src/armnnDeserializeParser/DeserializeParser.cpp
index eb7bccaa1d..f47c23f0b5 100644
--- a/src/armnnDeserializeParser/DeserializeParser.cpp
+++ b/src/armnnDeserializeParser/DeserializeParser.cpp
@@ -136,6 +136,7 @@ m_ParserFunctions(Layer_MAX+1, &DeserializeParser::ParseUnsupportedLayer)
// register supported layers
m_ParserFunctions[Layer_AdditionLayer] = &DeserializeParser::ParseAdd;
m_ParserFunctions[Layer_MultiplicationLayer] = &DeserializeParser::ParseMultiplication;
+ m_ParserFunctions[Layer_Pooling2dLayer] = &DeserializeParser::ParsePooling2d;
m_ParserFunctions[Layer_SoftmaxLayer] = &DeserializeParser::ParseSoftmax;
}
@@ -153,6 +154,8 @@ DeserializeParser::LayerBaseRawPtr DeserializeParser::GetBaseLayer(const GraphPt
return graphPtr->layers()->Get(layerIndex)->layer_as_MultiplicationLayer()->base();
case Layer::Layer_OutputLayer:
return graphPtr->layers()->Get(layerIndex)->layer_as_OutputLayer()->base()->base();
+ case Layer::Layer_Pooling2dLayer:
+ return graphPtr->layers()->Get(layerIndex)->layer_as_Pooling2dLayer()->base();
case Layer::Layer_SoftmaxLayer:
return graphPtr->layers()->Get(layerIndex)->layer_as_SoftmaxLayer()->base();
case Layer::Layer_NONE:
@@ -356,7 +359,6 @@ DeserializeParser::GraphPtr DeserializeParser::LoadGraphFromFile(const char* fil
}
std::ifstream file(fileName, std::ios::binary);
fileContent = std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
-
return LoadGraphFromBinary(reinterpret_cast<const uint8_t*>(fileContent.c_str()), fileContent.size());
}
@@ -581,8 +583,8 @@ void DeserializeParser::ParseAdd(unsigned int layerIndex)
auto outputs = GetOutputs(m_Graph, layerIndex);
CHECK_VALID_SIZE(outputs.size(), 1);
- auto layerName = boost::str(boost::format("Addition:%1%") % layerIndex);
- IConnectableLayer* layer = m_Network->AddAdditionLayer(layerName.c_str());
+ m_layerName = boost::str(boost::format("Addition:%1%") % layerIndex);
+ IConnectableLayer* layer = m_Network->AddAdditionLayer(m_layerName.c_str());
armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
@@ -601,8 +603,8 @@ void DeserializeParser::ParseMultiplication(unsigned int layerIndex)
auto outputs = GetOutputs(m_Graph, layerIndex);
CHECK_VALID_SIZE(outputs.size(), 1);
- auto layerName = boost::str(boost::format("Multiplication:%1%") % layerIndex);
- IConnectableLayer* layer = m_Network->AddMultiplicationLayer(layerName.c_str());
+ m_layerName = boost::str(boost::format("Multiplication:%1%") % layerIndex);
+ IConnectableLayer* layer = m_Network->AddMultiplicationLayer(m_layerName.c_str());
armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
@@ -611,6 +613,119 @@ void DeserializeParser::ParseMultiplication(unsigned int layerIndex)
RegisterOutputSlots(layerIndex, layer);
}
+armnn::Pooling2dDescriptor DeserializeParser::GetPoolingDescriptor(DeserializeParser::PoolingDescriptor pooling2dDesc,
+ unsigned int layerIndex)
+{
+ armnn::Pooling2dDescriptor desc;
+
+ switch (pooling2dDesc->poolType())
+ {
+ case PoolingAlgorithm_Average:
+ {
+ desc.m_PoolType = armnn::PoolingAlgorithm::Average;
+ m_layerName = boost::str(boost::format("AveragePool2D:%1%") % layerIndex);
+ break;
+ }
+ case PoolingAlgorithm_Max:
+ {
+ desc.m_PoolType = armnn::PoolingAlgorithm::Max;
+ m_layerName = boost::str(boost::format("MaxPool2D:%1%") % layerIndex);
+ break;
+ }
+ default:
+ {
+ BOOST_ASSERT_MSG(false, "Unsupported pooling algorithm");
+ }
+ }
+
+ switch (pooling2dDesc->outputShapeRounding())
+ {
+ case OutputShapeRounding_Floor:
+ {
+ desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
+ break;
+ }
+ case OutputShapeRounding_Ceiling:
+ {
+ desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Ceiling;
+ break;
+ }
+ default:
+ {
+ BOOST_ASSERT_MSG(false, "Unsupported output shape rounding");
+ }
+ }
+
+ switch (pooling2dDesc->paddingMethod())
+ {
+ case PaddingMethod_Exclude:
+ {
+ desc.m_PaddingMethod = armnn::PaddingMethod::Exclude;
+ break;
+ }
+ case PaddingMethod_IgnoreValue:
+ {
+ desc.m_PaddingMethod = armnn::PaddingMethod::IgnoreValue;
+ break;
+ }
+ default:
+ {
+ BOOST_ASSERT_MSG(false, "Unsupported padding method");
+ }
+ }
+
+ switch (pooling2dDesc->dataLayout())
+ {
+ case DataLayout_NCHW:
+ {
+ desc.m_DataLayout = armnn::DataLayout::NCHW;
+ break;
+ }
+ case DataLayout_NHWC:
+ {
+ desc.m_DataLayout = armnn::DataLayout::NHWC;
+ break;
+ }
+ default:
+ {
+ BOOST_ASSERT_MSG(false, "Unsupported data layout");
+ }
+ }
+
+ desc.m_PadRight = pooling2dDesc->padRight();
+ desc.m_PadLeft = pooling2dDesc->padLeft();
+ desc.m_PadBottom = pooling2dDesc->padBottom();
+ desc.m_PadTop = pooling2dDesc->padTop();
+ desc.m_StrideX = pooling2dDesc->strideX();
+ desc.m_StrideY = pooling2dDesc->strideY();
+ desc.m_PoolWidth = pooling2dDesc->poolWidth();
+ desc.m_PoolHeight = pooling2dDesc->poolHeight();
+
+ return desc;
+}
+
+void DeserializeParser::ParsePooling2d(unsigned int layerIndex)
+{
+ CHECK_LAYERS(m_Graph, 0, layerIndex);
+
+ auto pooling2dDes = m_Graph->layers()->Get(layerIndex)->layer_as_Pooling2dLayer()->descriptor();
+
+ auto inputs = GetInputs(m_Graph, layerIndex);
+ CHECK_VALID_SIZE(inputs.size(), 1);
+
+ auto outputs = GetOutputs(m_Graph, layerIndex);
+ CHECK_VALID_SIZE(outputs.size(), 1);
+ auto outputInfo = ToTensorInfo(outputs[0]);
+
+ auto pooling2dDescriptor = GetPoolingDescriptor(pooling2dDes, layerIndex);
+
+ IConnectableLayer* layer = m_Network->AddPooling2dLayer(pooling2dDescriptor, m_layerName.c_str());
+ layer->GetOutputSlot(0).SetTensorInfo(outputInfo);
+
+ RegisterInputSlots(layerIndex, layer);
+ RegisterOutputSlots(layerIndex, layer);
+}
+
void DeserializeParser::ParseSoftmax(unsigned int layerIndex)
{
CHECK_LAYERS(m_Graph, 0, layerIndex);
diff --git a/src/armnnDeserializeParser/DeserializeParser.hpp b/src/armnnDeserializeParser/DeserializeParser.hpp
index ddd02abede..1edb5a9f23 100644
--- a/src/armnnDeserializeParser/DeserializeParser.hpp
+++ b/src/armnnDeserializeParser/DeserializeParser.hpp
@@ -17,6 +17,7 @@ public:
// Shorthands for deserializer types
using GraphPtr = const armnn::armnnSerializer::SerializedGraph *;
using TensorRawPtr = const armnn::armnnSerializer::TensorInfo *;
+ using PoolingDescriptor = const armnn::armnnSerializer::Pooling2dDescriptor *;
using TensorRawPtrVector = std::vector<TensorRawPtr>;
using LayerRawPtr = const armnn::armnnSerializer::LayerBase *;
using LayerBaseRawPtr = const armnn::armnnSerializer::LayerBase *;
@@ -50,6 +51,8 @@ public:
static LayerBaseRawPtrVector GetGraphOutputs(const GraphPtr& graphPtr);
static LayerBaseRawPtr GetBaseLayer(const GraphPtr& graphPtr, unsigned int layerIndex);
static int32_t GetBindingLayerInfo(const GraphPtr& graphPtr, unsigned int layerIndex);
+ armnn::Pooling2dDescriptor GetPoolingDescriptor(PoolingDescriptor pooling2dDescriptor,
+ unsigned int layerIndex);
private:
// No copying allowed until it is wanted and properly implemented
@@ -65,6 +68,7 @@ private:
void ParseUnsupportedLayer(unsigned int layerIndex);
void ParseAdd(unsigned int layerIndex);
void ParseMultiplication(unsigned int layerIndex);
+ void ParsePooling2d(unsigned int layerIndex);
void ParseSoftmax(unsigned int layerIndex);
void RegisterOutputSlotOfConnection(uint32_t connectionIndex, armnn::IOutputSlot* slot);
@@ -82,6 +86,7 @@ private:
armnn::INetworkPtr m_Network;
GraphPtr m_Graph;
std::vector<LayerParsingFunction> m_ParserFunctions;
+ std::string m_layerName;
/// This holds the data of the file that was read in from CreateNetworkFromBinaryFile
/// Needed for m_Graph to point to
diff --git a/src/armnnDeserializeParser/test/DeserializePooling2d.cpp b/src/armnnDeserializeParser/test/DeserializePooling2d.cpp
new file mode 100644
index 0000000000..70b96ba27b
--- /dev/null
+++ b/src/armnnDeserializeParser/test/DeserializePooling2d.cpp
@@ -0,0 +1,162 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <boost/test/unit_test.hpp>
+#include "ParserFlatbuffersSerializeFixture.hpp"
+#include "../DeserializeParser.hpp"
+
+#include <string>
+#include <iostream>
+
+BOOST_AUTO_TEST_SUITE(DeserializeParser)
+
+struct Pooling2dFixture : public ParserFlatbuffersSerializeFixture
+{
+ explicit Pooling2dFixture(const std::string &inputShape,
+ const std::string &outputShape,
+ const std::string &dataType,
+ const std::string &dataLayout,
+ const std::string &poolingAlgorithm)
+ {
+ m_JsonString = R"(
+ {
+ inputIds: [0],
+ outputIds: [2],
+ layers: [
+ {
+ layer_type: "InputLayer",
+ layer: {
+ base: {
+ layerBindingId: 0,
+ base: {
+ index: 0,
+ layerName: "InputLayer",
+ layerType: "Input",
+ inputSlots: [{
+ index: 0,
+ connection: {sourceLayerIndex:0, outputSlotIndex:0 },
+ }],
+ outputSlots: [ {
+ index: 0,
+ tensorInfo: {
+ dimensions: )" + inputShape + R"(,
+ dataType: )" + dataType + R"(
+ }}]
+ }
+ }}},
+ {
+ layer_type: "Pooling2dLayer",
+ layer: {
+ base: {
+ index: 1,
+ layerName: "Pooling2dLayer",
+ layerType: "Pooling2d",
+ inputSlots: [{
+ index: 0,
+ connection: {sourceLayerIndex:0, outputSlotIndex:0 },
+ }],
+ outputSlots: [ {
+ index: 0,
+ tensorInfo: {
+ dimensions: )" + outputShape + R"(,
+ dataType: )" + dataType + R"(
+
+ }}]},
+ descriptor: {
+ poolType: )" + poolingAlgorithm + R"(,
+ outputShapeRounding: "Floor",
+ paddingMethod: Exclude,
+ dataLayout: )" + dataLayout + R"(,
+ padLeft: 0,
+ padRight: 0,
+ padTop: 0,
+ padBottom: 0,
+ poolWidth: 2,
+ poolHeight: 2,
+ strideX: 2,
+ strideY: 2
+ }
+ }},
+ {
+ layer_type: "OutputLayer",
+ layer: {
+ base:{
+ layerBindingId: 0,
+ base: {
+ index: 2,
+ layerName: "OutputLayer",
+ layerType: "Output",
+ inputSlots: [{
+ index: 0,
+ connection: {sourceLayerIndex:1, outputSlotIndex:0 },
+ }],
+ outputSlots: [ {
+ index: 0,
+ tensorInfo: {
+ dimensions: )" + outputShape + R"(,
+ dataType: )" + dataType + R"(
+ },
+ }],
+ }}},
+ }]
+ }
+ )";
+ SetupSingleInputSingleOutput("InputLayer", "OutputLayer");
+ }
+};
+
+struct SimpleAvgPoolingFixture : Pooling2dFixture
+{
+ SimpleAvgPoolingFixture() : Pooling2dFixture("[ 1, 2, 2, 1 ]", "[ 1, 1, 1, 1 ]",
+ "Float32", "NHWC", "Average") {}
+};
+
+struct SimpleAvgPoolingFixture2 : Pooling2dFixture
+{
+ SimpleAvgPoolingFixture2() : Pooling2dFixture("[ 1, 2, 2, 1 ]",
+ "[ 1, 1, 1, 1 ]",
+ "QuantisedAsymm8", "NHWC", "Average") {}
+};
+
+struct SimpleMaxPoolingFixture : Pooling2dFixture
+{
+ SimpleMaxPoolingFixture() : Pooling2dFixture("[ 1, 1, 2, 2 ]",
+ "[ 1, 1, 1, 1 ]",
+ "Float32", "NCHW", "Max") {}
+};
+
+struct SimpleMaxPoolingFixture2 : Pooling2dFixture
+{
+ SimpleMaxPoolingFixture2() : Pooling2dFixture("[ 1, 1, 2, 2 ]",
+ "[ 1, 1, 1, 1 ]",
+ "QuantisedAsymm8", "NCHW", "Max") {}
+};
+
+BOOST_FIXTURE_TEST_CASE(PoolingQuantisedAsymm8Avg, SimpleAvgPoolingFixture)
+{
+ RunTest<4, armnn::DataType::Float32>(0, { 2, 3, 5, 2 }, { 3 });
+}
+
+BOOST_FIXTURE_TEST_CASE(PoolingFloat32Avg, SimpleAvgPoolingFixture2)
+{
+ RunTest<4, armnn::DataType::QuantisedAsymm8>(0,
+ { 20, 40, 60, 80 },
+ { 50 });
+}
+
+BOOST_FIXTURE_TEST_CASE(PoolingQuantisedAsymm8Max, SimpleMaxPoolingFixture)
+{
+ RunTest<4, armnn::DataType::Float32>(0, { 2, 5, 5, 2 }, { 5 });
+}
+
+BOOST_FIXTURE_TEST_CASE(PoolingFloat32Max, SimpleMaxPoolingFixture2)
+{
+ RunTest<4, armnn::DataType::QuantisedAsymm8>(0,
+ { 20, 40, 60, 80 },
+ { 80 });
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+