From 23be07e855c066f192c1007d529064462853a27c Mon Sep 17 00:00:00 2001 From: jimfly01 Date: Tue, 4 Dec 2018 17:47:22 +0000 Subject: IVGCVSW-2333 Add ParseSub method to TfParser * Also added unit test Sub.cpp Change-Id: I6d23c11ae894ee433cd28ffdf0248b14e01b0131 --- src/armnnTfParser/TfParser.cpp | 40 ++++++++++++ src/armnnTfParser/TfParser.hpp | 1 + src/armnnTfParser/test/Sub.cpp | 135 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 src/armnnTfParser/test/Sub.cpp (limited to 'src') diff --git a/src/armnnTfParser/TfParser.cpp b/src/armnnTfParser/TfParser.cpp index 0d425257e8..8f6352c6e7 100644 --- a/src/armnnTfParser/TfParser.cpp +++ b/src/armnnTfParser/TfParser.cpp @@ -385,6 +385,7 @@ const std::map TfParser::ms_Ope { "Maximum", &TfParser::ParseMaximum }, { "Minimum", &TfParser::ParseMinimum }, { "Pad", &TfParser::ParsePad }, + { "Sub", &TfParser::ParseSub }, }; ITfParser* ITfParser::CreateRaw() @@ -1612,6 +1613,45 @@ ParsedTfOperationPtr TfParser::ParseMinimum(const tensorflow::NodeDef& nodeDef, return std::make_unique(this, nodeDef, layer); } +ParsedTfOperationPtr TfParser::ParseSub(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef) +{ + std::vector inputs = GetInputParsedTfOperationsChecked(nodeDef, 2); + + IOutputSlot* input0Slot = &inputs[0].m_IndexedValue->ResolveArmnnOutputSlot(inputs[0].m_Index); + IOutputSlot* input1Slot = &inputs[1].m_IndexedValue->ResolveArmnnOutputSlot(inputs[1].m_Index); + + const TensorInfo& input0Info = input0Slot->GetTensorInfo(); + const TensorInfo& input1Info = input1Slot->GetTensorInfo(); + + if (input0Info.GetNumDimensions() == 1) + { + const bool isNHWC = true; + input0Slot = AddBroadcastReshapeLayer(input1Slot, input0Slot, isNHWC, *m_Network, nodeDef); + } + + if (input1Info.GetNumDimensions() == 1) + { + const bool isNHWC = true; + input1Slot = AddBroadcastReshapeLayer(input0Slot, input1Slot, isNHWC, *m_Network, nodeDef); + } + + IConnectableLayer* const layer = m_Network->AddSubtractionLayer(nodeDef.name().c_str()); + + input0Slot->Connect(layer->GetInputSlot(0)); + input1Slot->Connect(layer->GetInputSlot(1)); + + if (input0Info.GetNumDimensions() == 1) + { + layer->GetOutputSlot(0).SetTensorInfo(input1Slot->GetTensorInfo()); + } + else + { + layer->GetOutputSlot(0).SetTensorInfo(input0Slot->GetTensorInfo()); + } + + return std::make_unique(this, nodeDef, layer); +} + unsigned int CheckPaddingTensor(const ConstTensor& paddingTensor, const TensorInfo& inputTensorInfo, const std::string& nodeName) diff --git a/src/armnnTfParser/TfParser.hpp b/src/armnnTfParser/TfParser.hpp index da78f48f54..5ca867c0f7 100644 --- a/src/armnnTfParser/TfParser.hpp +++ b/src/armnnTfParser/TfParser.hpp @@ -157,6 +157,7 @@ private: ParsedTfOperationPtr ParseMaximum(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef); ParsedTfOperationPtr ParseMinimum(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef); ParsedTfOperationPtr ParsePad(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef); + ParsedTfOperationPtr ParseSub(const tensorflow::NodeDef& nodeDef, const tensorflow::GraphDef& graphDef); ParsedTfOperationPtr AddActivationLayer(const tensorflow::NodeDef& nodeDef, armnn::ActivationDescriptor& desc); ParsedTfOperationPtr AddAdditionLayer(const tensorflow::NodeDef& nodeDef, bool isBiasAdd = false); ParsedTfOperationPtr AddRealDivLayer(const tensorflow::NodeDef& nodeDef); diff --git a/src/armnnTfParser/test/Sub.cpp b/src/armnnTfParser/test/Sub.cpp new file mode 100644 index 0000000000..2b3cbe65d8 --- /dev/null +++ b/src/armnnTfParser/test/Sub.cpp @@ -0,0 +1,135 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include +#include "armnnTfParser/ITfParser.hpp" +#include "ParserPrototxtFixture.hpp" + +BOOST_AUTO_TEST_SUITE(TensorflowParser) + +struct SubFixture : public armnnUtils::ParserPrototxtFixture +{ + SubFixture(const armnn::TensorShape& inputShape0, const armnn::TensorShape& inputShape1) + { + m_Prototext = R"( +node { + name: "input0" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_FLOAT + } + } + attr { + key: "shape" + value { + shape { + } + } + } +} +node { + name: "input1" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_FLOAT + } + } + attr { + key: "shape" + value { + shape { + } + } + } +} +node { + name: "output" + op: "Sub" + input: "input0" + input: "input1" + attr { + key: "T" + value { + type: DT_FLOAT + } + } +} + )"; + Setup({ { "input0", inputShape0 }, + { "input1", inputShape1 } }, + { "output" }); + + } +}; + +struct SubFixture4D4D : public SubFixture +{ + SubFixture4D4D() : SubFixture({ 1, 2, 2, 3 }, { 1, 2, 2, 3 }) {} +}; + +BOOST_FIXTURE_TEST_CASE(ParseSub, SubFixture4D4D) +{ + RunTest<4>({ { "input0", { 5.0f, 1.0f, 2.0f, + 3.0f, 4.0f, 5.0f, + 6.0f, 7.0f, 8.0f, + 29.0f, 10.0f, 11.0f } }, + + { "input1", { 0.0f, 1.0f, 3.0f, + 4.0f, 5.5f, 1.0f, + 2.0f, 17.0f, 18.0f, + 19.0f, 1.0f, 3.0f } } }, + + { { "output", { 5.0f, 0.0f, -1.0f, + -1.0f, -1.5f, 4.0f, + 4.0f, -10.0f, -10.0f, + 10.0f, 9.0f, 8.0f } } }); +} + +struct SubBroadcastFixture4D1D : public SubFixture +{ + SubBroadcastFixture4D1D() : SubFixture({ 1, 2, 2, 3 }, { 1 }) {} +}; + +BOOST_FIXTURE_TEST_CASE(ParseSubBroadcast4D1D, SubBroadcastFixture4D1D) +{ + RunTest<4>({ { "input0", { 0.0f, 1.0f, 2.0f, + 3.0f, 4.0f, 5.0f, + 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f } }, + + { "input1", { 5.0f } } }, + + { { "output", { -5.0f, -4.0f, -3.0f, + -2.0f, -1.0f, 0.0f, + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f } } }); +} + +struct SubBroadcastFixture1D4D : public SubFixture +{ + SubBroadcastFixture1D4D() : SubFixture({ 1 }, { 1, 2, 2, 3 }) {} +}; + +BOOST_FIXTURE_TEST_CASE(ParseSubBroadcast1D4D, SubBroadcastFixture1D4D) +{ + RunTest<4>({ { "input0", { 3.0f } }, + + { "input1", { 0.0f, 1.0f, 2.0f, + 3.0f, 4.0f, 5.0f, + 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f } } }, + + { { "output", { 3.0f, 2.0f, 1.0f, + 0.0f, -1.0f, -2.0f, + -3.0f, -4.0f, -5.0f, + -6.0f, -7.0f, -8.0f } } }); +} + + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file -- cgit v1.2.1