LCOV - code coverage report
Current view: top level - nntrainer/utils - util_func.h (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 71.0 % 62 44
Test Date: 2025-12-14 20:38:17 Functions: 39.5 % 43 17

            Line data    Source code
       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              : #include <variant>
      35              : 
      36              : // /**
      37              : //  * @brief     get the seed
      38              : //  * @return    seed
      39              : //  */
      40              : // unsigned int getSeed() { return 0; }
      41              : 
      42              : namespace nntrainer {
      43              : using ReadSource = std::variant<std::ifstream *, const char *>;
      44              : 
      45              : #define NN_RETURN_STATUS()                                                     \
      46              :   do {                                                                         \
      47              :     if (status != ML_ERROR_NONE) {                                             \
      48              :       return status;                                                           \
      49              :     }                                                                          \
      50              :   } while (0)
      51              : 
      52              : /**
      53              :  * @brief convert integer based status to throw
      54              :  *
      55              :  * @param status status to throw
      56              :  */
      57          351 : inline void throw_status(int status) {
      58          351 :   switch (status) {
      59              :   case ML_ERROR_NONE:
      60              :     break;
      61            1 :   case ML_ERROR_INVALID_PARAMETER:
      62            1 :     throw std::invalid_argument("invalid argument from c style throw");
      63            1 :   case ML_ERROR_OUT_OF_MEMORY:
      64            1 :     throw std::bad_alloc();
      65            1 :   case ML_ERROR_TIMED_OUT:
      66            1 :     throw std::runtime_error("Timed out from c style throw");
      67            1 :   case ML_ERROR_PERMISSION_DENIED:
      68            1 :     throw std::runtime_error("permission denied from c style throw");
      69            4 :   case ML_ERROR_UNKNOWN:
      70              :   default:
      71            4 :     throw std::runtime_error("unknown error from c style throw");
      72              :   }
      73          343 : }
      74              : 
      75         6047 : static auto rng = [] {
      76              :   std::mt19937 rng;
      77              :   // rng.seed(getSeed());
      78              :   rng.seed(0);
      79         6047 :   return rng;
      80              : }();
      81              : 
      82              : /**
      83              :  * @brief     sqrt function for float type
      84              :  * @param[in] x float
      85              :  */
      86            0 : template <typename T = float> T sqrtFloat(T x) {
      87         2296 :   return static_cast<T>(sqrt((float)x));
      88              : }
      89              : 
      90              : /**
      91              :  * @brief    sqrt function for dobuld type
      92              :  *
      93              :  * @param x value to take sqrt
      94              :  * @return double return value
      95              :  */
      96              : double sqrtDouble(double x);
      97              : 
      98              : /**
      99              :  * @brief     abs function for float type
     100              :  * @param[in] x float
     101              :  */
     102              : template <typename T = float> T absFloat(T x) {
     103              :   return static_cast<T>(abs((float)x));
     104              : }
     105              : 
     106              : /**
     107              :  * @brief     log function for float type
     108              :  * @param[in] x float
     109              :  */
     110       120170 : template <typename T = float> T logFloat(T x) {
     111       120170 :   return static_cast<T>(log(x + 1.0e-20));
     112              : }
     113              : 
     114              : /**
     115              :  * @brief     exp function for float type
     116              :  * @param[in] x float
     117              :  */
     118     28449870 : template <typename T = float> T exp_util(T x) { return static_cast<T>(exp(x)); }
     119              : 
     120              : uint32_t ceilDiv(uint32_t a, uint32_t b);
     121              : 
     122              : uint32_t align(uint32_t a, uint32_t b);
     123              : 
     124              : #ifdef _WIN32
     125              : #ifdef _Float16
     126              : template <> _Float16 exp_util<_Float16>(_Float16 x) {
     127              :   return static_cast<_Float16>(std::exp(static_cast<float>(x)));
     128              : }
     129              : #endif
     130              : #endif
     131              : 
     132              : /**
     133              :  * @brief     Check if float is not nan and not inf
     134              :  * @param[in] value float
     135              :  * @note      We can switch to use std::isfinite once it will start support half
     136              :  floats
     137              :  */
     138              : template <typename T> bool isFloatValid(const T value) {
     139           14 :   return !((value != value) ||
     140           28 :            (value == std::numeric_limits<float>::infinity()) ||
     141              :            (value == -std::numeric_limits<float>::infinity()));
     142              : }
     143              : 
     144              : /**
     145              :  * @brief     Check Existance of File
     146              :  * @param[in] file path of the file to be checked
     147              :  * @returns   true if file exists, else false
     148              :  */
     149              : bool isFileExist(std::string file);
     150              : 
     151              : constexpr const char *default_error_msg =
     152              :   "[util::checkeFile] file operation failed";
     153              : 
     154              : /**
     155              :  * @brief same as file.read except it checks if fail to read the file
     156              :  *
     157              :  * @param file file to read
     158              :  * @param array char * array
     159              :  * @param size size of the array
     160              :  * @param error_msg error msg to print when operation fail
     161              :  * @throw std::runtime_error if file.fail() is true after read.
     162              :  */
     163              : void checkedRead(std::ifstream &file, char *array, std::streamsize size,
     164              :                  const char *error_msg = default_error_msg,
     165              :                  size_t start_offset = 0, bool read_from_offset = false);
     166              : 
     167              : /**
     168              :  * @brief same as file.read except it checks if fail to read the file
     169              :  *
     170              :  * @param ReadSource Source to read
     171              :  * @param array char * array
     172              :  * @param size size of the array
     173              :  * @param error_msg error msg to print when operation fail
     174              :  * @throw std::runtime_error if file.fail() is true after read.
     175              :  */
     176              : void checkedRead(ReadSource src, char *array, std::streamsize size,
     177              :                  const char *error_msg, size_t start_offset,
     178              :                  bool read_from_offset);
     179              : 
     180              : /**
     181              :  * @brief same as file.write except it checks if fail to write the file
     182              :  *
     183              :  * @param file file to write
     184              :  * @param array char * array
     185              :  * @param size size of the array
     186              :  * @param error_msg error msg to print when operation fail
     187              :  * @throw std::runtime_error if file.fail() is true after write.
     188              :  */
     189              : void checkedWrite(std::ostream &file, const char *array, std::streamsize size,
     190              :                   const char *error_msg = default_error_msg);
     191              : /**
     192              :  * @brief read string from a binary file
     193              :  *
     194              :  * @param file file to input
     195              :  * @return std::string result string
     196              :  */
     197              : std::string readString(std::ifstream &file,
     198              :                        const char *error_msg = default_error_msg);
     199              : 
     200              : /**
     201              :  * @brief write string to a binary file
     202              :  *
     203              :  * @param file file to write
     204              :  * @param str target string to write
     205              :  */
     206              : void writeString(std::ofstream &file, const std::string &str,
     207              :                  const char *error_msg = default_error_msg);
     208              : 
     209              : /**
     210              :  * @brief check if string ends with @a suffix
     211              :  *
     212              :  * @param target string to cehck
     213              :  * @param suffix check if string ends with @a suffix
     214              :  * @retval true @a target ends with @a suffix
     215              :  * @retval false @a target does not ends with @a suffix
     216              :  */
     217              : bool endswith(const std::string &target, const std::string &suffix);
     218              : 
     219              : /**
     220              :  * @brief     print instance info. as <Type at (address)>
     221              :  * @param[in] std::ostream &out, T&& t
     222              :  * @param[in] t pointer to the instance
     223              :  */
     224              : template <typename T,
     225              :           typename std::enable_if_t<std::is_pointer<T>::value, T> * = nullptr>
     226           11 : void printInstance(std::ostream &out, const T &t) {
     227           22 :   out << '<' << typeid(*t).name() << " at " << t << '>' << std::endl;
     228           11 : }
     229              : 
     230              : /**
     231              :  * @brief make "key=value" from key and value
     232              :  *
     233              :  * @tparam T type of a value
     234              :  * @param key key
     235              :  * @param value value
     236              :  * @return std::string with "key=value"
     237              :  */
     238              : template <typename T>
     239           83 : static std::string withKey(const std::string &key, const T &value) {
     240           83 :   std::stringstream ss;
     241           83 :   ss << key << "=" << value;
     242           83 :   return ss.str();
     243           83 : }
     244              : 
     245              : /**
     246              :  * @brief make "key=value1,value2,...valueN" from key and multiple values
     247              :  *
     248              :  * @tparam T type of a value
     249              :  * @param key key
     250              :  * @param value list of values
     251              :  * @return std::string with "key=value1,value2,...valueN"
     252              :  */
     253              : template <typename T>
     254            8 : static std::string withKey(const std::string &key,
     255              :                            std::initializer_list<T> value) {
     256            8 :   if (std::empty(value)) {
     257            0 :     throw std::invalid_argument("empty data cannot be converted");
     258              :   }
     259            8 :   std::stringstream ss;
     260            8 :   ss << key << "=";
     261              :   auto iter = value.begin();
     262           16 :   for (; iter != value.end() - 1; ++iter) {
     263            8 :     ss << *iter << ',';
     264              :   }
     265            8 :   ss << *iter;
     266            8 :   return ss.str();
     267            8 : }
     268              : 
     269              : /**
     270              :  * @brief creat a stream, and if !stream.good() throw appropriate error code
     271              :  * depending on @c errno
     272              :  *
     273              :  * @tparam T return type
     274              :  * @param path path
     275              :  * @param mode mode to open path
     276              :  * @return T created stream
     277              :  */
     278              : template <typename T>
     279         2090 : T checkedOpenStream(const std::string &path, std::ios_base::openmode mode) {
     280         2090 :   T model_file(path, mode);
     281         2090 :   if (!model_file.good()) {
     282              :     const size_t error_buflen = 100;
     283              :     char error_buf[error_buflen];
     284            0 :     std::stringstream ss;
     285              :     ss << "[parseutil] requested file not opened, file path: " << path
     286            0 :        << " reason: " << SAFE_STRERROR(errno, error_buf, error_buflen);
     287            0 :     if (errno == EPERM || errno == EACCES) {
     288            0 :       throw nntrainer::exception::permission_denied(ss.str().c_str());
     289              :     } else {
     290            0 :       throw std::invalid_argument(ss.str().c_str());
     291              :     }
     292            0 :   }
     293              : 
     294         2090 :   return model_file;
     295            0 : }
     296              : 
     297              : /**
     298              :  * @brief     parse string and return key & value
     299              :  * @param[in] input_str input string to split with '='
     300              :  * @param[out] key key
     301              :  * @param[out] value value
     302              :  * @retval #ML_ERROR_NONE Successful.
     303              :  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
     304              :  */
     305              : int getKeyValue(const std::string &input_str, std::string &key,
     306              :                 std::string &value);
     307              : 
     308              : /**
     309              :  * @brief     parse string and stored to int
     310              :  * @param[in] n_str number of data
     311              :  * @param[in] str string to parse
     312              :  * @param[in] value int value to stored
     313              :  * @retval #ML_ERROR_NONE Successful.
     314              :  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
     315              :  */
     316              : int getValues(int n_str, std::string str, int *value);
     317              : 
     318              : /**
     319              :  * @brief     split string into vector with delimiter regex
     320              :  * @param[in] str string
     321              :  * @param[in] reg regular expression to use as delimiter
     322              :  * @retval    output string vector
     323              :  */
     324              : std::vector<std::string> split(const std::string &s, const std::regex &reg);
     325              : 
     326              : /**
     327              :  * @brief Cast insensitive string comparison
     328              :  *
     329              :  * @param a first string to compare
     330              :  * @param b second string to compare
     331              :  * @retval true if string is case-insensitive equal
     332              :  * @retval false if string is case-insensitive not equal
     333              :  */
     334              : bool istrequal(const std::string &a, const std::string &b);
     335              : 
     336              : /**
     337              :  * @brief Perform INT_LOGICAL_AND operation on enum class value
     338              :  *
     339              :  * @param e1 enum value
     340              :  * @param e2 enum value
     341              :  *
     342              :  * @return enum value after performing logical AND operation
     343              :  */
     344              : template <typename T, typename C = int>
     345              : bool enum_class_logical_and(T e1, T e2) {
     346              :   C i1 = static_cast<int>(e1);
     347              :   C i2 = static_cast<int>(e2);
     348              : 
     349        10552 :   return (i1 & i2) != 0;
     350              : }
     351              : 
     352              : /**
     353              :  * @brief Perform INT_OR operation on enum class value
     354              :  *
     355              :  * @param e1 enum value
     356              :  * @param e2 enum value
     357              :  *
     358              :  * @return enum value after performing OR operation
     359              :  */
     360              : template <typename T, typename C = int> T enum_class_or(T e1, T e2) {
     361              :   C i1 = static_cast<int>(e1);
     362              :   C i2 = static_cast<int>(e2);
     363              : 
     364        65725 :   return static_cast<T>(i1 | i2);
     365              : }
     366              : 
     367              : /**
     368              :  * @brief Find value in tuple by key (internal impl)
     369              :  *
     370              :  * @tparam Tuple Tuple type to search
     371              :  * @tparam ls... Tuple index sequence
     372              :  * @param t Tuple to search
     373              :  * @param key Key to find
     374              :  *
     375              :  * @return Found value or empty string
     376              :  */
     377              : template <typename Tuple, std::size_t... ls>
     378            0 : std::string find_in_tuple(const Tuple &t, std::index_sequence<ls...>,
     379              :                           const std::string &key) {
     380            0 :   std::string result = "";
     381              : 
     382            0 :   (..., ([&] {
     383            0 :      auto &&elem = std::get<ls>(t);
     384            0 :      if (strcmp(getPropKey(elem), key.c_str()) == 0) {
     385            0 :        result = elem.empty() ? "empty" : to_string(elem);
     386              :      }
     387            0 :    }()));
     388              : 
     389            0 :   return result;
     390              : }
     391              : 
     392              : /**
     393              :  * @brief Find value in tuple by key (user-friendly wrapper)
     394              :  *
     395              :  * @tparam Args Tuple element types
     396              :  * @param t Tuple to search
     397              :  * @param key Key to find
     398              :  *
     399              :  * @return Found value or empty string
     400              :  */
     401              : template <typename... Args>
     402              : std::string find_in_tuple(const std::tuple<Args...> &t,
     403              :                           const std::string &key) {
     404            0 :   return find_in_tuple(t, std::index_sequence_for<Args...>{}, key);
     405              : }
     406              : 
     407              : /**
     408              :  * @brief Convert a relative path into an absolute path.
     409              :  *
     410              :  * @param name relative path
     411              :  * @param resolved variable to store the result value.
     412              :  *
     413              :  * @return absolute path
     414              :  */
     415              : char *getRealpath(const char *name, char *resolved);
     416              : 
     417              : /**
     418              :  * @brief Get local time in tm struct format
     419              :  *
     420              :  * @param tp variable to store the result values
     421              :  *
     422              :  * @return tm struct
     423              :  */
     424              : tm *getLocaltime(tm *tp);
     425              : 
     426              : /**
     427              :  * @brief Create and return std::regex with the received string
     428              :  * @param str String in regular expression form
     429              :  * @return std::regex
     430              :  */
     431              : std::regex getRegex(const std::string &str);
     432              : 
     433              : /**
     434              :  * @brief  Convert a floating-point number into its fixed-point component (the
     435              :  * mantissa) and its exponent component.
     436              :  *
     437              :  * @param[in] input floating point to convert
     438              :  * @param[out] fixedpoint fixed-point
     439              :  * @param[out] exponent exponent
     440              :  */
     441              : void floatToFixedPointAndExponent(float input, int &fixedpoint, int &exponent);
     442              : 
     443              : /**
     444              :  * @brief Convert a fixed-point number and an exponent into a floating-point
     445              :  * number.
     446              :  *
     447              :  * @param[in] fixedpoint fixed-point
     448              :  * @param[in] exponent exponent
     449              :  * @return floating point result
     450              :  */
     451              : float fixedPointAndExponentToFloat(int fixedpoint, int exponent);
     452              : 
     453              : } /* namespace nntrainer */
     454              : 
     455              : #endif /* __cplusplus */
     456              : #endif /* __UTIL_FUNC_H__ */
        

Generated by: LCOV version 2.0-1