aboutsummaryrefslogtreecommitdiff
path: root/src/armnnUtils
diff options
context:
space:
mode:
authorFerran Balaguer <ferran.balaguer@arm.com>2019-01-11 19:29:18 +0000
committerFerran Balaguer Arm <ferran.balaguer@arm.com>2019-01-14 09:45:15 +0000
commit51dd62f5725e8a97f3f6957fbc2b899493eb7bb3 (patch)
treef8cce612850d49d798686cce5ad2ab7545b6e0b7 /src/armnnUtils
parent992d6dc57d8463729910b688f0fb5825d0d3ccf2 (diff)
downloadarmnn-51dd62f5725e8a97f3f6957fbc2b899493eb7bb3.tar.gz
IVGCVSW-1656 Add Mean support to Tf Parser
Change-Id: I3d31d6b72be1984acdb51fd9e7b5488a7aa5d832
Diffstat (limited to 'src/armnnUtils')
-rw-r--r--src/armnnUtils/ParserHelper.cpp49
-rw-r--r--src/armnnUtils/ParserHelper.hpp5
-rw-r--r--src/armnnUtils/ParserPrototxtFixture.hpp88
-rw-r--r--src/armnnUtils/test/ParsePrototxtFixtureTest.cpp42
-rw-r--r--src/armnnUtils/test/ParserHelperTest.cpp98
5 files changed, 275 insertions, 7 deletions
diff --git a/src/armnnUtils/ParserHelper.cpp b/src/armnnUtils/ParserHelper.cpp
index bf5ffdf0ad..9d633cfc42 100644
--- a/src/armnnUtils/ParserHelper.cpp
+++ b/src/armnnUtils/ParserHelper.cpp
@@ -61,4 +61,53 @@ void ProcessConcatInputTensorInfo(armnn::TensorInfo& inputTensorInfo, armnn::Ori
}
}
+void CalculateReducedOutputTensoInfo(const armnn::TensorInfo& inputTensorInfo, const armnn::TensorInfo& axisTensorInfo,
+ const std::set<unsigned int>& axisSet, bool keepDims,
+ armnn::TensorInfo& outputTensorInfo)
+{
+ std::vector<unsigned int> outputShapeVector;
+ bool dimensionFound = false;
+ unsigned int size = 1;
+
+ for (unsigned int i = 0; i < inputTensorInfo.GetNumDimensions(); ++i)
+ {
+ dimensionFound = false;
+ for (unsigned int axis: axisSet)
+ {
+ if (axis == i)
+ {
+ dimensionFound = true;
+ break;
+ }
+ }
+
+ if (!dimensionFound)
+ {
+ size *= inputTensorInfo.GetShape()[i];
+
+ if (keepDims)
+ {
+ outputShapeVector.push_back(inputTensorInfo.GetShape()[i]);
+ }
+ }
+ else
+ {
+ if (keepDims)
+ {
+ outputShapeVector.push_back(1);
+ }
+ }
+ }
+
+ if (keepDims)
+ {
+ armnn::TensorShape outputTensorShape(inputTensorInfo.GetNumDimensions(), &outputShapeVector[0]);
+ outputTensorInfo = armnn::TensorInfo(outputTensorShape, inputTensorInfo.GetDataType());
+ }
+ else
+ {
+ outputTensorInfo = armnn::TensorInfo({size}, inputTensorInfo.GetDataType());
+ }
+}
+
} // namespace armnnUtils
diff --git a/src/armnnUtils/ParserHelper.hpp b/src/armnnUtils/ParserHelper.hpp
index 93dfbf9360..24369dc521 100644
--- a/src/armnnUtils/ParserHelper.hpp
+++ b/src/armnnUtils/ParserHelper.hpp
@@ -14,4 +14,9 @@ void ProcessConcatInputTensorInfo(armnn::TensorInfo& inputTensorInfo, armnn::Ori
const unsigned int& concatAxis, unsigned int inputIndex,
std::vector<unsigned int>& mergeDimSizes, unsigned int& mergeDim);
+/// Creates a tensor info after reducing the dimensions mentioned in axisData.
+void CalculateReducedOutputTensoInfo(const armnn::TensorInfo& inputTensorInfo, const armnn::TensorInfo& axisTensorInfo,
+ const std::set<unsigned int>& axisSet, bool keepDims,
+ armnn::TensorInfo& outputTensorInfo);
+
} // namespace armnnUtils
diff --git a/src/armnnUtils/ParserPrototxtFixture.hpp b/src/armnnUtils/ParserPrototxtFixture.hpp
index acb8f82c4d..154f6bec2a 100644
--- a/src/armnnUtils/ParserPrototxtFixture.hpp
+++ b/src/armnnUtils/ParserPrototxtFixture.hpp
@@ -16,6 +16,7 @@
#include <boost/format.hpp>
+#include <iomanip>
#include <string>
namespace armnnUtils
@@ -37,6 +38,10 @@ struct ParserPrototxtFixture
void SetupSingleInputSingleOutput(const armnn::TensorShape& inputTensorShape,
const std::string& inputName,
const std::string& outputName);
+ void SetupSingleInputSingleOutput(const armnn::TensorShape& inputTensorShape,
+ const armnn::TensorShape& outputTensorShape,
+ const std::string& inputName,
+ const std::string& outputName);
void Setup(const std::map<std::string, armnn::TensorShape>& inputShapes,
const std::vector<std::string>& requestedOutputs);
void Setup();
@@ -56,6 +61,9 @@ struct ParserPrototxtFixture
void RunTest(const std::map<std::string, std::vector<float>>& inputData,
const std::map<std::string, std::vector<float>>& expectedOutputData);
+ /// Converts an int value into the Protobuf octal representation
+ std::string ConvertInt32ToOctalString(int value);
+
std::string m_Prototext;
std::unique_ptr<TParser, void(*)(TParser* parser)> m_Parser;
armnn::IRuntimePtr m_Runtime;
@@ -67,6 +75,10 @@ struct ParserPrototxtFixture
std::string m_SingleInputName;
std::string m_SingleOutputName;
/// @}
+
+ /// This will store the output shape so it don't need to be passed to the single-input-single-output overload
+ /// of RunTest().
+ armnn::TensorShape m_SingleOutputShape;
};
template<typename TParser>
@@ -91,6 +103,20 @@ void ParserPrototxtFixture<TParser>::SetupSingleInputSingleOutput(const armnn::T
}
template<typename TParser>
+void ParserPrototxtFixture<TParser>::SetupSingleInputSingleOutput(const armnn::TensorShape& inputTensorShape,
+ const armnn::TensorShape& outputTensorShape,
+ const std::string& inputName,
+ const std::string& outputName)
+{
+ // Stores the input name, the output name and the output tensor shape
+ // so they don't need to be passed to the single-input-single-output RunTest().
+ m_SingleInputName = inputName;
+ m_SingleOutputName = outputName;
+ m_SingleOutputShape = outputTensorShape;
+ Setup({ { inputName, inputTensorShape } }, { outputName });
+}
+
+template<typename TParser>
void ParserPrototxtFixture<TParser>::Setup(const std::map<std::string, armnn::TensorShape>& inputShapes,
const std::vector<std::string>& requestedOutputs)
{
@@ -181,17 +207,65 @@ void ParserPrototxtFixture<TParser>::RunTest(const std::map<std::string, std::ve
if (bindingInfo.second.GetNumElements() != it.second.size())
{
throw armnn::Exception(
- boost::str(
- boost::format("Output tensor %1% is expected to have %2% elements. "
- "%3% elements supplied. %4%") %
- it.first %
- bindingInfo.second.GetNumElements() %
- it.second.size() %
- CHECK_LOCATION().AsString()));
+ boost::str(boost::format("Output tensor %1% is expected to have %2% elements. "
+ "%3% elements supplied. %4%") %
+ it.first %
+ bindingInfo.second.GetNumElements() %
+ it.second.size() %
+ CHECK_LOCATION().AsString()));
}
+
+ // If the expected output shape is set, the output tensor checks will be carried out.
+ if (m_SingleOutputShape.GetNumDimensions() != 0)
+ {
+
+ if (bindingInfo.second.GetShape().GetNumDimensions() == NumOutputDimensions &&
+ bindingInfo.second.GetShape().GetNumDimensions() == m_SingleOutputShape.GetNumDimensions())
+ {
+ for (unsigned int i = 0; i < m_SingleOutputShape.GetNumDimensions(); ++i)
+ {
+ if (m_SingleOutputShape[i] != bindingInfo.second.GetShape()[i])
+ {
+ throw armnn::Exception(
+ boost::str(boost::format("Output tensor %1% is expected to have %2% shape. "
+ "%3% shape supplied. %4%") %
+ it.first %
+ bindingInfo.second.GetShape() %
+ m_SingleOutputShape %
+ CHECK_LOCATION().AsString()));
+ }
+ }
+ }
+ else
+ {
+ throw armnn::Exception(
+ boost::str(boost::format("Output tensor %1% is expected to have %2% dimensions. "
+ "%3% dimensions supplied. %4%") %
+ it.first %
+ bindingInfo.second.GetShape().GetNumDimensions() %
+ NumOutputDimensions %
+ CHECK_LOCATION().AsString()));
+ }
+ }
+
auto outputExpected = MakeTensor<float, NumOutputDimensions>(bindingInfo.second, it.second);
BOOST_TEST(CompareTensors(outputExpected, outputStorage[it.first]));
}
}
+template<typename TParser>
+std::string ParserPrototxtFixture<TParser>::ConvertInt32ToOctalString(int value)
+{
+ std::stringstream ss;
+ std::string returnString;
+ for (int i = 0; i < 4; ++i)
+ {
+ ss << "\\";
+ ss << std::setw(3) << std::setfill('0') << std::oct << ((value >> (i * 8)) & 0xFF);
+ }
+
+ ss >> returnString;
+ return returnString;
+}
+
} // namespace armnnUtils
diff --git a/src/armnnUtils/test/ParsePrototxtFixtureTest.cpp b/src/armnnUtils/test/ParsePrototxtFixtureTest.cpp
new file mode 100644
index 0000000000..926658ed0c
--- /dev/null
+++ b/src/armnnUtils/test/ParsePrototxtFixtureTest.cpp
@@ -0,0 +1,42 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <ParserPrototxtFixture.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include "armnnTfParser/ITfParser.hpp"
+
+BOOST_AUTO_TEST_SUITE(ParsePrototxtFixtureSuite)
+
+using Fixture = armnnUtils::ParserPrototxtFixture<armnnTfParser::ITfParser>;
+
+BOOST_FIXTURE_TEST_CASE(ConvertInt32ToOctalStringTest, Fixture)
+{
+ std::string octalString = ConvertInt32ToOctalString(1);
+ BOOST_ASSERT(octalString.compare("\\\\001\\\\000\\\\000\\\\000"));
+
+ octalString = ConvertInt32ToOctalString(256);
+ BOOST_ASSERT(octalString.compare("\\\\000\\\\100\\\\000\\\\000"));
+
+ octalString = ConvertInt32ToOctalString(65536);
+ BOOST_ASSERT(octalString.compare("\\\\000\\\\000\\\\100\\\\000"));
+
+ octalString = ConvertInt32ToOctalString(16777216);
+ BOOST_ASSERT(octalString.compare("\\\\000\\\\000\\\\000\\\\100"));
+
+ octalString = ConvertInt32ToOctalString(-1);
+ BOOST_ASSERT(octalString.compare("\\\\377\\\\377\\\\377\\\\377"));
+
+ octalString = ConvertInt32ToOctalString(-256);
+ BOOST_ASSERT(octalString.compare("\\\\000\\\\377\\\\377\\\\377"));
+
+ octalString = ConvertInt32ToOctalString(-65536);
+ BOOST_ASSERT(octalString.compare("\\\\000\\\\000\\\\377\\\\377"));
+
+ octalString = ConvertInt32ToOctalString(-16777216);
+ BOOST_ASSERT(octalString.compare("\\\\000\\\\000\\\\000\\\\377"));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/armnnUtils/test/ParserHelperTest.cpp b/src/armnnUtils/test/ParserHelperTest.cpp
new file mode 100644
index 0000000000..122ad7649e
--- /dev/null
+++ b/src/armnnUtils/test/ParserHelperTest.cpp
@@ -0,0 +1,98 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "../ParserHelper.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include "armnn/Types.hpp"
+
+using namespace armnn;
+using namespace armnnUtils;
+
+BOOST_AUTO_TEST_SUITE(ParserHelperSuite)
+
+BOOST_AUTO_TEST_CASE(CalculateReducedOutputTensoInfoTest)
+{
+ bool keepDims = false;
+
+ unsigned int inputShape[] = { 2, 3, 4 };
+ TensorInfo inputTensorInfo(3, &inputShape[0], DataType::Float32);
+
+ // Reducing all dimensions results in one single output value (one dimension)
+ unsigned int axisShape1[] = { 3 };
+ std::set<unsigned int> axisData1 = { 0, 1, 2 };
+ TensorInfo axisTensorInfo1(1, &axisShape1[0], DataType::Signed32);
+
+ TensorInfo outputTensorInfo1;
+
+ CalculateReducedOutputTensoInfo(inputTensorInfo, axisTensorInfo1, axisData1,
+ keepDims, outputTensorInfo1);
+
+ BOOST_ASSERT(outputTensorInfo1.GetNumDimensions() == 1);
+ BOOST_ASSERT(outputTensorInfo1.GetShape()[0] == 1);
+
+ // Reducing dimension 0 results in a 3x4 size tensor (one dimension)
+ unsigned int axisShape2[] = { 1 };
+ std::set<unsigned int> axisData2 = { 0 };
+ TensorInfo axisTensorInfo2(1, &axisShape2[0], DataType::Signed32);
+
+ TensorInfo outputTensorInfo2;
+
+ CalculateReducedOutputTensoInfo(inputTensorInfo, axisTensorInfo2, axisData2,
+ keepDims, outputTensorInfo2);
+
+ BOOST_ASSERT(outputTensorInfo2.GetNumDimensions() == 1);
+ BOOST_ASSERT(outputTensorInfo2.GetShape()[0] == 12);
+
+ // Reducing dimensions 0,1 results in a 4 size tensor (one dimension)
+ unsigned int axisShape3[] = { 2 };
+ std::set<unsigned int> axisData3 = { 0, 1 };
+ TensorInfo axisTensorInfo3(1, &axisShape3[0], DataType::Signed32);
+
+ TensorInfo outputTensorInfo3;
+
+ CalculateReducedOutputTensoInfo(inputTensorInfo, axisTensorInfo3, axisData3,
+ keepDims, outputTensorInfo3);
+
+ BOOST_ASSERT(outputTensorInfo3.GetNumDimensions() == 1);
+ BOOST_ASSERT(outputTensorInfo3.GetShape()[0] == 4);
+
+ // Reducing dimension 0 results in a { 1, 3, 4 } dimension tensor
+ keepDims = true;
+ unsigned int axisShape4[] = { 1 };
+ std::set<unsigned int> axisData4 = { 0 };
+ TensorInfo axisTensorInfo4(1, &axisShape4[0], DataType::Signed32);
+
+ TensorInfo outputTensorInfo4;
+
+ CalculateReducedOutputTensoInfo(inputTensorInfo, axisTensorInfo4, axisData4,
+ keepDims, outputTensorInfo4);
+
+ BOOST_ASSERT(outputTensorInfo4.GetNumDimensions() == 3);
+ BOOST_ASSERT(outputTensorInfo4.GetShape()[0] == 1);
+ BOOST_ASSERT(outputTensorInfo4.GetShape()[1] == 3);
+ BOOST_ASSERT(outputTensorInfo4.GetShape()[2] == 4);
+
+ // Reducing dimension 1, 2 results in a { 2, 1, 1 } dimension tensor
+ keepDims = true;
+ unsigned int axisShape5[] = { 2 };
+ std::set<unsigned int> axisData5 = { 1, 2 };
+ TensorInfo axisTensorInfo5(1, &axisShape5[0], DataType::Signed32);
+
+ TensorInfo outputTensorInfo5;
+
+ CalculateReducedOutputTensoInfo(inputTensorInfo, axisTensorInfo5, axisData5,
+ keepDims, outputTensorInfo5);
+
+ BOOST_ASSERT(outputTensorInfo5.GetNumDimensions() == 3);
+ BOOST_ASSERT(outputTensorInfo5.GetShape()[0] == 2);
+ BOOST_ASSERT(outputTensorInfo5.GetShape()[1] == 1);
+ BOOST_ASSERT(outputTensorInfo5.GetShape()[2] == 1);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+