From e52bd441e2ff0f09566230ed924c481da8d651d8 Mon Sep 17 00:00:00 2001 From: Mikhail Nosov Date: Thu, 31 Mar 2022 22:23:40 +0300 Subject: [PATCH] Frontend exception safety (#11368) * Frontend exception safety Every call to frontend's API (except Places) can throw exception. If during exception handling, FrontEndManager is destroyed and calls 'dlclose' for plugin - call stack will be corrupted and crash will occur. Solution is to wrap 'plugins' calls with try/catch and throw new exception in 'openvino' context TODO: currently "Place" objects don't have 'actual' wrappers, so exception in 'place' objects will potentially cause such crash (if exception handler destroys FrontEndManager). Workaround for user would be to try/catch any calls of Place API on their side. We're not expecting users to use Place API directly, so this workaround looks acceptable * Add check for exception message * Keep type of frontend exception during rethrow * IR FE tests: don't expect InferenceEngine::exception as it be not propagated as is by FrontEndManager --- src/core/tests/frontend/frontend_manager.cpp | 137 +++++++++++++++ src/core/tests/frontend/mock_frontend.cpp | 160 +++++++++++++++++- src/frontends/common/src/frontend.cpp | 21 ++- src/frontends/common/src/input_model.cpp | 51 +++--- src/frontends/common/src/utils.hpp | 35 ++++ .../partial_shape_deserialization.cpp | 12 +- 6 files changed, 377 insertions(+), 39 deletions(-) diff --git a/src/core/tests/frontend/frontend_manager.cpp b/src/core/tests/frontend/frontend_manager.cpp index 893d7974328..521b590e7bf 100644 --- a/src/core/tests/frontend/frontend_manager.cpp +++ b/src/core/tests/frontend/frontend_manager.cpp @@ -344,3 +344,140 @@ TEST(FrontEndExceptionTest, frontend_initialization_error_throw_info) { } FAIL() << "Test is expected to throw an exception."; } + +// FrontEndManager exception safety +#define CHECK_EXCEPTION_FRONTEND(statement) \ + try { \ + FrontEndManager fem; \ + auto fe = fem.load_by_framework("mock1"); \ + auto input_model = fe->load("throw_next"); \ + statement; \ + FAIL() << "Throw was expected"; \ + } catch (ov::frontend::GeneralFailure & error) { \ + EXPECT_NE(std::string(error.what()).find("Test exception"), std::string::npos) << error.what(); \ + } catch (...) { \ + FAIL() << "Unexpected error is thrown"; \ + } + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Load_By_Framework) { + EXPECT_ANY_THROW({ + FrontEndManager fem; + auto fe = fem.load_by_framework("mock1"); + fe->load("throw_now"); + }); +} + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Convert){CHECK_EXCEPTION_FRONTEND(fe->convert(input_model))} + +TEST(FrontEndManagerTest, + Exception_Safety_FrontEnd_Convert_OV_Model){CHECK_EXCEPTION_FRONTEND(fe->convert(std::shared_ptr()))} + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Get_Name){CHECK_EXCEPTION_FRONTEND(fe->get_name())} + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Supported) { + EXPECT_ANY_THROW({ + FrontEndManager fem; + auto fe = fem.load_by_framework("mock1"); + fe->supported("throw_now"); + }); +} + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Add_Extension){ + CHECK_EXCEPTION_FRONTEND(fe->add_extension(std::make_shared()))} + +TEST(FrontEndManagerTest, + Exception_Safety_FrontEnd_Convert_Partially){CHECK_EXCEPTION_FRONTEND(fe->convert_partially(input_model))} + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Normalize){CHECK_EXCEPTION_FRONTEND(fe->normalize(nullptr))} + +TEST(FrontEndManagerTest, Exception_Safety_FrontEnd_Decode) { + CHECK_EXCEPTION_FRONTEND(fe->decode(input_model)) +} + +// InputModel exception safety + +#define CHECK_EXCEPTION_INPUT_MODEL(statement) \ + try { \ + FrontEndManager fem; \ + auto fe = fem.load_by_framework("mock1"); \ + auto input_model = fe->load("throw_model"); \ + statement; \ + FAIL() << "Throw was expected"; \ + } catch (ov::frontend::GeneralFailure & error) { \ + EXPECT_NE(std::string(error.what()).find("Test exception"), std::string::npos) << error.what(); \ + } catch (...) { \ + FAIL() << "Unexpected error is thrown"; \ + } + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_get_inputs){CHECK_EXCEPTION_INPUT_MODEL(input_model->get_inputs())} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_get_outputs){CHECK_EXCEPTION_INPUT_MODEL(input_model->get_outputs())} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_get_place_by_tensor_name){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->get_place_by_tensor_name({}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_get_place_by_operation_name){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->get_place_by_operation_name({}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_get_place_by_operation_name_and_input_port){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->get_place_by_operation_name_and_input_port({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_get_place_by_operation_name_and_output_port){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->get_place_by_operation_name_and_output_port({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_set_name_for_tensor){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->set_name_for_tensor({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_add_name_for_tensor){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->add_name_for_tensor({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_set_name_for_operation){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->set_name_for_operation({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_free_name_for_tensor){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->free_name_for_tensor({}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_free_name_for_operation){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->free_name_for_operation({}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_set_name_for_dimension){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->set_name_for_dimension({}, {}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_cut_and_add_new_input){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->cut_and_add_new_input({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_cut_and_add_new_output){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->cut_and_add_new_output({}, {}))} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_add_output){CHECK_EXCEPTION_INPUT_MODEL(input_model->add_output({}))} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_remove_output){CHECK_EXCEPTION_INPUT_MODEL(input_model->remove_output({}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_override_all_outputs){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->override_all_outputs({}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_override_all_inputs){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->override_all_inputs({}))} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_extract_subgraph){CHECK_EXCEPTION_INPUT_MODEL(input_model->extract_subgraph({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_set_partial_shape){ + CHECK_EXCEPTION_INPUT_MODEL(input_model->set_partial_shape({}, {}))} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_get_partial_shape){CHECK_EXCEPTION_INPUT_MODEL(input_model->get_partial_shape({}))} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_set_element_type){CHECK_EXCEPTION_INPUT_MODEL(input_model->set_element_type({}, {}))} + +TEST(FrontEndManagerTest, + Exception_Safety_Input_Model_set_tensor_value){CHECK_EXCEPTION_INPUT_MODEL(input_model->set_tensor_value({}, {}))} + +TEST(FrontEndManagerTest, Exception_Safety_Input_Model_set_tensor_partial_value) { + CHECK_EXCEPTION_INPUT_MODEL(input_model->set_tensor_partial_value({}, {}, {})) +} diff --git a/src/core/tests/frontend/mock_frontend.cpp b/src/core/tests/frontend/mock_frontend.cpp index 4248a30da0d..75476c14532 100644 --- a/src/core/tests/frontend/mock_frontend.cpp +++ b/src/core/tests/frontend/mock_frontend.cpp @@ -3,6 +3,7 @@ // #include "ngraph/visibility.hpp" +#include "openvino/frontend/exception.hpp" #include "openvino/frontend/manager.hpp" #include "openvino/frontend/visibility.hpp" #include "openvino/opsets/opset8.hpp" @@ -17,19 +18,174 @@ using namespace ngraph; using namespace ov::frontend; -class InputModelMock : public InputModel {}; +class InputModelMock : public InputModel { +public: + bool m_throw = false; + + std::vector get_inputs() const override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + std::vector get_outputs() const override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + Place::Ptr get_place_by_tensor_name(const std::string& tensor_name) const override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + Place::Ptr get_place_by_operation_name(const std::string& operation_name) const override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + Place::Ptr get_place_by_operation_name_and_input_port(const std::string& operation_name, + int input_port_index) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + Place::Ptr get_place_by_operation_name_and_output_port(const std::string& operation_name, + int output_port_index) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + void set_name_for_tensor(const Place::Ptr& tensor, const std::string& new_name) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void add_name_for_tensor(const Place::Ptr& tensor, const std::string& new_name) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void set_name_for_operation(const Place::Ptr& operation, const std::string& new_name) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void free_name_for_tensor(const std::string& name) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void free_name_for_operation(const std::string& name) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void set_name_for_dimension(const Place::Ptr& place, size_t shape_dim_index, const std::string& dim_name) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void cut_and_add_new_input(const Place::Ptr& place, const std::string& new_name_optional) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void cut_and_add_new_output(const Place::Ptr& place, const std::string& new_name_optional) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + Place::Ptr add_output(const Place::Ptr& place) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + void remove_output(const Place::Ptr& place) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void override_all_outputs(const std::vector& outputs) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void override_all_inputs(const std::vector& inputs) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void extract_subgraph(const std::vector& inputs, const std::vector& outputs) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void set_partial_shape(const Place::Ptr& place, const PartialShape& shape) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + PartialShape get_partial_shape(const Place::Ptr& place) const override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + return {}; + } + + void set_element_type(const Place::Ptr& place, const element::Type& type) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void set_tensor_value(const Place::Ptr& place, const void* value) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } + + void set_tensor_partial_value(const Place::Ptr& place, const void* min_value, const void* max_value) override { + FRONT_END_GENERAL_CHECK(!m_throw, "Test exception"); + } +}; class FrontEndMock : public FrontEnd { + mutable bool m_throw_next{false}; + public: std::string get_name() const override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); return "mock1"; } + bool supported_impl(const std::vector& variants) const override { + if (variants.size() == 1 && variants[0].is()) { + std::string command = variants[0].as(); + FRONT_END_GENERAL_CHECK(command != "throw_now", "Test exception"); + } + return false; + } + + void add_extension(const std::shared_ptr& extension) override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); + } + InputModel::Ptr load_impl(const std::vector& variants) const override { - return std::make_shared(); + auto input_model = std::make_shared(); + if (variants.size() == 1 && variants[0].is()) { + std::string command = variants[0].as(); + if (command == "throw_now") { + OPENVINO_UNREACHABLE("Test throw load input model"); + } else if (command == "throw_next") { + m_throw_next = true; + } else if (command == "throw_model") { + input_model->m_throw = true; + } + } + return input_model; + } + + std::shared_ptr convert_partially(const InputModel::Ptr& model) const override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); + return nullptr; + } + + std::shared_ptr decode(const InputModel::Ptr& model) const override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); + + return nullptr; + } + + void convert(const std::shared_ptr& model) const override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); + } + + void normalize(const std::shared_ptr& model) const override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); } std::shared_ptr convert(const InputModel::Ptr& model) const override { + FRONT_END_GENERAL_CHECK(!m_throw_next, "Test exception"); auto shape = Shape{1, 2, 300, 300}; auto param = std::make_shared(ov::element::f32, shape); std::vector data(ov::shape_size(shape), 1.f); diff --git a/src/frontends/common/src/frontend.cpp b/src/frontends/common/src/frontend.cpp index cbc650ed1f4..14f0d12bc49 100644 --- a/src/frontends/common/src/frontend.cpp +++ b/src/frontends/common/src/frontend.cpp @@ -35,7 +35,7 @@ FrontEnd::~FrontEnd() = default; bool FrontEnd::supported_impl(const std::vector& variants) const { if (m_actual) { - return m_actual->supported_impl(variants); + FRONTEND_RETURN_STATEMENT("Check supported", m_actual->supported_impl(variants)) } return false; } @@ -44,39 +44,42 @@ InputModel::Ptr FrontEnd::load_impl(const std::vector& variants) const FRONT_END_CHECK_IMPLEMENTED(m_actual, load_impl); auto model = std::make_shared(); model->m_shared_object = m_shared_object; - model->m_actual = m_actual->load_impl(variants); + FRONTEND_CALL_STATEMENT("Loading input model", model->m_actual = m_actual->load_impl(variants)) return model; } std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const { FRONT_END_CHECK_IMPLEMENTED(m_actual, convert); - return FrontEnd::create_copy(m_actual->convert(model->m_actual), m_shared_object); + FRONTEND_RETURN_STATEMENT("Converting input model", + FrontEnd::create_copy(m_actual->convert(model->m_actual), m_shared_object)) } void FrontEnd::convert(const std::shared_ptr& model) const { FRONT_END_CHECK_IMPLEMENTED(m_actual, convert); - m_actual->convert(model); + FRONTEND_CALL_STATEMENT("Converting partially converted model", m_actual->convert(model)) } std::shared_ptr FrontEnd::convert_partially(const InputModel::Ptr& model) const { FRONT_END_CHECK_IMPLEMENTED(m_actual, convert_partially); - return FrontEnd::create_copy(m_actual->convert_partially(model->m_actual), m_shared_object); + FRONTEND_RETURN_STATEMENT("Partially convert model", + FrontEnd::create_copy(m_actual->convert_partially(model->m_actual), m_shared_object)) } std::shared_ptr FrontEnd::decode(const InputModel::Ptr& model) const { FRONT_END_CHECK_IMPLEMENTED(m_actual, decode); - return FrontEnd::create_copy(m_actual->decode(model->m_actual), m_shared_object); + FRONTEND_RETURN_STATEMENT("Decoding model", + FrontEnd::create_copy(m_actual->decode(model->m_actual), m_shared_object)) } void FrontEnd::normalize(const std::shared_ptr& model) const { FRONT_END_CHECK_IMPLEMENTED(m_actual, normalize); - m_actual->normalize(model); + FRONTEND_CALL_STATEMENT("Normalizing model", m_actual->normalize(model);) } void FrontEnd::add_extension(const std::shared_ptr& extension) { if (m_actual) { add_extension_to_shared_data(m_shared_object, extension); - m_actual->add_extension(extension); + FRONTEND_CALL_STATEMENT("Adding extension", m_actual->add_extension(extension)) return; } // Left unimplemented intentionally. @@ -103,5 +106,5 @@ std::string FrontEnd::get_name() const { if (!m_actual) { return {}; } - return m_actual->get_name(); + FRONTEND_RETURN_STATEMENT("Getting frontend name", m_actual->get_name();) } diff --git a/src/frontends/common/src/input_model.cpp b/src/frontends/common/src/input_model.cpp index ca37a774720..7a71ceaf6c4 100644 --- a/src/frontends/common/src/input_model.cpp +++ b/src/frontends/common/src/input_model.cpp @@ -16,28 +16,28 @@ std::vector InputModel::get_inputs() const { if (!m_actual) { return {}; } - return m_actual->get_inputs(); + FRONTEND_RETURN_STATEMENT("get_inputs", m_actual->get_inputs()) } std::vector InputModel::get_outputs() const { if (!m_actual) { return {}; } - return m_actual->get_outputs(); + FRONTEND_RETURN_STATEMENT("get_outputs", m_actual->get_outputs()) } Place::Ptr InputModel::get_place_by_tensor_name(const std::string& tensor_name) const { if (!m_actual) { return {}; } - return m_actual->get_place_by_tensor_name(tensor_name); + FRONTEND_RETURN_STATEMENT("get_place_by_tensor_name", m_actual->get_place_by_tensor_name(tensor_name)) } Place::Ptr InputModel::get_place_by_operation_name(const std::string& operation_name) const { if (!m_actual) { return {}; } - return m_actual->get_place_by_operation_name(operation_name); + FRONTEND_RETURN_STATEMENT("get_place_by_operation_name", m_actual->get_place_by_operation_name(operation_name)) } Place::Ptr InputModel::get_place_by_operation_name_and_input_port(const std::string& operation_name, @@ -45,7 +45,8 @@ Place::Ptr InputModel::get_place_by_operation_name_and_input_port(const std::str if (!m_actual) { return {}; } - return m_actual->get_place_by_operation_name_and_input_port(operation_name, input_port_index); + FRONTEND_RETURN_STATEMENT("get_place_by_operation_name_and_input_port", + m_actual->get_place_by_operation_name_and_input_port(operation_name, input_port_index)) } Place::Ptr InputModel::get_place_by_operation_name_and_output_port(const std::string& operation_name, @@ -53,96 +54,98 @@ Place::Ptr InputModel::get_place_by_operation_name_and_output_port(const std::st if (!m_actual) { return {}; } - return m_actual->get_place_by_operation_name_and_output_port(operation_name, output_port_index); + FRONTEND_RETURN_STATEMENT("get_place_by_operation_name_and_output_port", + m_actual->get_place_by_operation_name_and_output_port(operation_name, output_port_index)) } void InputModel::set_name_for_tensor(const Place::Ptr& tensor, const std::string& new_name) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_name_for_tensor); - m_actual->set_name_for_tensor(tensor, new_name); + FRONTEND_CALL_STATEMENT("set_name_for_tensor", m_actual->set_name_for_tensor(tensor, new_name)) } void InputModel::add_name_for_tensor(const Place::Ptr& tensor, const std::string& new_name) { FRONT_END_CHECK_IMPLEMENTED(m_actual, add_name_for_tensor); - m_actual->add_name_for_tensor(tensor, new_name); + FRONTEND_CALL_STATEMENT("add_name_for_tensor", m_actual->add_name_for_tensor(tensor, new_name)) } void InputModel::set_name_for_operation(const Place::Ptr& operation, const std::string& new_name) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_name_for_operation); - m_actual->set_name_for_operation(operation, new_name); + FRONTEND_CALL_STATEMENT("set_name_for_operation", m_actual->set_name_for_operation(operation, new_name)) } void InputModel::free_name_for_tensor(const std::string& name) { FRONT_END_CHECK_IMPLEMENTED(m_actual, free_name_for_tensor); - m_actual->free_name_for_tensor(name); + FRONTEND_CALL_STATEMENT("free_name_for_tensor", m_actual->free_name_for_tensor(name)) } void InputModel::free_name_for_operation(const std::string& name) { FRONT_END_CHECK_IMPLEMENTED(m_actual, free_name_for_operation); - m_actual->free_name_for_operation(name); + FRONTEND_CALL_STATEMENT("free_name_for_operation", m_actual->free_name_for_operation(name)) } void InputModel::set_name_for_dimension(const Place::Ptr& place, size_t shape_dim_index, const std::string& dim_name) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_name_for_dimension); - m_actual->set_name_for_dimension(place, shape_dim_index, dim_name); + FRONTEND_CALL_STATEMENT("set_name_for_dimension", + m_actual->set_name_for_dimension(place, shape_dim_index, dim_name)) } void InputModel::cut_and_add_new_input(const Place::Ptr& place, const std::string& new_name_optional) { FRONT_END_CHECK_IMPLEMENTED(m_actual, cut_and_add_new_input); - m_actual->cut_and_add_new_input(place, new_name_optional); + FRONTEND_CALL_STATEMENT("cut_and_add_new_input", m_actual->cut_and_add_new_input(place, new_name_optional)) } void InputModel::cut_and_add_new_output(const Place::Ptr& place, const std::string& new_name_optional) { FRONT_END_CHECK_IMPLEMENTED(m_actual, cut_and_add_new_output); - m_actual->cut_and_add_new_output(place, new_name_optional); + FRONTEND_CALL_STATEMENT("cut_and_add_new_output", m_actual->cut_and_add_new_output(place, new_name_optional)) } Place::Ptr InputModel::add_output(const Place::Ptr& place) { FRONT_END_CHECK_IMPLEMENTED(m_actual, add_output); - return m_actual->add_output(place); + FRONTEND_RETURN_STATEMENT("add_output", m_actual->add_output(place)) } void InputModel::remove_output(const Place::Ptr& place) { FRONT_END_CHECK_IMPLEMENTED(m_actual, remove_output); - m_actual->remove_output(place); + FRONTEND_CALL_STATEMENT("remove_output", m_actual->remove_output(place)) } void InputModel::override_all_outputs(const std::vector& outputs) { FRONT_END_CHECK_IMPLEMENTED(m_actual, override_all_outputs); - m_actual->override_all_outputs(outputs); + FRONTEND_CALL_STATEMENT("override_all_outputs", m_actual->override_all_outputs(outputs)) } void InputModel::override_all_inputs(const std::vector& inputs) { FRONT_END_CHECK_IMPLEMENTED(m_actual, override_all_inputs); - m_actual->override_all_inputs(inputs); + FRONTEND_CALL_STATEMENT("override_all_inputs", m_actual->override_all_inputs(inputs)) } void InputModel::extract_subgraph(const std::vector& inputs, const std::vector& outputs) { FRONT_END_CHECK_IMPLEMENTED(m_actual, extract_subgraph); - m_actual->extract_subgraph(inputs, outputs); + FRONTEND_CALL_STATEMENT("extract_subgraph", m_actual->extract_subgraph(inputs, outputs)) } // Setting tensor properties void InputModel::set_partial_shape(const Place::Ptr& place, const PartialShape& shape) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_partial_shape); - m_actual->set_partial_shape(place, shape); + FRONTEND_CALL_STATEMENT("set_partial_shape", m_actual->set_partial_shape(place, shape)) } PartialShape InputModel::get_partial_shape(const Place::Ptr& place) const { FRONT_END_CHECK_IMPLEMENTED(m_actual, get_partial_shape); - return m_actual->get_partial_shape(place); + FRONTEND_RETURN_STATEMENT("get_partial_shape", m_actual->get_partial_shape(place)) } void InputModel::set_element_type(const Place::Ptr& place, const element::Type& type) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_element_type); - m_actual->set_element_type(place, type); + FRONTEND_CALL_STATEMENT("set_element_type", m_actual->set_element_type(place, type)) } void InputModel::set_tensor_value(const Place::Ptr& place, const void* value) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_tensor_value); - m_actual->set_tensor_value(place, value); + FRONTEND_CALL_STATEMENT("set_tensor_value", m_actual->set_tensor_value(place, value)) } void InputModel::set_tensor_partial_value(const Place::Ptr& place, const void* min_value, const void* max_value) { FRONT_END_CHECK_IMPLEMENTED(m_actual, set_tensor_partial_value); - m_actual->set_tensor_partial_value(place, min_value, max_value); + FRONTEND_CALL_STATEMENT("set_tensor_partial_value", m_actual->set_tensor_partial_value(place, min_value, max_value)) } diff --git a/src/frontends/common/src/utils.hpp b/src/frontends/common/src/utils.hpp index 9256c55de08..4464af632a4 100644 --- a/src/frontends/common/src/utils.hpp +++ b/src/frontends/common/src/utils.hpp @@ -6,6 +6,41 @@ #include "openvino/frontend/visibility.hpp" +#define RETHROW_FRONTEND_EXCEPTION(Type) \ + catch (const Type& ex) { \ + throw Type(ex); \ + } + +#define FRONTEND_CALL_STATEMENT(MESSAGE, ...) \ + try { \ + __VA_ARGS__; \ + } \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::GeneralFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::OpValidationFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::InitializationFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::OpConversionFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::NotImplementedFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::AssertFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::Exception) \ + catch (...) { \ + OPENVINO_ASSERT(false, (MESSAGE)); \ + } + +#define FRONTEND_RETURN_STATEMENT(MESSAGE, FUNCTION) \ + try { \ + return FUNCTION; \ + } \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::GeneralFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::OpValidationFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::InitializationFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::OpConversionFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::frontend::NotImplementedFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::AssertFailure) \ + RETHROW_FRONTEND_EXCEPTION(ov::Exception) \ + catch (...) { \ + OPENVINO_ASSERT(false, (MESSAGE)); \ + } + namespace ov { namespace frontend { std::string get_frontend_library_path(); diff --git a/src/tests/functional/inference_engine/ir_serialization/partial_shape_deserialization.cpp b/src/tests/functional/inference_engine/ir_serialization/partial_shape_deserialization.cpp index a51e55ad3aa..6d0944e2297 100644 --- a/src/tests/functional/inference_engine/ir_serialization/partial_shape_deserialization.cpp +++ b/src/tests/functional/inference_engine/ir_serialization/partial_shape_deserialization.cpp @@ -296,7 +296,8 @@ TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestDynamicRankNegative) )V0G0N"; - ASSERT_THROW(getWithIRFrontend(model), InferenceEngine::Exception); + // TODO: change to ov::Exception (69781) + ASSERT_ANY_THROW(getWithIRFrontend(model)); } TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestDynamicDimNegative) { @@ -322,7 +323,8 @@ TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestDynamicDimNegative) { )V0G0N"; - ASSERT_THROW(getWithIRFrontend(model), InferenceEngine::Exception); + // TODO: change to ov::Exception (69781) + ASSERT_ANY_THROW(getWithIRFrontend(model)); } TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestWrongDim) { @@ -348,7 +350,8 @@ TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestWrongDim) { )V0G0N"; - ASSERT_THROW(getWithIRFrontend(model), InferenceEngine::Exception); + // TODO: change to ov::Exception (69781) + ASSERT_ANY_THROW(getWithIRFrontend(model)); } TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestWrongBoundary) { @@ -374,5 +377,6 @@ TEST_F(PartialShapeDeserialization, ShapeWithBoundariesTestWrongBoundary) { )V0G0N"; - ASSERT_THROW(getWithIRFrontend(model), InferenceEngine::Exception); + // TODO: change to ov::Exception (69781) + ASSERT_ANY_THROW(getWithIRFrontend(model)); }