1 /**
2 * Copyright 2020 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef MINDSPORE_LITE_SRC_COMMON_UTILS_H_
18 #define MINDSPORE_LITE_SRC_COMMON_UTILS_H_
19
20 #include <ctime>
21 #include <cstdint>
22 #include <vector>
23 #include <set>
24 #include <limits>
25 #include <cmath>
26 #include <string>
27 #include <utility>
28 #include <regex>
29 #include <algorithm>
30 #include <map>
31 #include "src/common/log_adapter.h"
32 #include "tools/common/option.h"
33 #include "include/errorcode.h"
34 #include "ir/dtype/type_id.h"
35
36 namespace mindspore {
37 namespace lite {
38 enum NodeType {
39 NodeType_ValueNode, // const
40 NodeType_Parameter, // var
41 NodeType_CNode // op
42 };
43
44 struct ShapeDim {
45 int64_t dim = 0;
46 int64_t min = 0;
47 int64_t max = 0;
48 };
49
50 struct DynamicShape {
51 std::vector<ShapeDim> dims;
52 };
53
54 const int USEC = 1000000;
55 const int MSEC = 1000;
56 uint64_t GetTimeUs();
57
58 bool IsSupportSDot();
59
60 size_t GetMaxMallocSize();
61
62 int GetCoreNum();
63
64 #ifdef __ANDROID__
65 uint32_t getHwCap(int hwcap_type);
66 #endif
67
68 template <typename T>
IsContain(const std::vector<T> & vec,T element)69 bool IsContain(const std::vector<T> &vec, T element) {
70 for (auto iter = vec.begin(); iter != vec.end(); iter++) {
71 if (*iter == element) {
72 return true;
73 }
74 }
75 return false;
76 }
77
78 template <typename T>
VectorErase(std::vector<T> * vec,T element)79 bool VectorErase(std::vector<T> *vec, T element) {
80 bool ret = false;
81 for (auto iter = vec->begin(); iter != vec->end();) {
82 if (*iter == element) {
83 iter = vec->erase(iter);
84 ret = true;
85 } else {
86 iter++;
87 }
88 }
89 return ret;
90 }
91
92 template <typename T>
VectorSetNull(std::vector<T> * vec,T element)93 bool VectorSetNull(std::vector<T> *vec, T element) {
94 bool ret = false;
95 for (size_t i = 0; i < vec->size(); i++) {
96 if (vec->at(i) == element) {
97 vec->at(i) = nullptr;
98 }
99 }
100 return ret;
101 }
102
103 template <typename T>
VectorReplace(std::vector<T> * vec,T srcElement,T dstElement)104 bool VectorReplace(std::vector<T> *vec, T srcElement, T dstElement) {
105 bool ret = false;
106 for (auto iter = vec->begin(); iter != vec->end(); iter++) {
107 if (*iter == srcElement) {
108 if (!IsContain(*vec, dstElement)) {
109 *iter = std::move(dstElement);
110 } else {
111 vec->erase(iter);
112 }
113 ret = true;
114 break;
115 }
116 }
117 return ret;
118 }
119
120 template <typename T>
ShapeVectorToStr(const std::vector<T> & shape)121 std::string ShapeVectorToStr(const std::vector<T> &shape) {
122 std::ostringstream oss;
123 bool first_dim = true;
124 oss << "[";
125 for (auto &x : shape) {
126 if (!first_dim) {
127 oss << ", ";
128 } else {
129 first_dim = false;
130 }
131 oss << x;
132 }
133 oss << "]";
134 return oss.str();
135 }
136
137 template <typename T>
VectorToStr(const std::vector<T> & list,std::function<std::string (const T &)> func)138 std::string VectorToStr(const std::vector<T> &list, std::function<std::string(const T &)> func) {
139 if (func == nullptr) {
140 return "";
141 }
142 std::ostringstream s_str;
143 s_str << "[";
144 for (size_t i = 0; i < list.size(); i++) {
145 s_str << func(list[i]);
146 if (i + 1 < list.size()) {
147 s_str << ", ";
148 }
149 }
150 s_str << "]";
151 return s_str.str();
152 }
153
154 template <typename T>
155 std::string VectorToStrJoin(const std::vector<T> &shape, const std::string &sep = ",") {
156 std::ostringstream oss;
157 bool first_dim = true;
158 for (auto &x : shape) {
159 if (!first_dim) {
160 oss << sep;
161 } else {
162 first_dim = false;
163 }
164 oss << x;
165 }
166 return oss.str();
167 }
168
169 template <typename K, typename V>
170 std::string MapToStrJoin(const std::map<K, V> &options, const std::string &kv_sep = ":",
171 const std::string &item_sep = ";") {
172 std::ostringstream oss;
173 bool first_dim = true;
174 for (auto &x : options) {
175 if (!first_dim) {
176 oss << item_sep;
177 } else {
178 first_dim = false;
179 }
180 oss << x.first << kv_sep << x.second;
181 }
182 return oss.str();
183 }
184
185 template <typename T>
CommonCheckTensorType(const std::vector<T * > & tensors,size_t index,TypeId input_type)186 bool CommonCheckTensorType(const std::vector<T *> &tensors, size_t index, TypeId input_type) {
187 if (tensors.at(index) == nullptr) {
188 MS_LOG(ERROR) << "Tensors index: " << index << " is a nullptr";
189 return false;
190 }
191 if (tensors.at(index)->data_type() != input_type) {
192 MS_LOG(ERROR) << "Invalid tensor[" << index << "] data_type: " << tensors.at(index)->data_type();
193 return false;
194 }
195 return true;
196 }
197
198 const char WHITESPACE[] = "\t\n\v\f\r ";
199 const char STR_TRUE[] = "true";
200 const char STR_FALSE[] = "false";
201
202 template <typename T>
ToString(T t)203 Option<std::string> ToString(T t) {
204 std::ostringstream out;
205 out << t;
206 if (!out.good()) {
207 return Option<std::string>(None());
208 }
209
210 return Option<std::string>(out.str());
211 }
212
213 template <>
ToString(bool value)214 inline Option<std::string> ToString(bool value) {
215 return value ? Option<std::string>(STR_TRUE) : Option<std::string>(STR_FALSE);
216 }
217
218 // get the file name from a given path
219 // for example: "/usr/bin", we will get "bin"
GetFileName(const std::string & path)220 inline std::string GetFileName(const std::string &path) {
221 if (path.empty()) {
222 MS_LOG(ERROR) << "string is empty";
223 return "";
224 }
225
226 char delim = '/';
227
228 size_t i = path.rfind(delim, path.length());
229 if (i != std::string::npos && i + 1 < path.length()) {
230 return (path.substr(i + 1, path.length() - i));
231 }
232
233 return "";
234 }
235
236 // trim the white space character in a string
237 // see also: macro WHITESPACE defined above
Trim(std::string * input)238 inline void Trim(std::string *input) {
239 if (input == nullptr) {
240 return;
241 }
242 if (input->empty()) {
243 return;
244 }
245
246 input->erase(0, input->find_first_not_of(WHITESPACE));
247 input->erase(input->find_last_not_of(WHITESPACE) + 1);
248 }
249
250 // to judge whether a string is starting with prefix
251 // for example: "hello world" is starting with "hello"
StartsWithPrefix(const std::string & source,const std::string & prefix)252 inline bool StartsWithPrefix(const std::string &source, const std::string &prefix) {
253 if (source.length() < prefix.length()) {
254 return false;
255 }
256
257 return (source.compare(0, prefix.length(), prefix) == 0);
258 }
259
260 // split string
261 std::vector<std::string> StrSplit(const std::string &str, const std::string &pattern);
262
263 bool ConvertStrToInt(const std::string &str, int *value);
264 bool ConvertStrToInt(const std::string &str, int64_t *value);
265
266 bool ParseShapeStr(const std::string &shape_str, std::vector<int64_t> *shape_ptr);
267
268 bool ParseShapeStr(const std::string &shape_str, std::vector<ShapeDim> *shape_ptr);
269 // tokenize string
270 std::vector<std::string> Tokenize(const std::string &src, const std::string &delimiters,
271 const Option<size_t> &max_token_num = Option<size_t>(None()));
272
273 enum RemoveSubStrMode { PREFIX, SUFFIX, ANY };
274
275 // remove redundant character
276 std::string RemoveSubStr(const std::string &from, const std::string &sub_str, RemoveSubStrMode mode = ANY);
277
278 // match version: x.y.z
279 std::string GetShortVersionStr(const std::string &str);
280
281 // compare string
282 bool IsVersionGreaterThan(const std::string &str1, const std::string &str2);
283
284 template <typename T>
GenericParseValue(const std::string & value)285 inline Option<T> GenericParseValue(const std::string &value) {
286 T ret;
287 std::istringstream input(value);
288 input >> ret;
289
290 if (input && input.eof()) {
291 return Option<T>(ret);
292 }
293
294 return Option<T>(None());
295 }
296
297 template <>
GenericParseValue(const std::string & value)298 inline Option<std::string> GenericParseValue(const std::string &value) {
299 return Option<std::string>(value);
300 }
301
302 template <>
GenericParseValue(const std::string & value)303 inline Option<bool> GenericParseValue(const std::string &value) {
304 if (value == "true") {
305 return Option<bool>(true);
306 } else if (value == "false") {
307 return Option<bool>(false);
308 }
309
310 return Option<bool>(None());
311 }
312
DataTypeSize(TypeId type)313 inline size_t DataTypeSize(TypeId type) {
314 switch (type) {
315 case kNumberTypeFloat64:
316 return sizeof(double);
317 case kNumberTypeFloat:
318 case kNumberTypeFloat32:
319 return sizeof(float);
320 case kNumberTypeInt8:
321 return sizeof(int8_t);
322 case kNumberTypeUInt8:
323 return sizeof(uint8_t);
324 case kNumberTypeFloat16:
325 case kNumberTypeBFloat16:
326 case kNumberTypeInt16:
327 return sizeof(int16_t);
328 case kNumberTypeInt32:
329 return sizeof(int32_t);
330 case kNumberTypeInt64:
331 return sizeof(int64_t);
332 case kNumberTypeUInt16:
333 return sizeof(uint16_t);
334 case kNumberTypeUInt32:
335 return sizeof(uint32_t);
336 case kNumberTypeUInt64:
337 return sizeof(uint64_t);
338 case kNumberTypeBool:
339 return sizeof(bool);
340 case kObjectTypeString:
341 return sizeof(char);
342 case kObjectTypeTensorType:
343 return 0;
344 case kMetaTypeTypeType:
345 return sizeof(int);
346 default:
347 MS_LOG(ERROR) << "Not support the type: " << type;
348 return 0;
349 }
350 }
351
352 inline bool FloatCompare(const float &a, const float &b = 0.0f) {
353 return std::fabs(a - b) <= std::numeric_limits<float>::epsilon();
354 }
355
JudgeDynamicShape(const std::vector<int> & shape)356 inline bool JudgeDynamicShape(const std::vector<int> &shape) {
357 if (shape.size() == 0) {
358 return true;
359 }
360 if (shape.size() == 1 && shape[0] == -1) {
361 return true;
362 }
363 return false;
364 }
365
JudgeDynamicShape(const std::vector<int64_t> & shape)366 inline bool JudgeDynamicShape(const std::vector<int64_t> &shape) {
367 if (shape.size() == 0) {
368 return true;
369 }
370 if (shape.size() == 1 && shape[0] == -1) {
371 return true;
372 }
373 return false;
374 }
375
StringTolower(const std::string & str)376 inline std::string StringTolower(const std::string &str) {
377 std::string ret = str;
378 std::transform(ret.begin(), ret.end(), ret.begin(), [](unsigned char c) { return std::tolower(c); });
379 return ret;
380 }
381 } // namespace lite
382 } // namespace mindspore
383
384 #endif // MINDSPORE_LITE_SRC_COMMON_UTILS_H_
385