Skip to content

Commit a62670f

Browse files
CuriousPanCakeitikhonopraaszdorloff
authored
Improve logging of the matching process (openvinotoolkit#28587)
Improve logging of the matching process to make more human-friendly Logging before: ![image](https://github.com/user-attachments/assets/40a33d8b-b8c4-4589-a3d2-802df6f23d77) Several examples of the improved logging: 1. ![image](https://github.com/user-attachments/assets/9afedf44-0419-4144-a6d3-4db34e145654) 2. ![image](https://github.com/user-attachments/assets/9cd11fd8-5278-4c1b-a7ad-3c6de25a4d44) 3. ![image](https://github.com/user-attachments/assets/eb649afd-5101-4dac-96d1-14b40908cc46) 4. ![image](https://github.com/user-attachments/assets/c006b9e1-bc67-4d8d-9f78-82d896f6f229) Signed-off-by: Andrii Staikov <andrii.staikov@intel.com> Ticket: * [CVS-151312](https://jira.devtools.intel.com/browse/CVS-151312) --------- Co-authored-by: Ivan Tikhonov <ivan.tikhonov@intel.com> Co-authored-by: Pawel Raasz <pawel.raasz@intel.com> Co-authored-by: Denis Orlov <denis.orlov@intel.com>
1 parent f77ef0f commit a62670f

File tree

21 files changed

+1087
-75
lines changed

21 files changed

+1087
-75
lines changed
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Transformations documentation
2+
3+
## Debug capabilities
4+
5+
* [Matcher logging README](./debug_capabilities/LOGGING_README.md)
6+
7+
## Key Contacts
8+
9+
For assistance regarding snippets, contact a member of [openvino-ie-transformations-maintainers](https://github.com/orgs/openvinotoolkit/teams/openvino-ie-transformations-maintainers) group.
10+
11+
## See also
12+
13+
* [OpenVINO™ README](../../../README.md)
14+
* [OpenVINO Core Components](../../README.md)
15+
* [Developer documentation](../../../docs/dev/index.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Logging of the pattern matching
2+
3+
The logging functionality allows to observe/debug the pattern matching process.
4+
5+
## Usage
6+
In order to utilzie the logging, first, you need to set the CMake flag ```-DENABLE_OPENVINO_DEBUG=ON```
7+
8+
_NOTE: the logging would also work if your build is configured as Release_
9+
10+
In order to start logging, set the environmental variable ```OV_MATCHER_LOGGING``` to ``true/ON`` before running your executable or script as following:
11+
```OV_MATCHER_LOGGING=true ./your_amazing_program```
12+
13+
If you want to log only specific matchers, use the ```OV_MATCHERS_TO_LOG``` environmental variable and provide their names separated as commas:
14+
```OV_MATCHER_LOGGING=true OV_MATCHERS_TO_LOG=EliminateSplitConcat,MarkDequantization ./your_amazing_program```
15+
16+
You can also set the environmental variable ```OV_VERBOSE_LOGGING``` to ```true```, to turn on more verbose logging that would print more information about the nodes taking part in the matching process:
17+
```OV_MATCHER_LOGGING=true OV_VERBOSE_LOGGING=true ./your_amazing_program```
18+
19+
## Useful feature:
20+
If you redirect the logging output into a .json file (extension is important for the correct processing of the file in Visual Studio Code). This allows collapsing blocks in Visual Studio Code as you would do with a normal .json file.
21+
22+
If you have any suggestions for improvement or you observe a bug in logging, feel free to submit changes or contact Andrii Staikov <andrii.staikov@intel.com>

src/common/transformations/include/transformations/utils/gen_pattern.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <string>
2323
#include <utility>
2424

25+
#include "openvino/core/log_util.hpp"
2526
#include "openvino/opsets/opset1.hpp"
2627
#include "openvino/opsets/opset2.hpp"
2728
#include "openvino/opsets/opset3.hpp"
@@ -34,6 +35,7 @@
3435
#include "openvino/pass/pattern/op/label.hpp"
3536
#include "openvino/pass/pattern/op/or.hpp"
3637
#include "openvino/pass/pattern/op/wrap_type.hpp"
38+
#include "openvino/util/log.hpp"
3739

3840
namespace ov {
3941
namespace gen_pattern {
@@ -811,17 +813,20 @@ class GenericPattern : public ov::pass::pattern::op::Pattern {
811813
pattern_value.get_index(),
812814
"!=",
813815
graph_value.get_index());
816+
OPENVINO_LOG_GENPATTERN1(matcher, pattern_value, graph_value);
814817
return false;
815818
}
816819

817820
auto value_node = graph_value.get_node_shared_ptr();
818821
if (!value_node->get_type_info().is_castable(m_type_info)) {
819822
_VERBOSE_LOG(level, "X OP type mismatch: ", m_signature, " vs ", graph_value);
823+
OPENVINO_LOG_GENPATTERN2(matcher, pattern_value, graph_value);
820824
return false;
821825
}
822826

823827
if (!m_vt.predicate(graph_value)) {
824828
_VERBOSE_LOG(level, "X value info mismatch: ", m_signature, " vs ", graph_value);
829+
OPENVINO_LOG_GENPATTERN3(matcher);
825830
return false;
826831
}
827832

@@ -830,6 +835,7 @@ class GenericPattern : public ov::pass::pattern::op::Pattern {
830835
value_node->visit_attributes(visitor);
831836
if (!visitor.matched()) {
832837
_VERBOSE_LOG(level, "X OP attrs mismatch: ", m_signature, " vs ", graph_value);
838+
OPENVINO_LOG_GENPATTERN4(matcher);
833839
return false;
834840
}
835841
}
@@ -843,14 +849,20 @@ class GenericPattern : public ov::pass::pattern::op::Pattern {
843849

844850
if (matcher_verbose_enabled())
845851
level.push_back('\t');
852+
OPENVINO_LOG_GENPATTERN5(matcher);
846853
bool ret = matcher->match_arguments(pattern_value.get_node(), graph_value.get_node_shared_ptr());
854+
OPENVINO_LOG_GENPATTERN6(matcher, ret);
847855
if (matcher_verbose_enabled()) {
848856
level.pop_back();
849857
_VERBOSE_LOG(level, ret ? "O" : "X", m_signature, " vs ", graph_value);
850858
}
851859
return ret;
852860
}
853861

862+
const DiscreteTypeInfo& get_wrapped_type() const {
863+
return m_type_info;
864+
}
865+
854866
private:
855867
const DiscreteTypeInfo& m_type_info;
856868
detail::AttrMap m_attrs;

src/common/util/include/openvino/util/env_util.hpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <cstdint>
88
#include <string>
9-
9+
#include <unordered_set>
1010
namespace ov {
1111
namespace util {
1212
/// \brief Get the names environment variable as a string.
@@ -31,5 +31,12 @@ int32_t getenv_int(const char* env_var, int32_t default_value = -1);
3131
/// \param default_value The value to return if the environment variable is not set.
3232
/// \return Returns the boolean value of the environment variable.
3333
bool getenv_bool(const char* env_var, bool default_value = false);
34+
35+
/// \brief Splits a string using by a single character delimiter
36+
/// without modifying the original string
37+
/// \param str String to split
38+
/// \param delimiter Delimiter to use for splitting
39+
/// \return Returns an unordered set of split strings
40+
std::unordered_set<std::string> split_by_delimiter(const std::string& str, char delimiter);
3441
} // namespace util
3542
} // namespace ov

src/common/util/include/openvino/util/log.hpp

+48
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@
66

77
#include <deque>
88
#include <functional>
9+
#include <iostream>
910
#include <sstream>
11+
#include <unordered_set>
1012
#include <vector>
1113

14+
#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
15+
# include <unistd.h>
16+
#endif
17+
18+
#include "openvino/util/env_util.hpp"
19+
1220
namespace ov {
1321
namespace util {
1422

@@ -17,6 +25,7 @@ enum class LOG_TYPE {
1725
_LOG_TYPE_WARNING,
1826
_LOG_TYPE_INFO,
1927
_LOG_TYPE_DEBUG,
28+
_LOG_TYPE_DEBUG_EMPTY,
2029
};
2130

2231
class LogHelper {
@@ -50,6 +59,7 @@ class Logger {
5059
};
5160

5261
void default_logger_handler_func(const std::string& s);
62+
void default_logger_handler_func_length(const std::string& s);
5363

5464
#ifdef ENABLE_OPENVINO_DEBUG
5565
/* Template function _write_all_to_stream has duplicates
@@ -93,6 +103,41 @@ static inline std::ostream& _write_all_to_stream(std::ostream& os, const T& arg,
93103
do { \
94104
ov::util::_write_all_to_stream(OPENVINO_LOG_STREAM(_LOG_TYPE_DEBUG), __VA_ARGS__); \
95105
} while (0)
106+
107+
static const bool logging_enabled = ov::util::getenv_bool("OV_MATCHER_LOGGING");
108+
static const std::unordered_set<std::string> matchers_to_log =
109+
ov::util::split_by_delimiter(ov::util::getenv_string("OV_MATCHERS_TO_LOG"), ',');
110+
111+
static inline bool is_terminal_output() {
112+
# ifdef _WIN32
113+
// No Windows support for colored logs for now.
114+
return false;
115+
# else
116+
static const bool stdout_to_terminal = isatty(fileno(stdout));
117+
return stdout_to_terminal;
118+
# endif
119+
}
120+
121+
# define OPENVINO_RESET (ov::util::is_terminal_output() ? "\033[0m" : "")
122+
# define OPENVINO_RED (ov::util::is_terminal_output() ? "\033[31m" : "")
123+
# define OPENVINO_GREEN (ov::util::is_terminal_output() ? "\033[1;32m" : "")
124+
# define OPENVINO_YELLOW (ov::util::is_terminal_output() ? "\033[33m" : "")
125+
# define OPENVINO_BLOCK_BEG "{"
126+
# define OPENVINO_BLOCK_END "}"
127+
# define OPENVINO_BLOCK_BODY ""
128+
# define OPENVINO_BLOCK_BODY_RIGHT "├─"
129+
130+
# define OPENVINO_LOG_MATCHING(matcher_ptr, ...) \
131+
do { \
132+
if (ov::util::logging_enabled) { \
133+
if (ov::util::matchers_to_log.empty() || \
134+
ov::util::matchers_to_log.find(matcher_ptr->get_name()) != ov::util::matchers_to_log.end()) { \
135+
ov::util::_write_all_to_stream(OPENVINO_LOG_STREAM(_LOG_TYPE_DEBUG_EMPTY), \
136+
__VA_ARGS__, \
137+
OPENVINO_RESET); \
138+
} \
139+
} \
140+
} while (0)
96141
#else
97142
# define OPENVINO_ERR(...) \
98143
do { \
@@ -106,6 +151,9 @@ static inline std::ostream& _write_all_to_stream(std::ostream& os, const T& arg,
106151
# define OPENVINO_DEBUG(...) \
107152
do { \
108153
} while (0)
154+
# define OPENVINO_LOG_MATCHING(matcher_ptr, ...) \
155+
do { \
156+
} while (0)
109157
#endif
110158

111159
} // namespace util

src/common/util/src/env_util.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,17 @@ bool ov::util::getenv_bool(const char* env_var, bool default_value) {
6969
}
7070
return rc;
7171
}
72+
73+
std::unordered_set<std::string> ov::util::split_by_delimiter(const std::string& str, char delimiter) {
74+
std::unordered_set<std::string> res;
75+
size_t start_search_from = 0;
76+
size_t pos;
77+
while ((pos = str.find(delimiter, start_search_from)) != std::string::npos) {
78+
res.insert(str.substr(start_search_from, pos - start_search_from));
79+
start_search_from = pos + 1;
80+
}
81+
if (start_search_from < str.size()) {
82+
res.insert(str.substr(start_search_from));
83+
}
84+
return res;
85+
}

src/common/util/src/log.cpp

+17-13
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,27 @@ ov::util::LogHelper::LogHelper(LOG_TYPE type,
3434
case LOG_TYPE::_LOG_TYPE_DEBUG:
3535
m_stream << "[DEBUG] ";
3636
break;
37+
case LOG_TYPE::_LOG_TYPE_DEBUG_EMPTY:
38+
break;
3739
}
3840

39-
{
40-
static std::mutex m;
41-
time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
42-
std::lock_guard<std::mutex> lock(m);
43-
auto tm = gmtime(&tt);
44-
if (tm) {
45-
char buffer[256];
46-
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%Sz", tm);
47-
m_stream << buffer << " ";
41+
if (type != LOG_TYPE::_LOG_TYPE_DEBUG_EMPTY) {
42+
{
43+
static std::mutex m;
44+
time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
45+
std::lock_guard<std::mutex> lock(m);
46+
auto tm = gmtime(&tt);
47+
if (tm) {
48+
char buffer[256];
49+
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%Sz", tm);
50+
m_stream << buffer << " ";
51+
}
4852
}
49-
}
5053

51-
m_stream << util::trim_file_name(file);
52-
m_stream << " " << line;
53-
m_stream << "\t";
54+
m_stream << util::trim_file_name(file);
55+
m_stream << " " << line;
56+
m_stream << "\t";
57+
}
5458
}
5559

5660
ov::util::LogHelper::~LogHelper() {

0 commit comments

Comments
 (0)