[utils] Add getRealpath function
[platform/core/ml/nntrainer.git] / nntrainer / utils / util_func.cpp
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.cpp
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 #ifdef _WIN32
24 #define MAX_PATH_LENGTH 1024
25 #endif
26
27 #include <cmath>
28 #include <fstream>
29 #include <random>
30
31 #include <nntrainer_log.h>
32 #include <util_func.h>
33
34 namespace nntrainer {
35
36 static auto rng = [] {
37   std::mt19937 rng;
38   rng.seed(getSeed());
39   return rng;
40 }();
41 static std::uniform_real_distribution<float> dist(-0.5, 0.5);
42
43 unsigned int getSeed() { return 0; }
44
45 float sqrtFloat(float x) { return sqrt(x); };
46
47 double sqrtDouble(double x) { return sqrt(x); };
48
49 float logFloat(float x) { return log(x + 1.0e-20); }
50
51 float exp_util(float x) { return exp(x); }
52
53 Tensor rotate_180(Tensor in) {
54   Tensor output(in.getDim());
55   output.setZero();
56   for (unsigned int i = 0; i < in.batch(); ++i) {
57     for (unsigned int j = 0; j < in.channel(); ++j) {
58       for (unsigned int k = 0; k < in.height(); ++k) {
59         for (unsigned int l = 0; l < in.width(); ++l) {
60           output.setValue(
61             i, j, k, l,
62             in.getValue(i, j, (in.height() - k - 1), (in.width() - l - 1)));
63         }
64       }
65     }
66   }
67   return output;
68 }
69
70 bool isFileExist(std::string file_name) {
71   std::ifstream infile(file_name);
72   return infile.good();
73 }
74
75 template <typename T>
76 static void checkFile(const T &file, const char *error_msg) {
77   if (file.bad() | file.eof() | !file.good() | file.fail()) {
78     throw std::runtime_error(error_msg);
79   }
80 }
81
82 void checkedRead(std::ifstream &file, char *array, std::streamsize size,
83                  const char *error_msg) {
84   file.read(array, size);
85
86   checkFile(file, error_msg);
87 }
88
89 void checkedWrite(std::ostream &file, const char *array, std::streamsize size,
90                   const char *error_msg) {
91   file.write(array, size);
92
93   checkFile(file, error_msg);
94 }
95
96 std::string readString(std::ifstream &file, const char *error_msg) {
97   std::string str;
98   size_t size;
99
100   checkedRead(file, (char *)&size, sizeof(size), error_msg);
101   str.resize(size);
102   checkedRead(file, (char *)&str[0], size, error_msg);
103
104   return str;
105 }
106
107 void writeString(std::ofstream &file, const std::string &str,
108                  const char *error_msg) {
109   size_t size = str.size();
110
111   checkedWrite(file, (char *)&size, sizeof(size), error_msg);
112   checkedWrite(file, (char *)&str[0], size, error_msg);
113 }
114
115 bool endswith(const std::string &target, const std::string &suffix) {
116   if (target.size() < suffix.size()) {
117     return false;
118   }
119   size_t spos = target.size() - suffix.size();
120   return target.substr(spos) == suffix;
121 }
122
123 int getKeyValue(const std::string &input_str, std::string &key,
124                 std::string &value) {
125   int status = ML_ERROR_NONE;
126   auto input_trimmed = input_str;
127
128   std::vector<std::string> list;
129   static const std::regex words_regex("[^\\s=]+");
130   input_trimmed.erase(
131     std::remove(input_trimmed.begin(), input_trimmed.end(), ' '),
132     input_trimmed.end());
133   auto words_begin = std::sregex_iterator(input_trimmed.begin(),
134                                           input_trimmed.end(), words_regex);
135   auto words_end = std::sregex_iterator();
136   int nwords = std::distance(words_begin, words_end);
137
138   if (nwords != 2) {
139     ml_loge("Error: input string must be 'key = value' format "
140             "(e.g.{\"key1=value1\",\"key2=value2\"}), \"%s\" given",
141             input_trimmed.c_str());
142     return ML_ERROR_INVALID_PARAMETER;
143   }
144
145   for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
146     list.push_back((*i).str());
147   }
148
149   key = list[0];
150   value = list[1];
151
152   return status;
153 }
154
155 int getValues(int n_str, std::string str, int *value) {
156   int status = ML_ERROR_NONE;
157   static const std::regex words_regex("[^\\s.,:;!?]+");
158   str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
159   auto words_begin = std::sregex_iterator(str.begin(), str.end(), words_regex);
160   auto words_end = std::sregex_iterator();
161
162   int num = std::distance(words_begin, words_end);
163   if (num != n_str) {
164     ml_loge("Number of Data is not match");
165     return ML_ERROR_INVALID_PARAMETER;
166   }
167   int cn = 0;
168   for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
169     value[cn] = std::stoi((*i).str());
170     cn++;
171   }
172   return status;
173 }
174
175 std::vector<std::string> split(const std::string &s, const std::regex &reg) {
176   std::vector<std::string> out;
177   const int NUM_SKIP_CHAR = 3;
178   char char_to_remove[NUM_SKIP_CHAR] = {' ', '[', ']'};
179   std::string str = s;
180   for (unsigned int i = 0; i < NUM_SKIP_CHAR; ++i) {
181     str.erase(std::remove(str.begin(), str.end(), char_to_remove[i]),
182               str.end());
183   }
184   std::regex_token_iterator<std::string::iterator> end;
185   std::regex_token_iterator<std::string::iterator> iter(str.begin(), str.end(),
186                                                         reg, -1);
187
188   while (iter != end) {
189     out.push_back(*iter);
190     ++iter;
191   }
192   return out;
193 }
194
195 bool istrequal(const std::string &a, const std::string &b) {
196   if (a.size() != b.size())
197     return false;
198
199   return std::equal(a.begin(), a.end(), b.begin(), [](char a_, char b_) {
200     return tolower(a_) == tolower(b_);
201   });
202 }
203
204 char *getRealpath(const char *name, char *resolved) {
205 #ifdef _WIN32
206   return _fullpath(resolved, name, MAX_PATH_LENGTH);
207 #else
208   return realpath(name, resolved);
209 #endif
210 }
211
212 } // namespace nntrainer