[split layer] Maintain split layer property with props
authorhyeonseok lee <hs89.lee@samsung.com>
Mon, 6 Sep 2021 08:26:53 +0000 (17:26 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Mon, 13 Sep 2021 11:59:57 +0000 (20:59 +0900)
 - All the property of split layer will be maintain with props

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

Signed-off-by: hyeonseok lee <hs89.lee@samsung.com>
nntrainer/layers/common_properties.cpp
nntrainer/layers/common_properties.h
nntrainer/layers/split_layer.cpp
nntrainer/layers/split_layer.h

index 4b8627a..2390c7f 100644 (file)
@@ -100,6 +100,10 @@ bool InputSpec::isValid(const ConnectionSpec &v) const {
   return v.getLayerIds().size() > 0;
 }
 
+bool SplitDimension::isValid(const unsigned int &value) const {
+  return value > 0 && value < ml::train::TensorDim::MAXDIM;
+}
+
 /**
  * @brief unsigned integer property, internally used to parse padding values
  *
index 852dcd0..027e9b7 100644 (file)
@@ -242,6 +242,28 @@ public:
 };
 
 /**
+ * @brief SplitDimension property, dimension along which to split the input
+ *
+ */
+class SplitDimension : public nntrainer::PositiveIntegerProperty {
+public:
+  static constexpr const char *key =
+    "split_dimension";            /**< unique key to access */
+  using prop_tag = uint_prop_tag; /**< property type */
+
+  /**
+   * @brief check if given value is valid
+   *
+   * @param v value to check
+   * @retval true if it is greater than 0 and smaller than
+   * ml::train::TensorDim::MAXDIM
+   * @retval false if it is samller than 0 or greate than
+   * ml::train::TensorDim::MAXDIM
+   */
+  bool isValid(const unsigned int &value) const override;
+};
+
+/**
  * @brief Padding2D property, this is used to calculate padding2D
  * @details Padding2D is saved as a string. Upon calling Padding2D::compute,
  * returns std::vector<unsigned int> which has computed padding2Ds, below
index 6aec76e..b3a189d 100644 (file)
@@ -14,6 +14,7 @@
 #include <cstring>
 #include <nntrainer_error.h>
 #include <nntrainer_log.h>
+#include <node_exporter.h>
 #include <parse_util.h>
 #include <split_layer.h>
 #include <util_func.h>
@@ -22,22 +23,19 @@ namespace nntrainer {
 
 static constexpr size_t SINGLE_INOUT_IDX = 0;
 
-void SplitLayer::finalize(InitLayerContext &context) {
-  if (split_dimension < 1) {
-    throw std::invalid_argument(
-      "Error: cannot split along the batch dimension");
-  }
-
-  if (split_dimension >= ml::train::TensorDim::MAXDIM) {
-    throw std::invalid_argument(
-      "Error: split dimension exceeding the total number of dimensions");
-  }
+SplitLayer::SplitLayer() :
+  Layer(),
+  leading_helper_dim(1),
+  split_props(props::SplitDimension()) {}
 
+void SplitLayer::finalize(InitLayerContext &context) {
   if (context.getNumInputs() != 1) {
     throw std::invalid_argument(
       "Error: only a single input is supported with split layer");
   }
 
+  unsigned int split_dimension = std::get<props::SplitDimension>(split_props);
+
   /**
    * The split is only done along the split_dimension dimension.
    * For example, consider input dimension [b,c,h,w],
@@ -152,46 +150,16 @@ void SplitLayer::calcDerivative(RunLayerContext &context) {
   input_.reshape(in_dim);
 }
 
-void SplitLayer::setProperty(const std::vector<std::string> &values) {
-  /// @todo: deprecate this in favor of loadProperties
-  for (unsigned int i = 0; i < values.size(); ++i) {
-    std::string key;
-    std::string value;
-    std::stringstream ss;
-
-    if (getKeyValue(values[i], key, value) != ML_ERROR_NONE) {
-      throw std::invalid_argument("Error parsing the property: " + values[i]);
-    }
-
-    if (value.empty()) {
-      ss << "value is empty: key: " << key << ", value: " << value;
-      throw std::invalid_argument(ss.str());
-    }
-
-    /// @note this calls derived setProperty if available
-    setProperty(key, value);
-  }
+void SplitLayer::exportTo(Exporter &exporter,
+                          const ExportMethods &method) const {
+  exporter.saveResult(split_props, method, this);
 }
 
-void SplitLayer::setProperty(const std::string &type_str,
-                             const std::string &value) {
-  using PropertyType = nntrainer::Layer::PropertyType;
-  int status = ML_ERROR_NONE;
-  nntrainer::Layer::PropertyType type =
-    static_cast<nntrainer::Layer::PropertyType>(parseLayerProperty(type_str));
-
-  switch (type) {
-  case PropertyType::split_dimension: {
-    status = setUint(split_dimension, value);
-    NNTR_THROW_IF(split_dimension == 0, std::invalid_argument)
-      << "[Split] Batch dimension cannot be split dimension";
-    throw_status(status);
-  } break;
-  default:
-    std::string msg =
-      "[SplitLayer] Unknown Layer Property Key for value " + std::string(value);
-    throw exception::not_supported(msg);
-  }
+void SplitLayer::setProperty(const std::vector<std::string> &values) {
+  auto remain_props = loadProperties(values, split_props);
+  NNTR_THROW_IF(!remain_props.empty(), std::invalid_argument)
+    << "[SplitLayer] Unknown Layer Properties count " +
+         std::to_string(values.size());
 }
 
 } /* namespace nntrainer */
index 5118ce2..640a41b 100644 (file)
@@ -30,10 +30,7 @@ public:
   /**
    * @brief     Constructor of Split Layer
    */
-  SplitLayer(unsigned int split_dim = 1) :
-    Layer(),
-    split_dimension(split_dim),
-    leading_helper_dim(1) {}
+  SplitLayer();
 
   /**
    * @brief     Destructor of Split Layer
@@ -75,8 +72,7 @@ public:
   /**
    * @copydoc Layer::exportTo(Exporter &exporter, ExportMethods method)
    */
-  void exportTo(Exporter &exporter,
-                const ExportMethods &method) const override {}
+  void exportTo(Exporter &exporter, const ExportMethods &method) const override;
 
   /**
    * @copydoc Layer::setProperty(const std::vector<std::string> &values)
@@ -105,21 +101,11 @@ public:
   }
 
 private:
-  unsigned int split_dimension; /** dimension along which to split the input */
   unsigned int leading_helper_dim; /**< batch dimension of helper dimension not
                                 containing the actual batch */
   TensorDim input_reshape_helper;  /** helper dimension to reshape input */
   TensorDim output_reshape_helper; /** helper dimension to reshape outputs */
-
-  /**
-   * @brief setProperty by type and value separated
-   * @param[in] type property type to be passed
-   * @param[in] value value to be passed
-   * @exception exception::not_supported     when property type is not valid for
-   * the particular layer
-   * @exception std::invalid_argument invalid argument
-   */
-  void setProperty(const std::string &type, const std::string &value);
+  std::tuple<props::SplitDimension> split_props;
 
   /**
    * @brief set batch for the internal variables