Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CAPI] add ov_get_last_error_msg() API #20643

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/bindings/c/include/openvino/c/ov_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,10 @@ 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
*/
OPENVINO_C_API(const char*)
ov_get_last_err_msg();
12 changes: 8 additions & 4 deletions src/bindings/c/src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
#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&) { \
catch (const ov::ExceptionType& ex) { \
dup_last_err_msg(ex.what()); \
return ov_status_e::StatusCode; \
}

Expand All @@ -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; \
}

Expand Down Expand Up @@ -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);
riverlijunjie marked this conversation as resolved.
Show resolved Hide resolved
23 changes: 23 additions & 0 deletions src/bindings/c/src/ov_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ char* str_to_char_array(const std::string& str) {
return char_array;
}

static char* last_err_msg = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to store last_err_msg as std::string and convert to char* directly in ov_get_last_err_msg()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the string contents will be lost if store exception.what() into std::string variable:
static std::string last_err_msg ; last_err_msg = std::string(ex.what())

Maybe there is some mistake why the content has been lost in std::string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the content lost issue and use std::string, thank your suggestion! @vurusovs

static std::mutex last_msg_mutex;
void dup_last_err_msg(const std::string msg) {
vurusovs marked this conversation as resolved.
Show resolved Hide resolved
std::lock_guard<std::mutex> 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<std::mutex> 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;
Expand Down Expand Up @@ -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<std::mutex> 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,
Expand Down
34 changes: 34 additions & 0 deletions src/bindings/c/tests/ov_core_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ov_core_test : public ov_capi_test_base {
ov_capi_test_base::TearDown();
}
};

INSTANTIATE_TEST_SUITE_P(ov_core, ov_core_test, ::testing::Values("CPU"));

TEST_P(ov_core_test, ov_core_create_with_config) {
Expand Down Expand Up @@ -699,4 +700,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
Loading