diff --git a/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_exceptions.hpp b/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_exceptions.hpp new file mode 100644 index 00000000000..46fa2be0888 --- /dev/null +++ b/ngraph/frontend/frontend_manager/include/frontend_manager/frontend_exceptions.hpp @@ -0,0 +1,123 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include "frontend_manager_defs.hpp" +#include "ngraph/check.hpp" + +namespace ngraph +{ + namespace frontend + { + class FRONTEND_API GeneralFailure : public CheckFailure + { + public: + GeneralFailure(const CheckLocInfo& check_loc_info, + const std::string& context, + const std::string& explanation) + : CheckFailure(check_loc_info, + "FrontEnd API failed with GeneralFailure: " + context, + explanation) + { + } + }; + + class FRONTEND_API InitializationFailure : public CheckFailure + { + public: + InitializationFailure(const CheckLocInfo& check_loc_info, + const std::string& context, + const std::string& explanation) + : CheckFailure(check_loc_info, + "FrontEnd API failed with InitializationFailure: " + context, + explanation) + { + } + }; + + class FRONTEND_API OpValidationFailure : public CheckFailure + { + public: + OpValidationFailure(const CheckLocInfo& check_loc_info, + const std::string& context, + const std::string& explanation) + : CheckFailure(check_loc_info, + "FrontEnd API failed with OpValidationFailure: " + context, + explanation) + { + } + }; + + class FRONTEND_API OpConversionFailure : public CheckFailure + { + public: + OpConversionFailure(const CheckLocInfo& check_loc_info, + const std::string& context, + const std::string& explanation) + : CheckFailure(check_loc_info, + "FrontEnd API failed with OpConversionFailure: " + context, + explanation) + { + } + }; + + class FRONTEND_API NotImplementedFailure : public CheckFailure + { + public: + NotImplementedFailure(const CheckLocInfo& check_loc_info, + const std::string& context, + const std::string& explanation) + : CheckFailure(check_loc_info, + "FrontEnd API failed with NotImplementedFailure: " + context, + explanation) + { + } + }; + +/// \brief Macro to check whether a boolean condition holds. +/// \param cond Condition to check +/// \param ... Additional error message info to be added to the error message via the `<<` +/// stream-insertion operator. Note that the expressions here will be evaluated lazily, +/// i.e., only if the `cond` evalutes to `false`. +/// \throws ::ngraph::frontend::GeneralFailure if `cond` is false. +#define FRONT_END_GENERAL_CHECK(...) \ + NGRAPH_CHECK_HELPER(::ngraph::frontend::GeneralFailure, "", __VA_ARGS__) + +/// \brief Macro to check whether a boolean condition holds. +/// \param cond Condition to check +/// \param ... Additional error message info to be added to the error message via the `<<` +/// stream-insertion operator. Note that the expressions here will be evaluated lazily, +/// i.e., only if the `cond` evalutes to `false`. +/// \throws ::ngraph::frontend::InitializationFailure if `cond` is false. +#define FRONT_END_INITIALIZATION_CHECK(...) \ + NGRAPH_CHECK_HELPER(::ngraph::frontend::InitializationFailure, "", __VA_ARGS__) + +/// \brief Macro to check whether a boolean condition holds. +/// \param cond Condition to check +/// \param ... Additional error message info to be added to the error message via the `<<` +/// stream-insertion operator. Note that the expressions here will be evaluated lazily, +/// i.e., only if the `cond` evalutes to `false`. +/// \throws ::ngraph::frontend::OpConversionFailure if `cond` is false. +#define FRONT_END_OP_CONVERSION_CHECK(...) \ + NGRAPH_CHECK_HELPER(::ngraph::frontend::OpConversionFailure, "", __VA_ARGS__) + +/// \brief Assert macro. +/// \param NAME Name of the function that is not implemented +/// \throws ::ngraph::frontend::NotImplementedFailure +#define FRONT_END_NOT_IMPLEMENTED(NAME) \ + NGRAPH_CHECK_HELPER(::ngraph::frontend::NotImplementedFailure, \ + "", \ + false, \ + #NAME " is not implemented for this FrontEnd class") + +/// \brief Assert macro. +/// \param MSG Error message +/// \throws ::ngraph::frontend::GeneralFailure +#define FRONT_END_THROW(MSG) FRONT_END_GENERAL_CHECK(false, MSG) + + } // namespace frontend +} // namespace ngraph \ No newline at end of file diff --git a/ngraph/frontend/frontend_manager/src/frontend_manager.cpp b/ngraph/frontend/frontend_manager/src/frontend_manager.cpp index c1a864ffd6e..037a2522523 100644 --- a/ngraph/frontend/frontend_manager/src/frontend_manager.cpp +++ b/ngraph/frontend/frontend_manager/src/frontend_manager.cpp @@ -5,20 +5,13 @@ #include #include +#include "frontend_manager/frontend_exceptions.hpp" #include "frontend_manager/frontend_manager.hpp" #include "plugin_loader.hpp" using namespace ngraph; using namespace ngraph::frontend; -#define FRONT_END_NOT_IMPLEMENTED(NAME) \ - throw std::runtime_error(#NAME " is not implemented for this FrontEnd class") -#define FRONT_END_ASSERT(EXPRESSION) \ - { \ - if (!(EXPRESSION)) \ - throw "AssertionFailed"; \ - } - //----------- FrontEndManager --------------------------- class FrontEndManager::Impl { @@ -32,7 +25,8 @@ public: FrontEnd::Ptr loadByFramework(const std::string& framework, FrontEndCapFlags fec) { - FRONT_END_ASSERT(m_factories.count(framework)) + FRONT_END_INITIALIZATION_CHECK( + m_factories.count(framework), "FrontEnd for Framework ", framework, " is not found"); return m_factories[framework](fec); } diff --git a/ngraph/test/frontend/frontend_manager.cpp b/ngraph/test/frontend/frontend_manager.cpp index 10e8eac8e60..af70885d237 100644 --- a/ngraph/test/frontend/frontend_manager.cpp +++ b/ngraph/test/frontend/frontend_manager.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // +#include #include #include @@ -161,3 +162,150 @@ TEST(FrontEndManagerTest, testDefaultPlace) ASSERT_ANY_THROW(place->is_equal(nullptr)); ASSERT_ANY_THROW(place->is_equal_data(nullptr)); } + +TEST(FrontEndExceptionTest, frontend_general_error_no_throw) +{ + EXPECT_NO_THROW(FRONT_END_GENERAL_CHECK(true)); +} + +TEST(FrontEndExceptionTest, frontend_general_error_no_throw_info) +{ + EXPECT_NO_THROW(FRONT_END_GENERAL_CHECK(true, "msg example")); +} + +TEST(FrontEndExceptionTest, frontend_general_error_throw_no_info) +{ + EXPECT_THROW(FRONT_END_GENERAL_CHECK(false), ngraph::frontend::GeneralFailure); +} + +TEST(FrontEndExceptionTest, frontend_initialization_error_no_throw) +{ + EXPECT_NO_THROW(FRONT_END_INITIALIZATION_CHECK(true)); +} + +TEST(FrontEndExceptionTest, frontend_initialization_error_no_throw_info) +{ + EXPECT_NO_THROW(FRONT_END_INITIALIZATION_CHECK(true, "msg example")); +} + +TEST(FrontEndExceptionTest, frontend_initialization_error_throw_no_info) +{ + EXPECT_THROW(FRONT_END_INITIALIZATION_CHECK(false), ngraph::frontend::InitializationFailure); +} + +TEST(FrontEndExceptionTest, frontend_op_conversion_error_no_throw) +{ + EXPECT_NO_THROW(FRONT_END_OP_CONVERSION_CHECK(true)); +} + +TEST(FrontEndExceptionTest, frontend_op_conversion_error_no_throw_info) +{ + EXPECT_NO_THROW(FRONT_END_OP_CONVERSION_CHECK(true, "msg example")); +} + +TEST(FrontEndExceptionTest, frontend_op_conversion_error_throw_no_info) +{ + EXPECT_THROW(FRONT_END_OP_CONVERSION_CHECK(false), ngraph::frontend::OpConversionFailure); +} + +TEST(FrontEndExceptionTest, frontend_assert_throw_check_info) +{ + std::string msg("msg example"); + try + { + FRONT_END_THROW(msg); + } + catch (const ngraph::frontend::GeneralFailure& ex) + { + std::string caught_msg(ex.what()); + EXPECT_NE(caught_msg.find(msg), std::string::npos); + return; + } + catch (...) + { + FAIL() << "Not expected exception type."; + } + FAIL() << "Test is expected to throw an exception."; +} + +TEST(FrontEndExceptionTest, frontend_not_implemented_throw_check_info) +{ + struct TestClass + { + }; + try + { + FRONT_END_NOT_IMPLEMENTED(TestClass); + } + catch (const ngraph::frontend::NotImplementedFailure& ex) + { + std::string caught_msg(ex.what()); + EXPECT_NE(caught_msg.find("TestClass"), std::string::npos); + return; + } + catch (...) + { + FAIL() << "Not expected exception type."; + } + FAIL() << "Test is expected to throw an exception."; +} + +TEST(FrontEndExceptionTest, frontend_general_error_throw_info) +{ + std::string msg("msg example"); + try + { + FRONT_END_GENERAL_CHECK(false, msg); + } + catch (const ngraph::frontend::GeneralFailure& ex) + { + std::string caught_msg(ex.what()); + EXPECT_NE(caught_msg.find(msg), std::string::npos); + return; + } + catch (...) + { + FAIL() << "Not expected exception type."; + } + FAIL() << "Test is expected to throw an exception."; +} + +TEST(FrontEndExceptionTest, frontend_op_conversion_error_throw_info) +{ + std::string msg("msg example"); + try + { + FRONT_END_OP_CONVERSION_CHECK(false, msg); + } + catch (const ngraph::frontend::OpConversionFailure& ex) + { + std::string caught_msg(ex.what()); + EXPECT_NE(caught_msg.find(msg), std::string::npos); + return; + } + catch (...) + { + FAIL() << "Not expected exception type."; + } + FAIL() << "Test is expected to throw an exception."; +} + +TEST(FrontEndExceptionTest, frontend_initialization_error_throw_info) +{ + std::string msg("msg example"); + try + { + FRONT_END_INITIALIZATION_CHECK(false, msg); + } + catch (const ngraph::frontend::InitializationFailure& ex) + { + std::string caught_msg(ex.what()); + EXPECT_NE(caught_msg.find(msg), std::string::npos); + return; + } + catch (...) + { + FAIL() << "Not expected exception type."; + } + FAIL() << "Test is expected to throw an exception."; +}