[layers/activation_func] Apply template on activation functions
[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 <random>
34
35 // /**
36 //  * @brief     get the seed
37 //  * @return    seed
38 //  */
39 // unsigned int getSeed() { return 0; }
40
41 namespace nntrainer {
42
43 #define NN_RETURN_STATUS()         \
44   do {                             \
45     if (status != ML_ERROR_NONE) { \
46       return status;               \
47     }                              \
48   } while (0)
49
50 /**
51  * @brief convert integer based status to throw
52  *
53  * @param status status to throw
54  */
55 inline void throw_status(int status) {
56   switch (status) {
57   case ML_ERROR_NONE:
58     break;
59   case ML_ERROR_INVALID_PARAMETER:
60     throw std::invalid_argument("invalid argument from c style throw");
61   case ML_ERROR_OUT_OF_MEMORY:
62     throw std::bad_alloc();
63   case ML_ERROR_TIMED_OUT:
64     throw std::runtime_error("Timed out from c style throw");
65   case ML_ERROR_PERMISSION_DENIED:
66     throw std::runtime_error("permission denied from c style throw");
67   case ML_ERROR_UNKNOWN:
68   default:
69     throw std::runtime_error("unknown error from c style throw");
70   }
71 }
72
73 static auto rng = [] {
74   std::mt19937 rng;
75   // rng.seed(getSeed());
76   rng.seed(0);
77   return rng;
78 }();
79
80 /**
81  * @brief     sqrt function for float type
82  * @param[in] x float
83  */
84 float sqrtFloat(float x);
85
86 /**
87  * @brief    sqrt function for dobuld type
88  *
89  * @param x value to take sqrt
90  * @return double return value
91  */
92 double sqrtDouble(double x);
93
94 /**
95  * @brief     log function for float type
96  * @param[in] x float
97  */
98 float logFloat(float x);
99
100 /**
101  * @brief     exp function for float type
102  * @param[in] x float
103  */
104
105 template <typename T = float> T exp_util(T x) { return static_cast<T>(exp(x)); }
106
107 /**
108  * @brief     Check Existance of File
109  * @param[in] file path of the file to be checked
110  * @returns   true if file exists, else false
111  */
112 bool isFileExist(std::string file);
113
114 constexpr const char *default_error_msg =
115   "[util::checkeFile] file operation failed";
116
117 /**
118  * @brief same as file.read except it checks if fail to read the file
119  *
120  * @param file file to read
121  * @param array char * array
122  * @param size size of the array
123  * @param error_msg error msg to print when operation fail
124  * @throw std::runtime_error if file.fail() is true after read.
125  */
126 void checkedRead(std::ifstream &file, char *array, std::streamsize size,
127                  const char *error_msg = default_error_msg);
128
129 /**
130  * @brief same as file.write except it checks if fail to write the file
131  *
132  * @param file file to write
133  * @param array char * array
134  * @param size size of the array
135  * @param error_msg error msg to print when operation fail
136  * @throw std::runtime_error if file.fail() is true after write.
137  */
138 void checkedWrite(std::ostream &file, const char *array, std::streamsize size,
139                   const char *error_msg = default_error_msg);
140 /**
141  * @brief read string from a binary file
142  *
143  * @param file file to input
144  * @return std::string result string
145  */
146 std::string readString(std::ifstream &file,
147                        const char *error_msg = default_error_msg);
148
149 /**
150  * @brief write string to a binary file
151  *
152  * @param file file to write
153  * @param str target string to write
154  */
155 void writeString(std::ofstream &file, const std::string &str,
156                  const char *error_msg = default_error_msg);
157
158 /**
159  * @brief check if string ends with @a suffix
160  *
161  * @param target string to cehck
162  * @param suffix check if string ends with @a suffix
163  * @retval true @a target ends with @a suffix
164  * @retval false @a target does not ends with @a suffix
165  */
166 bool endswith(const std::string &target, const std::string &suffix);
167
168 /**
169  * @brief     print instance info. as <Type at (address)>
170  * @param[in] std::ostream &out, T&& t
171  * @param[in] t pointer to the instance
172  */
173 template <typename T,
174           typename std::enable_if_t<std::is_pointer<T>::value, T> * = nullptr>
175 void printInstance(std::ostream &out, const T &t) {
176   out << '<' << typeid(*t).name() << " at " << t << '>' << std::endl;
177 }
178
179 /**
180  * @brief creat a stream, and if !stream.good() throw appropriate error code
181  * depending on @c errno
182  *
183  * @tparam T return type
184  * @param path path
185  * @param mode mode to open path
186  * @return T created stream
187  */
188 template <typename T>
189 T checkedOpenStream(const std::string &path, std::ios_base::openmode mode) {
190   T model_file(path, mode);
191   if (!model_file.good()) {
192     const size_t error_buflen = 100;
193     char error_buf[error_buflen];
194     std::stringstream ss;
195     ss << "[parseutil] requested file not opened, file path: " << path
196        << " reason: " << strerror_r(errno, error_buf, error_buflen);
197     if (errno == EPERM || errno == EACCES) {
198       throw nntrainer::exception::permission_denied(ss.str().c_str());
199     } else {
200       throw std::invalid_argument(ss.str().c_str());
201     }
202   }
203
204   return model_file;
205 }
206
207 /**
208  * @brief     parse string and return key & value
209  * @param[in] input_str input string to split with '='
210  * @param[out] key key
211  * @param[out] value value
212  * @retval #ML_ERROR_NONE Successful.
213  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
214  */
215 int getKeyValue(const std::string &input_str, std::string &key,
216                 std::string &value);
217
218 /**
219  * @brief     parse string and stored to int
220  * @param[in] n_str number of data
221  * @param[in] str string to parse
222  * @param[in] value int value to stored
223  * @retval #ML_ERROR_NONE Successful.
224  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
225  */
226 int getValues(int n_str, std::string str, int *value);
227
228 /**
229  * @brief     split string into vector with delimiter regex
230  * @param[in] str string
231  * @param[in] reg regular expression to use as delimiter
232  * @retval    output string vector
233  */
234 std::vector<std::string> split(const std::string &s, const std::regex &reg);
235
236 /**
237  * @brief Cast insensitive string comparison
238  *
239  * @param a first string to compare
240  * @param b second string to compare
241  * @retval true if string is case-insensitive equal
242  * @retval false if string is case-insensitive not equal
243  */
244 bool istrequal(const std::string &a, const std::string &b);
245
246 /**
247  * @brief Perform INT_LOGICAL_AND operation on enum class value
248  *
249  * @param e1 enum value
250  * @param e2 enum value
251  *
252  * @return enum value after performing logical AND operation
253  */
254 template <typename T, typename C = int>
255 bool enum_class_logical_and(T e1, T e2) {
256   C i1 = static_cast<int>(e1);
257   C i2 = static_cast<int>(e2);
258
259   return (i1 & i2) != 0;
260 }
261
262 /**
263  * @brief Perform INT_OR operation on enum class value
264  *
265  * @param e1 enum value
266  * @param e2 enum value
267  *
268  * @return enum value after performing OR operation
269  */
270 template <typename T, typename C = int> T enum_class_or(T e1, T e2) {
271   C i1 = static_cast<int>(e1);
272   C i2 = static_cast<int>(e2);
273
274   return static_cast<T>(i1 | i2);
275 }
276
277 /**
278  * @brief Convert a relative path into an absolute path.
279  *
280  * @param name relative path
281  * @param resolved variable to store the result value.
282  *
283  * @return absolute path
284  */
285 char *getRealpath(const char *name, char *resolved);
286
287 /**
288  * @brief Get local time in tm struct format
289  *
290  * @param tp variable to store the result values
291  *
292  * @return tm struct
293  */
294 tm *getLocaltime(tm *tp);
295
296 } /* namespace nntrainer */
297
298 #endif /* __cplusplus */
299 #endif /* __UTIL_FUNC_H__ */