[Ini] Propose ini wrapper
authorJihoon Lee <jhoon.it.lee@samsung.com>
Thu, 8 Apr 2021 08:43:42 +0000 (17:43 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Fri, 16 Apr 2021 02:23:16 +0000 (11:23 +0900)
This patch adds `IniSection` which was often used inside unittest.

Most codes are taken from the test directly.

**Self evaluation:**
1. Build test: [X]Passed [ ]Failed [ ]Skipped
2. Run test: [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: Jihoon Lee <jhoon.it.lee@samsung.com>
jni/Android.mk
nntrainer/utils/ini_wrapper.cpp [new file with mode: 0644]
nntrainer/utils/ini_wrapper.h [new file with mode: 0644]
nntrainer/utils/meson.build

index 2856b6d..7ac9b25 100644 (file)
@@ -125,6 +125,7 @@ NNTRAINER_SRCS := $(NNTRAINER_ROOT)/nntrainer/models/neuralnet.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/optimizers/sgd.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/optimizers/optimizer_factory.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/utils/util_func.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/utils/ini_wrapper.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/utils/parse_util.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/utils/profiler.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/compiler/ini_interpreter.cpp \
diff --git a/nntrainer/utils/ini_wrapper.cpp b/nntrainer/utils/ini_wrapper.cpp
new file mode 100644 (file)
index 0000000..c93344e
--- /dev/null
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
+ *
+ * @file ini_wrapper.cpp
+ * @date 08 April 2021
+ * @brief NNTrainer Ini Wrapper helps to save ini
+ * @note this is to be used with ini_interpreter
+ * @see        https://github.com/nnstreamer/nntrainer
+ * @author Jihoon Lee <jhoon.it.lee@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+#include <ini_wrapper.h>
+
+#include <nntrainer_error.h>
+#include <parse_util.h>
+#include <regex>
+
+namespace nntrainer {
+
+IniSection::IniSection(const std::string &name) : section_name(name) {}
+
+IniSection::IniSection(const std::string &section_name,
+                       const std::string &entry_str) :
+  IniSection(section_name) {
+  setEntry(entry_str);
+}
+
+IniSection::IniSection(IniSection &from, const std::string &section_name,
+                       const std::string &entry_str) :
+  IniSection(from) {
+  if (!section_name.empty()) {
+    this->section_name = section_name;
+  }
+  if (!entry_str.empty()) {
+    setEntry(entry_str);
+  }
+}
+
+void IniSection::print(std::ostream &out) {
+  out << '[' << section_name << ']' << std::endl;
+  for (auto &it : entry)
+    out << it.first << " = " << it.second << std::endl;
+}
+
+void IniSection::setEntry(const std::map<std::string, std::string> &entry) {
+  for (auto &it : entry) {
+    this->entry[it.first] = it.second;
+  }
+}
+
+void IniSection::setEntry(const std::string &entry_str) {
+  // setting property separated by "|"
+  std::regex words_regex("[^|]+");
+
+  auto words_begin =
+    std::sregex_iterator(entry_str.begin(), entry_str.end(), words_regex);
+  auto words_end = std::sregex_iterator();
+
+  std::string key, value;
+  for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
+    std::string cur = (*i).str();
+
+    if (cur[0] == '-') {
+      entry.erase(cur.substr(1));
+      continue;
+    }
+
+    int status = getKeyValue(cur, key, value);
+    NNTR_THROW_IF(status != ML_ERROR_NONE, std::invalid_argument)
+      << "getKeyValue Failed";
+    entry[key] = value;
+  }
+}
+
+} // namespace nntrainer
diff --git a/nntrainer/utils/ini_wrapper.h b/nntrainer/utils/ini_wrapper.h
new file mode 100644 (file)
index 0000000..4db98b9
--- /dev/null
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
+ *
+ * @file ini_wrapper.h
+ * @date 08 April 2021
+ * @brief NNTrainer Ini Wrapper helps to save ini
+ * @note this is to be used with ini_interpreter
+ * @see        https://github.com/nnstreamer/nntrainer
+ * @author Jihoon Lee <jhoon.it.lee@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <iostream>
+#include <map>
+#include <string>
+
+#ifndef __INI_WRAPPER_H__
+#define __INI_WRAPPER_H__
+
+namespace nntrainer {
+
+/**
+ * @brief IniSection class that maps to one ini section
+ * @todo consider API style setEntry function
+ *
+ */
+class IniSection {
+
+public:
+  /**
+   * @brief Construct a new Ini Section object
+   *
+   * @param name section name
+   */
+  IniSection(const std::string &name);
+
+  /**
+   * @brief Construct a new Ini Section object
+   *
+   * @param section_name section name
+   * @param entry_str entry representing string (separated by `|`)
+   */
+  IniSection(const std::string &section_name, const std::string &entry_str);
+
+  /**
+   * @brief Copy Construct a new Ini Section object
+   * @note this function copies entry from @a from and overwrite entry and
+   * section_name
+   *
+   * @param from Ini Section to copy from
+   * @param section_name section name to override, if empty, section name is not
+   * updated
+   * @param entry_str entry string to override the given section name
+   */
+  IniSection(IniSection &from, const std::string &section_name,
+             const std::string &entry_str);
+
+  /**
+   * @brief Construct a new Ini Section object
+   *
+   * @param from Ini Section to copy from
+   * @param entry_str entry string to override the given section name
+   */
+  IniSection(IniSection &from, const std::string &entry_str) :
+    IniSection(from, "", entry_str) {}
+
+  IniSection() = default;
+  ~IniSection() = default;
+
+  /**
+   * @brief +=operator from IniSection
+   *
+   * @param rhs operand to add
+   * @return IniSection& this
+   */
+  IniSection &operator+=(const IniSection &rhs) {
+    setEntry(rhs.entry);
+    return *this;
+  }
+
+  /**
+   * @brief + operator from IniSection
+   *
+   * @param rhs operand to add
+   * @return IniSection new Inisection
+   */
+  IniSection operator+(const IniSection &rhs) const {
+    return IniSection(*this) += rhs;
+  }
+
+  /**
+   * @brief += operator from string
+   *
+   * @param s string representation to add
+   * @return IniSection& this
+   */
+  IniSection &operator+=(const std::string &s) {
+    setEntry(s);
+    return *this;
+  }
+
+  /**
+   * @brief + operator from string
+   *
+   * @param s string representation to add
+   * @return IniSection Newly created section
+   */
+  IniSection operator+(const std::string &s) { return IniSection(*this) += s; }
+
+  /**
+   * @brief equal operator between ini section
+   *
+   * @param rhs ini section to compare
+   * @return true two inisections are equal
+   * @return false two ini sections are not equal
+   */
+  bool operator==(const IniSection &rhs) const {
+    return section_name == rhs.section_name && entry == rhs.entry;
+  }
+
+  /**
+   * @brief  not equal operator between ini section
+   *
+   * @param rhs ini section to compare
+   * @return true two inisections are not equal
+   * @return false two inisections are equal
+   */
+  bool operator!=(const IniSection &rhs) const { return !operator==(rhs); }
+
+  /**
+   * @brief print out a section
+   *
+   * @param out ostream to print
+   */
+  void print(std::ostream &out);
+
+  /**
+   * @brief Get the Name object
+   *
+   * @return std::string section name
+   */
+  std::string getName() { return section_name; }
+
+private:
+  /**
+   * @brief Set the Entry
+   *
+   * @param entry set entry from a given map
+   */
+  void setEntry(const std::map<std::string, std::string> &entry);
+
+  /**
+   * @brief set entry from the string representation
+   *
+   * @param entry_str setEntry as "Type = neuralnetwork | decayrate = 0.96 |
+   * -epochs = 1" will delete epochs, and overwrite type and decayrate
+   */
+  void setEntry(const std::string &entry_str);
+
+  std::string section_name; /**< section name of the ini section */
+
+  /// @note if ini_wrapper needs to be optimized, change this to unordered_map
+  std::map<std::string, std::string>
+    entry; /**< entry information that this ini contains */
+
+  /**
+   * @brief <<operator of a section
+   *
+   * @param os ostream
+   * @param section section to print
+   * @return std::ostream& ostream
+   */
+  friend std::ostream &operator<<(std::ostream &os, const IniSection &section) {
+    return os << section.section_name;
+  }
+};
+
+} // namespace nntrainer
+
+#endif // __INI_WRAPPER_H__
index 0bdaed8..f734093 100644 (file)
@@ -2,6 +2,7 @@ util_sources = [
   'parse_util.cpp',
   'util_func.cpp',
   'profiler.cpp',
+  'ini_wrapper.cpp',
 ]
 
 util_headers = [