Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / inference_engine / debug.h
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 /**
6  * \brief Basic debugging tools
7  * \file debug.h
8  */
9 #pragma once
10
11 #include <cstdlib>
12 #include <cstdarg>
13 #include <string>
14 #include <ctime>
15 #include <cstdint>
16 #include <algorithm>
17 #include <functional>
18 #include <cctype>
19 #include <iostream>
20 #include <sstream>
21 #include <vector>
22 #include <iterator>
23 #include <numeric>
24 #include <w_unistd.h>
25 #include "ie_algorithm.hpp"
26
27 #ifdef _WIN32
28 #include <windows.h>
29
30 #define POSIX_EPOCH_AS_FILETIME 116444736000000000ULL
31 #define OPT_USAGE
32 static void gettimeofday(struct timeval * tp, struct timezone *) {
33     SYSTEMTIME  system_time;
34     FILETIME    file_time;
35     uint64_t    time;
36
37     GetSystemTime(&system_time);
38     SystemTimeToFileTime(&system_time, &file_time);
39
40     time = file_time.dwLowDateTime;
41     time += static_cast<uint64_t>(file_time.dwHighDateTime) << 32;
42
43     tp->tv_sec = static_cast<long>((time - POSIX_EPOCH_AS_FILETIME) / 10000000L);
44     tp->tv_usec = (system_time.wMilliseconds * 1000);
45 }
46 #else
47 #define vsnprintf_s vsnprintf
48
49 #include <string.h>
50 #include <sys/time.h>
51
52 #ifndef OPT_USAGE
53 #ifdef __GNUC__
54 #define OPT_USAGE __attribute__ ((unused))
55 #else
56 #define OPT_USAGE
57 #endif
58 #endif
59 #endif
60 /// Diff in uSec
61 inline int64_t operator-(const timeval& lhs, const timeval& rhs) {
62     return static_cast<int64_t>(lhs.tv_sec - rhs.tv_sec) * 1000000 + lhs.tv_usec - rhs.tv_usec;
63 }
64
65 namespace InferenceEngine {
66 namespace details {
67
68 /**
69 * @brief vector serialisation to be used in exception
70 */
71 template <typename T>
72 inline std::ostream & operator << (std::ostream &out, const std::vector<T> &vec) {
73     if (vec.empty()) return std::operator<<(out, "[]");
74     out << "[" << vec[0];
75     for (unsigned i=1; i < vec.size(); i++) {
76         out << ", " << vec[i];
77     }
78     return out << "]";
79 }
80
81
82 /**
83  * @brief trim from start (in place)
84  * @param s - string to trim
85  */
86 inline void ltrim(std::string &s) {
87     s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
88 }
89
90 /**
91  * @brief trim from end (in place)
92  * @param s - string to trim
93  */
94 inline void rtrim(std::string &s) {
95     s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
96 }
97
98 /**
99  * @brief trim from both ends (in place)
100  * @param s - string to trim
101  */
102 inline std::string &trim(std::string &s) {
103     ltrim(s);
104     rtrim(s);
105     return s;
106 }
107
108 /**
109  * @brief split string into a vector of substrings
110  * @param src - string to split
111  * @param delimiter - string used as a delimiter
112  * @return vector of substrings
113  */
114 inline std::vector<std::string> split(const std::string &src, const std::string &delimiter) {
115     std::vector<std::string> tokens;
116     std::string tokenBuf;
117     size_t prev = 0,
118             pos = 0,
119             srcLength = src.length(),
120             delimLength = delimiter.length();
121     do {
122         pos = src.find(delimiter, prev);
123         if (pos == std::string::npos) {
124             pos = srcLength;
125         }
126         tokenBuf = src.substr(prev, pos - prev);
127         if (!tokenBuf.empty()) {
128             tokens.push_back(tokenBuf);
129         }
130         prev = pos + delimLength;
131     } while (pos < srcLength && prev < srcLength);
132     return tokens;
133 }
134
135 /**
136  * @brief create a string representation for a vector of values
137  * @param vec - vector of values
138  * @return string representation
139  */
140 template<typename T, typename A>
141 std::string dumpVec(std::vector<T, A> const &vec) {
142     if (vec.empty()) return "[]";
143     std::stringstream oss;
144     oss << "[" << vec[0];
145     for (size_t i = 1; i < vec.size(); i++) oss << "," << vec[i];
146     oss << "]";
147     return oss.str();
148 }
149
150 /**
151  * @brief multiply vector's values
152  * @param vec - vector with values
153  * @return result of multiplication
154  */
155 template<typename T, typename A>
156 T product(std::vector<T, A> const &vec) {
157     if (vec.empty()) return 0;
158     T ret = vec[0];
159     for (size_t i = 1; i < vec.size(); ++i) ret *= vec[i];
160     return ret;
161 }
162
163 /**
164  * @brief check if vectors contain same values
165  * @param v1 - first vector
166  * @param v2 - second vector
167  * @return true if vectors contain same values
168  */
169 template<typename T, typename A>
170 bool equal(const std::vector<T, A> &v1, const std::vector<T, A> &v2) {
171     if (v1.size() != v2.size()) return false;
172     for (auto i1 = v1.cbegin(), i2 = v2.cbegin(); i1 != v1.cend(); ++i1, ++i2) {
173         if (*i1 != *i2)
174             return false;
175     }
176     return true;
177 }
178
179 inline bool equal(const std::string &lhs, const std::string &rhs, bool ignoreCase = true) {
180     return (lhs.size() == rhs.size()) && (ignoreCase ?
181         0 == strncasecmp(lhs.c_str(), rhs.c_str(), lhs.size()) :
182         0 == strncmp(lhs.c_str(), rhs.c_str(), lhs.size()));
183 }
184
185 /**
186  * @brief check string end with given substring
187  * @param src - string to check
188  * @param with - given substring
189  * @return true if string end with given substring
190  */
191 inline bool endsWith(const std::string &src, const char *with) {
192     int wl = static_cast<int>(strlen(with));
193     int so = static_cast<int>(src.length()) - wl;
194     if (so < 0) return false;
195     return 0 == strncmp(with, &src[so], wl);
196 }
197
198 /**
199 * @brief converts all upper-case letters in a string to lower case
200 * @param s - string to convert
201 */
202 inline std::string tolower(const std::string &s) {
203     std::string ret;
204     ret.resize(s.length());
205     std::transform(s.begin(), s.end(), ret.begin(), ::tolower);
206     return ret;
207 }
208 }  // namespace details
209 }  // namespace InferenceEngine
210
211 /**
212  * @brief print a log message
213  * @param isErr - is message an error or not
214  * @param level - string containing message level, like "ERROR" or "DEBUG"
215  * @param file - file the message was produced by
216  * @param line - string in file the message was dispatched from
217  * @param msg - format for message + arguments
218  */
219 static void OPT_USAGE print_log(bool isErr, const char *level, const char *file, int line, const char *msg, ...) {
220     va_list va;
221     va_start(va, msg);
222     char buffer[64];
223     struct tm tm_info;
224
225     struct timeval tval;
226     gettimeofday(&tval, NULL);
227
228     auto outFd = isErr ? stderr : stdout;
229
230 #ifdef _WIN32
231     time_t timer;
232     timer = tval.tv_sec;
233     localtime_s(&tm_info, &timer);
234 #else
235     localtime_r(&tval.tv_sec, &tm_info);
236 #endif
237
238     strftime(buffer, 64, "%Y:%m:%d %H:%M:%S", &tm_info);
239
240     fprintf(outFd, "%s.%06ld [%s] %s:%d : ", buffer, (long)tval.tv_usec, level, file, line);
241     vfprintf(outFd, msg, va);
242     va_end(va);
243     fprintf(outFd, "\r\n");
244     fflush(outFd);
245 }
246
247 /**
248  * @def LogError
249  * @brief Log an error message
250  */
251 #define LogError(...) {print_log(true , "ERROR", __FILE__, __LINE__, ##__VA_ARGS__); }
252
253 /**
254  * @def LogWarning
255  * @brief Log warning message
256  */
257 #define LogWarning(...) { print_log(true , "WARNING", __FILE__, __LINE__, ##__VA_ARGS__); }
258
259 /**
260  * @def LogInfo
261  * @brief Log info message
262  */
263 #define LogInfo(...) { print_log(false, "INFO", __FILE__, __LINE__, ##__VA_ARGS__); }
264
265 /**
266  * @def LogDebug
267  * @brief Log debug message
268  */
269 #define LogDebug(...) { print_log(false, "DEBUG", __FILE__, __LINE__, ##__VA_ARGS__); }
270
271 /**
272  * @def OssDebug
273  * @brief Log oss debug message
274  */
275 #define OssDebug(x) { std::stringstream oss; oss << x ; LogDebug("%s", oss.str().c_str()); }