5147accb9d2f98ba98970af8a661267520600aed
[platform/core/ml/nntrainer.git] / nntrainer / utils / util_func.h
1 /**
2  * Copyright (C) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
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  *   http://www.apache.org/licenses/LICENSE-2.0
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  *
14  * @file        util_func.h
15  * @date        08 April 2020
16  * @brief       This is collection of math functions.
17  * @see         https://github.com/nnstreamer/nntrainer
18  * @author      Jijoong Moon <jijoong.moon@samsung.com>
19  * @bug         No known bugs except for NYI items
20  *
21  */
22
23 #ifndef __UTIL_FUNC_H__
24 #define __UTIL_FUNC_H__
25
26 #ifdef __cplusplus
27
28 #include <cstring>
29 #include <regex>
30 #include <sstream>
31
32 #include <nntrainer_error.h>
33 #include <tensor.h>
34
35 namespace nntrainer {
36
37 #define NN_RETURN_STATUS()         \
38   do {                             \
39     if (status != ML_ERROR_NONE) { \
40       return status;               \
41     }                              \
42   } while (0)
43
44 /**
45  * @brief convert integer based status to throw
46  *
47  * @param status status to throw
48  */
49 inline void throw_status(int status) {
50   switch (status) {
51   case ML_ERROR_NONE:
52     break;
53   case ML_ERROR_INVALID_PARAMETER:
54     throw std::invalid_argument("invalid argument from c style throw");
55   case ML_ERROR_OUT_OF_MEMORY:
56     throw std::bad_alloc();
57   case ML_ERROR_TIMED_OUT:
58     throw std::runtime_error("Timed out from c style throw");
59   case ML_ERROR_PERMISSION_DENIED:
60     throw std::runtime_error("permission denied from c style throw");
61   case ML_ERROR_UNKNOWN:
62   default:
63     throw std::runtime_error("unknown error from c style throw");
64   }
65 }
66
67 /**
68  * @brief     get the seed
69  * @return    seed
70  */
71 unsigned int getSeed();
72
73 /**
74  * @brief     sqrt function for float type
75  * @param[in] x float
76  */
77 float sqrtFloat(float x);
78
79 /**
80  * @brief    sqrt function for dobuld type
81  *
82  * @param x value to take sqrt
83  * @return double return value
84  */
85 double sqrtDouble(double x);
86
87 /**
88  * @brief     log function for float type
89  * @param[in] x float
90  */
91 float logFloat(float x);
92
93 /**
94  * @brief     exp function for float type
95  * @param[in] x float
96  */
97 float exp_util(float x);
98
99 /**
100  * @brief     rotate 180 dgree
101  * @param[in] in input Tensor
102  * @retVal Tensor rotated tensor (180 degree)
103  */
104 Tensor rotate_180(Tensor in);
105
106 /**
107  * @brief     Check Existance of File
108  * @param[in] file path of the file to be checked
109  * @returns   true if file exists, else false
110  */
111 bool isFileExist(std::string file);
112
113 constexpr const char *default_error_msg =
114   "[util::checkeFile] file operation failed";
115
116 /**
117  * @brief same as file.read except it checks if fail to read the file
118  *
119  * @param file file to read
120  * @param array char * array
121  * @param size size of the array
122  * @param error_msg error msg to print when operation fail
123  * @throw std::runtime_error if file.fail() is true after read.
124  */
125 void checkedRead(std::ifstream &file, char *array, std::streamsize size,
126                  const char *error_msg = default_error_msg);
127
128 /**
129  * @brief same as file.write except it checks if fail to write the file
130  *
131  * @param file file to write
132  * @param array char * array
133  * @param size size of the array
134  * @param error_msg error msg to print when operation fail
135  * @throw std::runtime_error if file.fail() is true after write.
136  */
137 void checkedWrite(std::ostream &file, const char *array, std::streamsize size,
138                   const char *error_msg = default_error_msg);
139 /**
140  * @brief read string from a binary file
141  *
142  * @param file file to input
143  * @return std::string result string
144  */
145 std::string readString(std::ifstream &file,
146                        const char *error_msg = default_error_msg);
147
148 /**
149  * @brief write string to a binary file
150  *
151  * @param file file to write
152  * @param str target string to write
153  */
154 void writeString(std::ofstream &file, const std::string &str,
155                  const char *error_msg = default_error_msg);
156
157 /**
158  * @brief check if string ends with @a suffix
159  *
160  * @param target string to cehck
161  * @param suffix check if string ends with @a suffix
162  * @retval true @a target ends with @a suffix
163  * @retval false @a target does not ends with @a suffix
164  */
165 bool endswith(const std::string &target, const std::string &suffix);
166
167 /**
168  * @brief     print instance info. as <Type at (address)>
169  * @param[in] std::ostream &out, T&& t
170  * @param[in] t pointer to the instance
171  */
172 template <typename T,
173           typename std::enable_if_t<std::is_pointer<T>::value, T> * = nullptr>
174 void printInstance(std::ostream &out, const T &t) {
175   out << '<' << typeid(*t).name() << " at " << t << '>' << std::endl;
176 }
177
178 /**
179  * @brief creat a stream, and if !stream.good() throw appropriate error code
180  * depending on @c errno
181  *
182  * @tparam T return type
183  * @param path path
184  * @param mode mode to open path
185  * @return T created stream
186  */
187 template <typename T>
188 T checkedOpenStream(const std::string &path, std::ios_base::openmode mode) {
189   T model_file(path, mode);
190   if (!model_file.good()) {
191     std::stringstream ss;
192     ss << "[parseutil] requested file not opened, file path: " << path
193        << " reason: " << std::strerror(errno);
194     if (errno == EPERM || errno == EACCES) {
195       throw nntrainer::exception::permission_denied(ss.str().c_str());
196     } else {
197       throw std::invalid_argument(ss.str().c_str());
198     }
199   }
200
201   return model_file;
202 }
203
204 /**
205  * @brief     parse string and return key & value
206  * @param[in] input_str input string to split with '='
207  * @param[out] key key
208  * @param[out] value value
209  * @retval #ML_ERROR_NONE Successful.
210  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
211  */
212 int getKeyValue(const std::string &input_str, std::string &key,
213                 std::string &value);
214
215 /**
216  * @brief     parse string and stored to int
217  * @param[in] n_str number of data
218  * @param[in] str string to parse
219  * @param[in] value int value to stored
220  * @retval #ML_ERROR_NONE Successful.
221  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
222  */
223 int getValues(int n_str, std::string str, int *value);
224
225 /**
226  * @brief     split string into vector with delimiter regex
227  * @param[in] str string
228  * @param[in] reg regular expression to use as delimiter
229  * @retval    output string vector
230  */
231 std::vector<std::string> split(const std::string &s, const std::regex &reg);
232
233 /**
234  * @brief Cast insensitive string comparison
235  *
236  * @param a first string to compare
237  * @param b second string to compare
238  * @retval true if string is case-insensitive equal
239  * @retval false if string is case-insensitive not equal
240  */
241 bool istrequal(const std::string &a, const std::string &b);
242
243 /**
244  * @brief Perform INT_LOGICAL_AND operation on enum class value
245  *
246  * @param e1 enum value
247  * @param e2 enum value
248  *
249  * @return enum value after performing logical AND operation
250  */
251 template <typename T, typename C = int>
252 bool enum_class_logical_and(T e1, T e2) {
253   C i1 = static_cast<int>(e1);
254   C i2 = static_cast<int>(e2);
255
256   return (i1 & i2) != 0;
257 }
258
259 /**
260  * @brief Perform INT_OR operation on enum class value
261  *
262  * @param e1 enum value
263  * @param e2 enum value
264  *
265  * @return enum value after performing OR operation
266  */
267 template <typename T, typename C = int> T enum_class_or(T e1, T e2) {
268   C i1 = static_cast<int>(e1);
269   C i2 = static_cast<int>(e2);
270
271   return static_cast<T>(i1 | i2);
272 }
273
274 } /* namespace nntrainer */
275
276 #endif /* __cplusplus */
277 #endif /* __UTIL_FUNC_H__ */