From 2cfd2598243e06339031559eb8908a73d19e8a3a Mon Sep 17 00:00:00 2001 From: Pawel Raasz Date: Thu, 13 Jul 2023 11:42:01 +0200 Subject: [PATCH] [core]Trim `__FILE__` macro by compiler if supported (#18411) * Trim __FILE__ macro by compiler if supported * Use file for older version cmake Debug messages * Move trim compilation options to os_flags.cmake * Fix MSVC trimming options * Add additional trim on runtime * Update trim function description * Use ov implementation for ngraph::trim_file_name * Restore ie_c_api.h * Remove unused define * MSVC add trim for CXX language --- .../compile_flags/os_flags.cmake | 37 ++++++++- src/CMakeLists.txt | 1 - .../include/openvino/util/const_string.hpp | 45 +++++++++++ .../util/include/openvino/util/file_util.hpp | 16 ++++ src/common/util/include/openvino/util/log.hpp | 78 +++++-------------- src/common/util/src/file_util.cpp | 7 ++ src/common/util/src/log.cpp | 4 +- src/core/include/ngraph/log.hpp | 49 ++++++------ src/core/src/except.cpp | 18 ++--- src/core/src/log.cpp | 7 ++ src/core/tests/check.cpp | 8 ++ src/core/tests/file_util.cpp | 46 +++++++++++ 12 files changed, 215 insertions(+), 101 deletions(-) create mode 100644 src/common/util/include/openvino/util/const_string.hpp diff --git a/cmake/developer_package/compile_flags/os_flags.cmake b/cmake/developer_package/compile_flags/os_flags.cmake index f7641a7b96d..fd7a389e1af 100644 --- a/cmake/developer_package/compile_flags/os_flags.cmake +++ b/cmake/developer_package/compile_flags/os_flags.cmake @@ -266,7 +266,7 @@ function(ov_abi_free_target target) endif() endfunction() -# +# # ie_python_minimal_api() # # Set options to use only Python Limited API @@ -318,6 +318,18 @@ elseif(CMAKE_COMPILER_IS_GNUCXX OR OV_COMPILER_IS_CLANG) ie_add_compiler_flags(-fsigned-char) endif() +file(RELATIVE_PATH OV_RELATIVE_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + +if(${CMAKE_VERSION} VERSION_LESS "3.20") + file(TO_NATIVE_PATH ${OpenVINO_SOURCE_DIR} OV_NATIVE_PROJECT_ROOT_DIR) + file(TO_NATIVE_PATH ${OV_RELATIVE_BIN_PATH} NATIVE_OV_RELATIVE_BIN_PATH) +else() + cmake_path(NATIVE_PATH OpenVINO_SOURCE_DIR OV_NATIVE_PROJECT_ROOT_DIR) + cmake_path(NATIVE_PATH OV_RELATIVE_BIN_PATH NATIVE_OV_RELATIVE_BIN_PATH) +endif() + +file(RELATIVE_PATH OV_NATIVE_PARENT_PROJECT_ROOT_DIR "${OpenVINO_SOURCE_DIR}/.." ${OpenVINO_SOURCE_DIR}) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # # Common options / warnings enabled @@ -366,6 +378,9 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # C4275 non dll-interface class used as base for dll-interface class ie_add_compiler_flags(/wd4275) + # Enable __FILE__ trim + add_compile_options("$<$:/d1trimfile:${OV_NATIVE_PROJECT_ROOT_DIR}\\>") + # # Debug information flags, by default CMake adds /Zi option # but provides no way to specify CMAKE_COMPILE_PDB_NAME on root level @@ -408,7 +423,7 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND WIN32) ie_add_compiler_flags(/Qdiag-disable:3180) # 11075: To get full report use -Qopt-report:4 -Qopt-report-phase ipo ie_add_compiler_flags(/Qdiag-disable:11075) - # 15335: was not vectorized: vectorization possible but seems inefficient. + # 15335: was not vectorized: vectorization possible but seems inefficient. # Use vector always directive or /Qvec-threshold0 to override ie_add_compiler_flags(/Qdiag-disable:15335) else() @@ -430,9 +445,22 @@ else() # - https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html # - https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html if(CMAKE_COMPILER_IS_GNUCXX) + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8") + # Enable __FILE__ trim + ie_add_compiler_flags(-ffile-prefix-map=${OV_NATIVE_PROJECT_ROOT_DIR}/=) + ie_add_compiler_flags(-ffile-prefix-map=${OV_RELATIVE_BIN_PATH}/=) + endif() # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wabi=11") endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "10") + # Enable __FILE__ trim + ie_add_compiler_flags(-ffile-prefix-map=${OV_NATIVE_PROJECT_ROOT_DIR}/=) + ie_add_compiler_flags(-ffile-prefix-map=${OV_RELATIVE_BIN_PATH}/=) + endif() + endif() + # # Warnings as errors # @@ -476,6 +504,11 @@ else() endif() endif() +add_compile_definitions( + + # Defines to trim check of __FILE__ macro in case if not done by compiler. + OV_NATIVE_PARENT_PROJECT_ROOT_DIR="${OV_NATIVE_PARENT_PROJECT_ROOT_DIR}") + check_cxx_compiler_flag("-Wsuggest-override" SUGGEST_OVERRIDE_SUPPORTED) if(SUGGEST_OVERRIDE_SUPPORTED) set(CMAKE_CXX_FLAGS "-Wsuggest-override ${CMAKE_CXX_FLAGS}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 405b95c0d72..610a208953b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,6 @@ # add_definitions(-DIN_OV_COMPONENT) -add_definitions(-DPROJECT_ROOT_DIR="${OpenVINO_SOURCE_DIR}") include(cmake/install_tbb.cmake) diff --git a/src/common/util/include/openvino/util/const_string.hpp b/src/common/util/include/openvino/util/const_string.hpp new file mode 100644 index 00000000000..9aa04790fe3 --- /dev/null +++ b/src/common/util/include/openvino/util/const_string.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace ov { +namespace util { +class ConstString { +public: + template + constexpr ConstString(const char (&p)[SIZE]) : m_string(p), + m_size(SIZE) {} + + constexpr char operator[](size_t i) const { + return i < m_size ? m_string[i] : throw std::out_of_range(""); + } + constexpr const char* get_ptr(size_t offset) const { + return offset < m_size ? &m_string[offset] : m_string; + } + constexpr size_t size() const { + return m_size; + } + +private: + const char* m_string; + size_t m_size; +}; + +constexpr const char* find_last(ConstString s, size_t offset, char ch) { + return offset == 0 ? s.get_ptr(0) : (s[offset] == ch ? s.get_ptr(offset + 1) : find_last(s, offset - 1, ch)); +} + +constexpr const char* find_last(ConstString s, char ch) { + return find_last(s, s.size() - 1, ch); +} + +constexpr const char* get_file_name(ConstString s) { + return find_last(s, '/'); +} + +} // namespace util +} // namespace ov diff --git a/src/common/util/include/openvino/util/file_util.hpp b/src/common/util/include/openvino/util/file_util.hpp index 7e68646ceb1..4d8d5dd8b3a 100644 --- a/src/common/util/include/openvino/util/file_util.hpp +++ b/src/common/util/include/openvino/util/file_util.hpp @@ -338,5 +338,21 @@ std::vector load_binary(const std::string& path); */ void save_binary(const std::string& path, std::vector binary); +/** + * @brief Trim OpenVINO project file name path if OpenVINO project directory found. + * + * Function use `OV_NATIVE_PARENT_PROJECT_ROOT_DIR` definition with project directory name defines + * 'openvino_dir_name'. The input file name is scanned for OV_NATIVE_PARENT_PROJECT_ROOT_DIR, + * if found returns pointer to trimmed name otherwise returns input pointer. + * + * e.g: OV_NATIVE_PARENT_PROJECT_ROOT_DIR = openvino + * - /home/user/openvino/src/example.cpp -> src/example.cpp + * - ../../../../openvino/src/example.cpp -> src/example.cpp + * + * @param fname Pointer to OpenVINO file name path. + * @return Pointer to trimmed file name path. + */ +const char* trim_file_name(const char* const fname); + } // namespace util } // namespace ov diff --git a/src/common/util/include/openvino/util/log.hpp b/src/common/util/include/openvino/util/log.hpp index c5ff3b5b24e..3160c6d2f6c 100644 --- a/src/common/util/include/openvino/util/log.hpp +++ b/src/common/util/include/openvino/util/log.hpp @@ -11,41 +11,7 @@ namespace ov { namespace util { -class ConstString { -public: - template - constexpr ConstString(const char (&p)[SIZE]) : m_string(p), - m_size(SIZE) {} - constexpr char operator[](size_t i) const { - return i < m_size ? m_string[i] : throw std::out_of_range(""); - } - constexpr const char* get_ptr(size_t offset) const { - return offset < m_size ? &m_string[offset] : m_string; - } - constexpr size_t size() const { - return m_size; - } - -private: - const char* m_string; - size_t m_size; -}; - -constexpr const char* find_last(ConstString s, size_t offset, char ch) { - return offset == 0 ? s.get_ptr(0) : (s[offset] == ch ? s.get_ptr(offset + 1) : find_last(s, offset - 1, ch)); -} - -constexpr const char* find_last(ConstString s, char ch) { - return find_last(s, s.size() - 1, ch); -} - -constexpr const char* get_file_name(ConstString s) { - return find_last(s, '/'); -} -constexpr const char* trim_file_name(ConstString root, ConstString s) { - return s.get_ptr(root.size()); -} enum class LOG_TYPE { _LOG_TYPE_ERROR, _LOG_TYPE_WARNING, @@ -85,36 +51,32 @@ private: void default_logger_handler_func(const std::string& s); -#ifndef PROJECT_ROOT_DIR -# define PROJECT_ROOT_DIR "" -#endif - -#define OPENVINO_ERR \ - ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_ERROR, \ - ::ov::util::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ::ov::util::default_logger_handler_func) \ +#define OPENVINO_ERR \ + ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_ERROR, \ + __FILE__, \ + __LINE__, \ + ::ov::util::default_logger_handler_func) \ .stream() -#define OPENVINO_WARN \ - ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_WARNING, \ - ::ov::util::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ::ov::util::default_logger_handler_func) \ +#define OPENVINO_WARN \ + ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_WARNING, \ + __FILE__, \ + __LINE__, \ + ::ov::util::default_logger_handler_func) \ .stream() -#define OPENVINO_INFO \ - ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_INFO, \ - ::ov::util::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ::ov::util::default_logger_handler_func) \ +#define OPENVINO_INFO \ + ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_INFO, \ + __FILE__, \ + __LINE__, \ + ::ov::util::default_logger_handler_func) \ .stream() -#define OPENVINO_DEBUG \ - ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_DEBUG, \ - ::ov::util::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ::ov::util::default_logger_handler_func) \ +#define OPENVINO_DEBUG \ + ::ov::util::LogHelper(::ov::util::LOG_TYPE::_LOG_TYPE_DEBUG, \ + __FILE__, \ + __LINE__, \ + ::ov::util::default_logger_handler_func) \ .stream() } // namespace util } // namespace ov diff --git a/src/common/util/src/file_util.cpp b/src/common/util/src/file_util.cpp index 2ec2f9cfb7f..7bcc99b5c32 100644 --- a/src/common/util/src/file_util.cpp +++ b/src/common/util/src/file_util.cpp @@ -634,3 +634,10 @@ void ov::util::save_binary(const std::string& path, std::vector binary) throw std::runtime_error("Could not save binary to " + path); } } + +const char* ov::util::trim_file_name(const char* const fname) { + static const auto pattern = std::string(OV_NATIVE_PARENT_PROJECT_ROOT_DIR) + FileTraits::file_separator; + + const auto has_pattern_ptr = std::strstr(fname, pattern.c_str()); + return has_pattern_ptr ? has_pattern_ptr + pattern.size() : fname; +} diff --git a/src/common/util/src/log.cpp b/src/common/util/src/log.cpp index bafaf6ba11f..84ed0b58364 100644 --- a/src/common/util/src/log.cpp +++ b/src/common/util/src/log.cpp @@ -9,6 +9,8 @@ #include #include +#include "openvino/util/file_util.hpp" + void ov::util::default_logger_handler_func(const std::string& s) { std::cout << s << std::endl; } @@ -41,7 +43,7 @@ ov::util::LogHelper::LogHelper(LOG_TYPE type, m_stream << buffer << " "; } - m_stream << file; + m_stream << util::trim_file_name(file); m_stream << " " << line; m_stream << "\t"; } diff --git a/src/core/include/ngraph/log.hpp b/src/core/include/ngraph/log.hpp index b1d2f4a4c27..596c4a4a6da 100644 --- a/src/core/include/ngraph/log.hpp +++ b/src/core/include/ngraph/log.hpp @@ -69,9 +69,9 @@ constexpr const char* get_file_name(ConstString s) { return find_last(s, '/'); } NGRAPH_API_DEPRECATED -constexpr const char* trim_file_name(ConstString root, ConstString s) { - return s.get_ptr(root.size()); -} +NGRAPH_API +const char* trim_file_name(const char* const fname); + enum class LOG_TYPE { _LOG_TYPE_ERROR, _LOG_TYPE_WARNING, @@ -113,36 +113,33 @@ NGRAPH_API_DEPRECATED NGRAPH_API void default_logger_handler_func(const std::string& s); -#ifndef PROJECT_ROOT_DIR -# define PROJECT_ROOT_DIR "" -#endif NGRAPH_SUPPRESS_DEPRECATED_END -#define NGRAPH_ERR \ - ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_ERROR, \ - ngraph::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ngraph::default_logger_handler_func) \ +#define NGRAPH_ERR \ + ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_ERROR, \ + ngraph::trim_file_name(__FILE__), \ + __LINE__, \ + ngraph::default_logger_handler_func) \ .stream() -#define NGRAPH_WARN \ - ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_WARNING, \ - ngraph::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ngraph::default_logger_handler_func) \ +#define NGRAPH_WARN \ + ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_WARNING, \ + ngraph::trim_file_name(__FILE__), \ + __LINE__, \ + ngraph::default_logger_handler_func) \ .stream() -#define NGRAPH_INFO \ - ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_INFO, \ - ngraph::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ngraph::default_logger_handler_func) \ +#define NGRAPH_INFO \ + ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_INFO, \ + ngraph::trim_file_name(__FILE__), \ + __LINE__, \ + ngraph::default_logger_handler_func) \ .stream() -#define NGRAPH_DEBUG \ - ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_DEBUG, \ - ngraph::trim_file_name(PROJECT_ROOT_DIR, __FILE__), \ - __LINE__, \ - ngraph::default_logger_handler_func) \ +#define NGRAPH_DEBUG \ + ngraph::LogHelper(ngraph::LOG_TYPE::_LOG_TYPE_DEBUG, \ + ngraph::trim_file_name(__FILE__), \ + __LINE__, \ + ngraph::default_logger_handler_func) \ .stream() } // namespace ngraph diff --git a/src/core/src/except.cpp b/src/core/src/except.cpp index e7352e17fe7..61bb40b8f32 100644 --- a/src/core/src/except.cpp +++ b/src/core/src/except.cpp @@ -4,6 +4,8 @@ #include "openvino/core/except.hpp" +#include "openvino/util/file_util.hpp" + ov::Exception::Exception(const std::string& what_arg) : std::runtime_error(what_arg) {} void ov::Exception::create(const CheckLocInfo& check_loc_info, const std::string& explanation) { @@ -15,22 +17,12 @@ void ov::Exception::create(const CheckLocInfo& check_loc_info, const std::string std::string ov::Exception::make_what(const CheckLocInfo& check_loc_info, const std::string& context_info, const std::string& explanation) { - // Use relative path only for internal code - auto getRelativePath = [](const std::string& path) -> std::string { - // Path to local OpenVINO repository - static const std::string project_root(PROJECT_ROOT_DIR); - // All internal paths start from project root - if (path.find(project_root) != 0) - return path; - // Add +1 to remove first / - return path.substr(project_root.length() + 1); - }; std::stringstream ss; if (check_loc_info.check_string) { - ss << "Check '" << check_loc_info.check_string << "' failed at " << getRelativePath(check_loc_info.file) << ":" - << check_loc_info.line; + ss << "Check '" << check_loc_info.check_string << "' failed at " << util::trim_file_name(check_loc_info.file) + << ":" << check_loc_info.line; } else { - ss << "Exception from " << getRelativePath(check_loc_info.file) << ":" << check_loc_info.line; + ss << "Exception from " << util::trim_file_name(check_loc_info.file) << ":" << check_loc_info.line; } if (!context_info.empty()) { ss << ":" << std::endl << context_info; diff --git a/src/core/src/log.cpp b/src/core/src/log.cpp index f3783791e0b..105cc6cb6e6 100644 --- a/src/core/src/log.cpp +++ b/src/core/src/log.cpp @@ -14,6 +14,7 @@ #include "ngraph/distributed.hpp" #include "ngraph/env_util.hpp" +#include "openvino/util/file_util.hpp" using namespace std; using namespace ngraph; @@ -60,3 +61,9 @@ LogHelper::~LogHelper() { // Logger::log_item(m_stream.str()); #endif } + +NGRAPH_SUPPRESS_DEPRECATED_START +const char* ngraph::trim_file_name(const char* const fname) { + return ov::util::trim_file_name(fname); +} +NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/src/core/tests/check.cpp b/src/core/tests/check.cpp index 8cfdb4dd772..73f2ecfeaf3 100644 --- a/src/core/tests/check.cpp +++ b/src/core/tests/check.cpp @@ -6,7 +6,9 @@ #include +#include "common_test_utils/test_assertions.hpp" #include "openvino/core/except.hpp" +#include "openvino/util/file_util.hpp" using namespace std; @@ -85,3 +87,9 @@ TEST(check, ngraph_check_with_explanation) { EXPECT_TRUE(check_failure_thrown); } + +TEST(check, ov_throw_exception_check_relative_path_to_source) { + const auto path = ov::util::path_join({"src", "core", "tests", "check.cpp"}); + const auto exp_msg = "Exception from " + path + ":" + std::to_string(__LINE__ + 1) + ":\nTest message"; + OV_EXPECT_THROW(OPENVINO_THROW("Test message"), ov::Exception, testing::HasSubstr(exp_msg)); +} diff --git a/src/core/tests/file_util.cpp b/src/core/tests/file_util.cpp index b1628efbe2b..11544293a1d 100644 --- a/src/core/tests/file_util.cpp +++ b/src/core/tests/file_util.cpp @@ -10,6 +10,7 @@ #include #include "gtest/gtest.h" +#include "openvino/util/file_util.hpp" NGRAPH_SUPPRESS_DEPRECATED_START @@ -110,3 +111,48 @@ TEST(file_util, sanitize_path) { EXPECT_STREQ("workspace\\tensor.data", file_util::sanitize_path(path).c_str()); } } + +NGRAPH_SUPPRESS_DEPRECATED_END + +using namespace testing; + +class TrimFileTest : public Test { +protected: + void SetUp() override { + project_dir_name = std::string(OV_NATIVE_PARENT_PROJECT_ROOT_DIR); + } + + std::string project_dir_name; +}; + +TEST_F(TrimFileTest, relative_path_to_source) { + const auto exp_path = ov::util::path_join({"src", "test_src.cpp"}); + + const auto file_path = ov::util::path_join({"..", "..", "..", project_dir_name, "src", "test_src.cpp"}); + + auto str_ptr = ov::util::trim_file_name(file_path.c_str()); + EXPECT_EQ(exp_path, str_ptr); +} + +TEST_F(TrimFileTest, relative_path_to_source_but_no_project_dir) { + const auto file_path = ov::util::path_join({"..", "..", "..", "src", "test_src.cpp"}); + + auto str_ptr = ov::util::trim_file_name(file_path.c_str()); + EXPECT_EQ(file_path, str_ptr); +} + +TEST_F(TrimFileTest, absolute_path_to_source) { + const auto exp_path = ov::util::path_join({"src", "test_src.cpp"}); + + const auto file_path = ov::util::path_join({"home", "user", project_dir_name, "src", "test_src.cpp"}); + + auto str_ptr = ov::util::trim_file_name(file_path.c_str()); + EXPECT_EQ(exp_path, str_ptr); +} + +TEST_F(TrimFileTest, absolute_path_to_source_but_no_project_dir) { + const auto file_path = ov::util::path_join({"home", "user", "src", "test_src.cpp"}); + + auto str_ptr = ov::util::trim_file_name(file_path.c_str()); + EXPECT_EQ(file_path, str_ptr); +}