[NG Frontend] Frontend exceptions (#5993)

* [NG Frontend] Introduce classes and macros for Frontend-specific exceptions

* Add FrontEnd exception unit tests

* resolve review comments

* Import FE exception classes

* code style

Co-authored-by: Ivan Tikhonov <ivan.tikhonov@intel.com>
This commit is contained in:
Mikhail Nosov 2021-06-11 07:14:36 +03:00 committed by GitHub
parent 14e486b767
commit 05469e95e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 274 additions and 9 deletions

View File

@ -0,0 +1,123 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <memory>
#include <string>
#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

View File

@ -5,20 +5,13 @@
#include <ngraph/env_util.hpp> #include <ngraph/env_util.hpp>
#include <ngraph/except.hpp> #include <ngraph/except.hpp>
#include "frontend_manager/frontend_exceptions.hpp"
#include "frontend_manager/frontend_manager.hpp" #include "frontend_manager/frontend_manager.hpp"
#include "plugin_loader.hpp" #include "plugin_loader.hpp"
using namespace ngraph; using namespace ngraph;
using namespace ngraph::frontend; 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 --------------------------- //----------- FrontEndManager ---------------------------
class FrontEndManager::Impl class FrontEndManager::Impl
{ {
@ -32,7 +25,8 @@ public:
FrontEnd::Ptr loadByFramework(const std::string& framework, FrontEndCapFlags fec) 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); return m_factories[framework](fec);
} }

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
#include <frontend_manager/frontend_exceptions.hpp>
#include <frontend_manager/frontend_manager.hpp> #include <frontend_manager/frontend_manager.hpp>
#include <memory> #include <memory>
@ -161,3 +162,150 @@ TEST(FrontEndManagerTest, testDefaultPlace)
ASSERT_ANY_THROW(place->is_equal(nullptr)); ASSERT_ANY_THROW(place->is_equal(nullptr));
ASSERT_ANY_THROW(place->is_equal_data(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.";
}