1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
6 * \brief Basic debugging tools
25 #include "ie_algorithm.hpp"
30 #define POSIX_EPOCH_AS_FILETIME 116444736000000000ULL
32 static void gettimeofday(struct timeval * tp, struct timezone *) {
33 SYSTEMTIME system_time;
37 GetSystemTime(&system_time);
38 SystemTimeToFileTime(&system_time, &file_time);
40 time = file_time.dwLowDateTime;
41 time += static_cast<uint64_t>(file_time.dwHighDateTime) << 32;
43 tp->tv_sec = static_cast<long>((time - POSIX_EPOCH_AS_FILETIME) / 10000000L);
44 tp->tv_usec = (system_time.wMilliseconds * 1000);
47 #define vsnprintf_s vsnprintf
54 #define OPT_USAGE __attribute__ ((unused))
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;
65 namespace InferenceEngine {
69 * @brief vector serialisation to be used in exception
72 inline std::ostream & operator << (std::ostream &out, const std::vector<T> &vec) {
73 if (vec.empty()) return std::operator<<(out, "[]");
75 for (unsigned i=1; i < vec.size(); i++) {
76 out << ", " << vec[i];
83 * @brief trim from start (in place)
84 * @param s - string to trim
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))));
91 * @brief trim from end (in place)
92 * @param s - string to trim
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());
99 * @brief trim from both ends (in place)
100 * @param s - string to trim
102 inline std::string &trim(std::string &s) {
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
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;
119 srcLength = src.length(),
120 delimLength = delimiter.length();
122 pos = src.find(delimiter, prev);
123 if (pos == std::string::npos) {
126 tokenBuf = src.substr(prev, pos - prev);
127 if (!tokenBuf.empty()) {
128 tokens.push_back(tokenBuf);
130 prev = pos + delimLength;
131 } while (pos < srcLength && prev < srcLength);
136 * @brief create a string representation for a vector of values
137 * @param vec - vector of values
138 * @return string representation
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];
151 * @brief multiply vector's values
152 * @param vec - vector with values
153 * @return result of multiplication
155 template<typename T, typename A>
156 T product(std::vector<T, A> const &vec) {
157 if (vec.empty()) return 0;
159 for (size_t i = 1; i < vec.size(); ++i) ret *= vec[i];
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
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) {
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()));
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
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);
199 * @brief converts all upper-case letters in a string to lower case
200 * @param s - string to convert
202 inline std::string tolower(const std::string &s) {
204 ret.resize(s.length());
205 std::transform(s.begin(), s.end(), ret.begin(), ::tolower);
208 } // namespace details
209 } // namespace InferenceEngine
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
219 static void OPT_USAGE print_log(bool isErr, const char *level, const char *file, int line, const char *msg, ...) {
226 gettimeofday(&tval, NULL);
228 auto outFd = isErr ? stderr : stdout;
233 localtime_s(&tm_info, &timer);
235 localtime_r(&tval.tv_sec, &tm_info);
238 strftime(buffer, 64, "%Y:%m:%d %H:%M:%S", &tm_info);
240 fprintf(outFd, "%s.%06ld [%s] %s:%d : ", buffer, (long)tval.tv_usec, level, file, line);
241 vfprintf(outFd, msg, va);
243 fprintf(outFd, "\r\n");
249 * @brief Log an error message
251 #define LogError(...) {print_log(true , "ERROR", __FILE__, __LINE__, ##__VA_ARGS__); }
255 * @brief Log warning message
257 #define LogWarning(...) { print_log(true , "WARNING", __FILE__, __LINE__, ##__VA_ARGS__); }
261 * @brief Log info message
263 #define LogInfo(...) { print_log(false, "INFO", __FILE__, __LINE__, ##__VA_ARGS__); }
267 * @brief Log debug message
269 #define LogDebug(...) { print_log(false, "DEBUG", __FILE__, __LINE__, ##__VA_ARGS__); }
273 * @brief Log oss debug message
275 #define OssDebug(x) { std::stringstream oss; oss << x ; LogDebug("%s", oss.str().c_str()); }