aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorColm Donelan <Colm.Donelan@arm.com>2020-06-09 16:56:25 +0100
committerColm Donelan <Colm.Donelan@arm.com>2020-06-09 16:56:46 +0100
commit6350d27286114dfdae5f65ae1823ba1150087efb (patch)
treeb2941db6a0d1cfff1bdb9005e1a7b1c1c3149844 /src
parentb22a75e2aaec1175bbacba54e1a33a83f9749ce2 (diff)
downloadarmnn-6350d27286114dfdae5f65ae1823ba1150087efb.tar.gz
IVGCVSW-4968 Fix exception handling in TfLiteParser.
* The function TfLiteParser::CreateNetworkFromModel was continuing to parse the input file even after a fatal exception was encountered. restructure catch exceptions outside the for loop. * Add simple unit tests to test some exception handling. Signed-off-by: Colm Donelan <Colm.Donelan@arm.com> Change-Id: I202ca6819d40a47159b4ac8f2847958f945666c2
Diffstat (limited to 'src')
-rw-r--r--src/armnnTfLiteParser/TfLiteParser.cpp66
-rw-r--r--src/armnnTfLiteParser/test/TfLiteParser.cpp41
2 files changed, 66 insertions, 41 deletions
diff --git a/src/armnnTfLiteParser/TfLiteParser.cpp b/src/armnnTfLiteParser/TfLiteParser.cpp
index c695caa280..1737da8616 100644
--- a/src/armnnTfLiteParser/TfLiteParser.cpp
+++ b/src/armnnTfLiteParser/TfLiteParser.cpp
@@ -619,9 +619,6 @@ INetworkPtr TfLiteParser::CreateNetworkFromModel()
m_Network = INetwork::Create();
ARMNN_ASSERT(m_Model.get() != nullptr);
- bool failedToCreate = false;
- std::stringstream errors;
-
if (m_Model->subgraphs.size() != 1)
{
throw ParseException(
@@ -632,65 +629,52 @@ INetworkPtr TfLiteParser::CreateNetworkFromModel()
}
size_t subgraphIndex = 0;
- for (SubgraphPtr const & subgraph : m_Model->subgraphs)
+ size_t operatorIndex = 0;
+ try
{
- m_SubgraphConnections.emplace_back(subgraph->tensors.size());
-
- size_t operatorIndex = 0;
- for (OperatorPtr const & op : subgraph->operators)
+ for (SubgraphPtr const& subgraph : m_Model->subgraphs)
{
- try
+ m_SubgraphConnections.emplace_back(subgraph->tensors.size());
+ for (OperatorPtr const& op : subgraph->operators)
{
- auto const & opCodePtr = m_Model->operator_codes[op->opcode_index];
+ auto const& opCodePtr = m_Model->operator_codes[op->opcode_index];
auto builtinCode = opCodePtr->builtin_code;
if (builtinCode > tflite::BuiltinOperator_MAX)
{
- throw ParseException(
- boost::str(
- boost::format("Operator code %1% is out of range 0-%2%. "
- "subgraph:%3% operator idx:%4%. %5%") %
- builtinCode %
- tflite::BuiltinOperator_MAX %
- subgraphIndex %
- operatorIndex %
- CHECK_LOCATION().AsString()));
+ throw ParseException(boost::str(boost::format("Operator code %1% is out of range 0-%2%. "
+ "subgraph:%3% operator idx:%4%. %5%") %
+ builtinCode % tflite::BuiltinOperator_MAX % subgraphIndex %
+ operatorIndex % CHECK_LOCATION().AsString()));
}
// lookup and call the parser function
- auto & parserFunction = m_ParserFunctions[builtinCode];
+ auto& parserFunction = m_ParserFunctions[builtinCode];
(this->*parserFunction)(subgraphIndex, operatorIndex);
+ ++operatorIndex;
}
- catch (const ParseException& e)
- {
- failedToCreate = true;
- std::stringstream errorString;
- errorString << "Failed to parse operator #" << operatorIndex
- << " within subgraph #" << subgraphIndex
- << " error: " << e.what();
- ARMNN_LOG(error) << errorString.str();
+ SetupInputLayers(subgraphIndex);
+ SetupOutputLayers(subgraphIndex);
+ SetupConstantLayers(subgraphIndex);
- errors << errorString.str() << "\n";
- }
- ++operatorIndex;
+ ++subgraphIndex;
+ operatorIndex = 0;
}
-
- SetupInputLayers(subgraphIndex);
- SetupOutputLayers(subgraphIndex);
- SetupConstantLayers(subgraphIndex);
-
- ++subgraphIndex;
}
-
- if (failedToCreate)
+ catch (const ParseException& e)
{
- // we can skip everything and let the outer exception handler deal with the error
+ std::stringstream errorString;
+ errorString << "Failed to parse operator #" << operatorIndex << " within subgraph #"
+ << subgraphIndex << " error: " << e.what();
+ ARMNN_LOG(error) << errorString.str();
+ std::stringstream errors;
+ errors << errorString.str() << "\n";
throw ParseException(errors.str());
}
// establish the connections from the layer outputs to the inputs of the subsequent layers
- for (size_t subgraphIndex = 0; subgraphIndex < m_SubgraphConnections.size(); ++subgraphIndex)
+ for (subgraphIndex = 0; subgraphIndex < m_SubgraphConnections.size(); ++subgraphIndex)
{
for (size_t tensorIndex = 0; tensorIndex < m_SubgraphConnections[subgraphIndex].size(); ++tensorIndex)
{
diff --git a/src/armnnTfLiteParser/test/TfLiteParser.cpp b/src/armnnTfLiteParser/test/TfLiteParser.cpp
new file mode 100644
index 0000000000..36827c0586
--- /dev/null
+++ b/src/armnnTfLiteParser/test/TfLiteParser.cpp
@@ -0,0 +1,41 @@
+//
+// Copyright © 2020 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <boost/test/unit_test.hpp>
+#include "ParserFlatbuffersFixture.hpp"
+#include "../TfLiteParser.hpp"
+
+BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
+
+BOOST_AUTO_TEST_CASE(ParseEmptyBinaryData)
+{
+ ITfLiteParser::TfLiteParserOptions options;
+ ITfLiteParserPtr m_Parser(ITfLiteParser::Create(armnn::Optional<ITfLiteParser::TfLiteParserOptions>(options)));
+ // Should throw armnn::ParseException: Buffer doesn't conform to the expected Tensorflow Lite flatbuffers format.
+ BOOST_CHECK_THROW(m_Parser->CreateNetworkFromBinary({0}), armnn::ParseException);
+}
+
+struct NoInputBindingsFixture : public ParserFlatbuffersFixture
+{
+ explicit NoInputBindingsFixture()
+ {
+ m_JsonString = R"(
+ {
+ "version": 3,
+ "operator_codes": [ { "builtin_code": "CONV_2D" } ],
+ "subgraphs": [ { } ]
+ }
+ )";
+ SetupSingleInputSingleOutput("inputTensor", "outputTensor");
+ }
+};
+
+BOOST_FIXTURE_TEST_CASE( ParseBadInputBindings, NoInputBindingsFixture )
+{
+ // Should throw armnn::ParseException: No input binding found for subgraph:0 and name:inputTensor.
+ BOOST_CHECK_THROW( (RunTest<4, armnn::DataType::QAsymmU8>(0, { }, { 0 })), armnn::ParseException);
+}
+
+BOOST_AUTO_TEST_SUITE_END()