From 2fb3e7170f6b2bb57245312766210c46b96edff8 Mon Sep 17 00:00:00 2001 From: "River.Li" Date: Fri, 20 Oct 2023 14:21:38 +0800 Subject: [PATCH] [CAPI] add ov_get_last_error_msg() API --- src/bindings/c/include/openvino/c/ov_common.h | 8 +++++ src/bindings/c/src/common.h | 16 +++++---- src/bindings/c/src/ov_core.cpp | 23 ++++++++++++ src/bindings/c/tests/ov_core_test.cpp | 35 ++++++++++++++++++- 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/bindings/c/include/openvino/c/ov_common.h b/src/bindings/c/include/openvino/c/ov_common.h index faf9369050c839..2846f91c8666ba 100644 --- a/src/bindings/c/include/openvino/c/ov_common.h +++ b/src/bindings/c/include/openvino/c/ov_common.h @@ -204,3 +204,11 @@ ov_get_error_info(ov_status_e status); */ OPENVINO_C_API(void) ov_free(const char* content); + +/** + * @brief Get the last error msg. + * @ingroup ov_base_c_api + * @param none. + */ +OPENVINO_C_API(const char*) +ov_get_last_err_msg(); \ No newline at end of file diff --git a/src/bindings/c/src/common.h b/src/bindings/c/src/common.h index ff2e0bcac07312..cc047669aef793 100644 --- a/src/bindings/c/src/common.h +++ b/src/bindings/c/src/common.h @@ -14,14 +14,16 @@ #include "openvino/core/except.hpp" #include "openvino/openvino.hpp" -#define CATCH_IE_EXCEPTION(StatusCode, ExceptionType) \ - catch (const InferenceEngine::ExceptionType&) { \ - return ov_status_e::StatusCode; \ +#define CATCH_IE_EXCEPTION(StatusCode, ExceptionType) \ + catch (const InferenceEngine::ExceptionType& ex) { \ + dup_last_err_msg(ex.what()); \ + return ov_status_e::StatusCode; \ } -#define CATCH_OV_EXCEPTION(StatusCode, ExceptionType) \ - catch (const ov::ExceptionType&) { \ - return ov_status_e::StatusCode; \ +#define CATCH_OV_EXCEPTION(StatusCode, ExceptionType) \ + catch (const ov::ExceptionType& ex) { \ + dup_last_err_msg(ex.what()); \ + return ov_status_e::StatusCode; \ } #define CATCH_OV_EXCEPTIONS \ @@ -41,6 +43,7 @@ CATCH_IE_EXCEPTION(NETWORK_NOT_READ, NetworkNotRead) \ CATCH_IE_EXCEPTION(INFER_CANCELLED, InferCancelled) \ catch (...) { \ + dup_last_err_msg("An unknown exception occurred"); \ return ov_status_e::UNKNOW_EXCEPTION; \ } @@ -224,3 +227,4 @@ struct mem_istream : virtual mem_stringbuf, std::istream { char* str_to_char_array(const std::string& str); ov::element::Type get_element_type(ov_element_type_e type); +void dup_last_err_msg(const std::string msg); diff --git a/src/bindings/c/src/ov_core.cpp b/src/bindings/c/src/ov_core.cpp index 6e292dc7abf331..eca574db45b34f 100644 --- a/src/bindings/c/src/ov_core.cpp +++ b/src/bindings/c/src/ov_core.cpp @@ -17,6 +17,24 @@ char* str_to_char_array(const std::string& str) { return char_array; } +static char* last_err_msg = nullptr; +static std::mutex last_msg_mutex; +inline void dup_last_err_msg(const std::string msg) { + std::lock_guard lock(last_msg_mutex); + ov_free(last_err_msg); + last_err_msg = str_to_char_array(msg); +} + +const char* ov_get_last_err_msg() { + std::lock_guard lock(last_msg_mutex); + char* res = nullptr; + if (last_err_msg) + res = str_to_char_array(std::string(last_err_msg)); + ov_free(last_err_msg); + last_err_msg = nullptr; + return res; +} + ov_status_e ov_get_openvino_version(ov_version_t* version) { if (!version) { return ov_status_e::INVALID_C_PARAM; @@ -66,6 +84,11 @@ ov_status_e ov_core_create(ov_core_t** core) { void ov_core_free(ov_core_t* core) { if (core) delete core; + + // release err msg buffer, there will be no err msg after core is freed. + std::lock_guard lock(last_msg_mutex); + ov_free(last_err_msg); + last_err_msg = nullptr; } ov_status_e ov_core_read_model(const ov_core_t* core, diff --git a/src/bindings/c/tests/ov_core_test.cpp b/src/bindings/c/tests/ov_core_test.cpp index f6203da682ff97..e33f771b0c2366 100644 --- a/src/bindings/c/tests/ov_core_test.cpp +++ b/src/bindings/c/tests/ov_core_test.cpp @@ -33,7 +33,7 @@ class ov_core_test : public ov_capi_test_base { ov_capi_test_base::TearDown(); } }; -INSTANTIATE_TEST_SUITE_P(device_name, ov_core_test, ::testing::Values("CPU")); +INSTANTIATE_TEST_SUITE_P(ov_capi_test, ov_core_test, ::testing::Values("CPU")); TEST_P(ov_core_test, ov_core_create_with_config) { std::string plugins_xml = TestDataHelpers::generate_test_xml_file(); @@ -699,4 +699,37 @@ TEST_P(ov_core_test, ov_core_compile_model_from_file_unicode) { } #endif +using ov_util_test = ov_core_test; +INSTANTIATE_TEST_SUITE_P(ov_capi_test, ov_util_test, ::testing::Values("CPU")); + +TEST_P(ov_util_test, ov_get_last_err_msg_check) { + auto device_name = GetParam(); + ov_core_t* core = nullptr; + OV_EXPECT_OK(ov_core_create(&core)); + EXPECT_NE(nullptr, core); + + const char* key = ov_property_key_inference_num_threads; + OV_EXPECT_OK(ov_core_set_property(core, device_name.c_str(), key, "abc")); + + char* ret = nullptr; + OV_EXPECT_NOT_OK(ov_core_get_property(core, device_name.c_str(), key, &ret)); + + auto err_msg = ov_get_last_err_msg(); + EXPECT_NE(nullptr, err_msg); + ov_free(err_msg); + ov_free(ret); + ov_core_free(core); +} + +TEST_P(ov_util_test, ov_get_last_err_msg_check_empty_msg) { + auto device_name = GetParam(); + ov_core_t* core = nullptr; + OV_EXPECT_OK(ov_core_create(&core)); + EXPECT_NE(nullptr, core); + + auto err_msg = ov_get_last_err_msg(); + EXPECT_EQ(nullptr, err_msg); + ov_core_free(core); +} + } // namespace