• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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