Update reshape to restore original shapes if reshape has failed (#5681)

* Update reshape not to throw an exception; restore parameters shape if reshape was wrong

* Early exit

* Fix test
This commit is contained in:
Gleb Kazantaev 2021-05-20 11:19:46 +03:00 committed by GitHub
parent cdc98d7286
commit 1f0381e2b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 21 deletions

View File

@ -325,29 +325,43 @@ void CNNNetworkNGraphImpl::reshape() {
StatusCode
CNNNetworkNGraphImpl::reshape(const std::map<std::string, std::vector<size_t>>& inputShapes,
ResponseDesc* responseDesc) noexcept {
if (inputShapes.empty()) return OK;
const auto & params = _ngraph_function->get_parameters();
// Check that we need to do reshape only if input shapes will be changed
bool needReshape = false;
for (const auto & param : params) {
const auto it = inputShapes.find(param->get_friendly_name());
if (it == inputShapes.end()) {
continue;
}
if (param->get_partial_shape().is_dynamic() || param->get_shape() != it->second) {
needReshape = true;
break;
}
}
if (!needReshape) return OK;
// save original parameters shape
std::map<std::string, ngraph::PartialShape> originalInputShapes;
for (const auto & param : params) {
originalInputShapes[param->get_friendly_name()] = param->get_partial_shape();
}
try {
auto params = _ngraph_function->get_parameters();
ngraph::pass::Manager ssr_manager;
ssr_manager.register_pass<ngraph::pass::SmartReshape>();
ssr_manager.run_passes(_ngraph_function);
// Check that we need to do reshape only if input shapes will be changed
bool needReshape = false;
for (size_t i = 0; i < params.size() && !inputShapes.empty(); i++) {
const auto& param = params[i];
auto it = inputShapes.find(param->get_friendly_name());
if (it == inputShapes.end())
continue;
if (param->get_partial_shape().is_dynamic() || param->get_shape() != it->second) {
needReshape = true;
break;
}
}
if (needReshape) {
ngraph::pass::Manager ssr_manager;
ssr_manager.register_pass<ngraph::pass::SmartReshape>();
ssr_manager.run_passes(_ngraph_function);
reshape(inputShapes);
std::map<std::string, ngraph::PartialShape> reshapeShapes;
for (const auto & item : inputShapes) {
reshapeShapes[item.first] = ngraph::PartialShape(item.second);
}
reshape(reshapeShapes);
} catch (std::exception& ex) {
reshape(originalInputShapes);
return DescriptionBuffer(GENERAL_ERROR, responseDesc) << ex.what();
}
@ -355,7 +369,7 @@ CNNNetworkNGraphImpl::reshape(const std::map<std::string, std::vector<size_t>>&
}
void
CNNNetworkNGraphImpl::reshape(const std::map<std::string, std::vector<size_t>>& inputShapes) {
CNNNetworkNGraphImpl::reshape(const std::map<std::string, ngraph::PartialShape>& inputShapes) {
OV_ITT_SCOPED_TASK(itt::domains::IE, "CNNNetworkNGraphImpl::reshape");
auto params = _ngraph_function->get_parameters();

View File

@ -104,7 +104,7 @@ private:
* @brief Reshape on the same shape
*/
void reshape();
void reshape(const std::map<std::string, std::vector<size_t>>& inputShapes);
void reshape(const std::map<std::string, ngraph::PartialShape>& inputShapes);
void validateFunctionNames() const;
};
} // namespace details

View File

@ -42,6 +42,39 @@
using namespace testing;
using namespace InferenceEngine;
TEST(CNNNGraphImplTests, TestReshapeWithSameShape) {
std::shared_ptr<ngraph::Function> f;
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 1000, 4});
input->set_friendly_name("input");
auto shape = ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {1, 4000});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, shape, true);
f = std::make_shared<ngraph::Function>(ngraph::OutputVector{reshape}, ngraph::ParameterVector{input});
}
auto net = InferenceEngine::CNNNetwork(f);
ASSERT_NO_THROW(net.reshape({{"input", SizeVector({1, 4000})}}));
}
TEST(CNNNGraphImplTests, TestInvalidReshape) {
std::shared_ptr<ngraph::Function> f;
{
auto input = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::f32, ngraph::Shape{1, 1000, 4});
input->set_friendly_name("input");
auto shape = ngraph::opset5::Constant::create(ngraph::element::i64, {2}, {1, 4000});
auto reshape = std::make_shared<ngraph::opset5::Reshape>(input, shape, true);
f = std::make_shared<ngraph::Function>(ngraph::OutputVector{reshape}, ngraph::ParameterVector{input});
}
auto net = InferenceEngine::CNNNetwork(f);
ASSERT_ANY_THROW(net.reshape({{"input", SizeVector({4})}}));
auto param = *net.getFunction()->get_parameters().begin();
ASSERT_EQ(param->get_output_shape(0), ngraph::Shape({1, 1000, 4}));
ASSERT_NO_THROW(net.reshape({{"input", SizeVector({1, 1000, 4})}}));
}
IE_SUPPRESS_DEPRECATED_START
TEST(CNNNGraphImplTests, TestNMS5OutputNames) {