[Layer] Add permute layer scaffolding
authorJihoon Lee <jhoon.it.lee@samsung.com>
Tue, 4 May 2021 01:50:09 +0000 (10:50 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 8 Jun 2021 08:02:09 +0000 (17:02 +0900)
This patch adds permute layer scaffolding

**Minor Fix**
- Add error handling for transpose tensordim

**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>
api/ccapi/include/layer.h
jni/Android.mk
nntrainer/app_context.cpp
nntrainer/layers/meson.build
nntrainer/layers/permute_layer.cpp [new file with mode: 0644]
nntrainer/layers/permute_layer.h [new file with mode: 0644]
nntrainer/tensor/tensor_dim.cpp
nntrainer/utils/base_properties.h
test/unittest/unittest_base_properties.cpp

index 481ce26..4656346 100644 (file)
@@ -54,6 +54,7 @@ enum LayerType {
   LAYER_LSTM,                 /** LSTM Layer type */
   LAYER_SPLIT,                /** Splite Layer type */
   LAYER_TIME_DIST,            /** Time Distributed Layer type */
+  LAYER_PERMUTE,              /** Permute layer */
   LAYER_UNKNOWN = ML_TRAIN_LAYER_TYPE_UNKNOWN /** Unknown */
 };
 
index c848d19..e2eae32 100644 (file)
@@ -130,6 +130,7 @@ NNTRAINER_SRCS := $(NNTRAINER_ROOT)/nntrainer/models/neuralnet.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/layers/rnn.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/layers/lstm.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/layers/time_dist.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/permute_layer.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/layers/acti_func.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/layers/split_layer.cpp \
                   $(NNTRAINER_ROOT)/nntrainer/layers/common_properties.cpp \
index eb17ec8..04de518 100644 (file)
@@ -42,6 +42,7 @@
 #include <nntrainer_error.h>
 #include <output_layer.h>
 #include <parse_util.h>
+#include <permute_layer.h>
 #include <plugged_layer.h>
 #include <plugged_optimizer.h>
 #include <pooling2d_layer.h>
@@ -248,6 +249,9 @@ static void add_default_object(AppContext &ac) {
                      LayerType::LAYER_TIME_DIST);
   ac.registerFactory(nntrainer::createLayer<SplitLayer>, SplitLayer::type,
                      LayerType::LAYER_SPLIT);
+  ac.registerFactory(nntrainer::createLayer<PermuteLayer>, PermuteLayer::type,
+                     LayerType::LAYER_PERMUTE);
+
   ac.registerFactory(AppContext::unknownFactory<nntrainer::Layer>, "unknown",
                      LayerType::LAYER_UNKNOWN);
 }
index 9953ca3..39d0bdc 100644 (file)
@@ -22,7 +22,8 @@ layer_sources = [
   'lstm.cpp',
   'time_dist.cpp',
   'common_properties.cpp',
-  'split_layer.cpp'
+  'split_layer.cpp',
+  'permute_layer.cpp'
 ]
 
 layer_headers = [
diff --git a/nntrainer/layers/permute_layer.cpp b/nntrainer/layers/permute_layer.cpp
new file mode 100644 (file)
index 0000000..e8a2543
--- /dev/null
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
+ *
+ * @file   permute_layer.cpp
+ * @date   06 May 2021
+ * @brief  Permute layer to support transpose
+ * @see           https://github.com/nnstreamer/nntrainer
+ * @author Jihoon Lee <jhoon.it.lee@samsung.com>
+ * @bug    No known bugs except for NYI items
+ */
+#include <tuple>
+
+#include <nntrainer_error.h>
+#include <nntrainer_log.h>
+#include <parse_util.h>
+#include <permute_layer.h>
+#include <tensor.h>
+#include <tensor_dim.h>
+
+namespace nntrainer {
+
+const std::string PermuteLayer::type = "permute";
+
+int PermuteLayer::initialize(Manager &manager) { /** NYI */
+  return ML_ERROR_NONE;
+}
+
+void PermuteLayer::forwarding(bool training) { /** NYI */
+}
+
+void PermuteLayer::calcDerivative() { /** NYI */
+}
+
+void PermuteLayer::copy(std::shared_ptr<Layer> l) { /** NYI */
+}
+
+void PermuteLayer::export_to(Exporter &exporter, ExportMethods method) const {}
+
+int PermuteLayer::setProperty(std::vector<std::string> values) {
+  return ML_ERROR_NONE;
+}
+
+} // namespace nntrainer
diff --git a/nntrainer/layers/permute_layer.h b/nntrainer/layers/permute_layer.h
new file mode 100644 (file)
index 0000000..b5e05b4
--- /dev/null
@@ -0,0 +1,97 @@
+
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
+ *
+ * @file   permute_layer.h
+ * @date   06 May 2021
+ * @brief  Permute layer to support transpose
+ * @see           https://github.com/nnstreamer/nntrainer
+ * @author Jihoon Lee <jhoon.it.lee@samsung.com>
+ * @bug    No known bugs except for NYI items
+ */
+#ifndef __PERMUTE_LAYER_H__
+#define __PERMUTE_LAYER_H__
+
+#include <array>
+
+#include <base_properties.h>
+#include <layer_internal.h>
+#include <node_exporter.h>
+namespace nntrainer {
+/**
+ * @class   PermuteLayer
+ * @brief   Permute layer to transpose a tensor
+ */
+class PermuteLayer : public Layer {
+public:
+  /**
+   * @brief     Constructor of Permute Layer
+   * @param     direction direction to permute
+   */
+  template <typename... Args> PermuteLayer(Args... args) : Layer(args...) {}
+
+  /**
+   * @brief     Destructor of Permute Layer
+   */
+  ~PermuteLayer() = default;
+
+  /**
+   *  @brief  Move constructor.
+   *  @param[in] PermuteLayer &&
+   */
+  PermuteLayer(PermuteLayer &&rhs) noexcept = default;
+
+  /**
+   * @brief  Move assignment operator.
+   * @param[in] rhs PermuteLayer to be moved.
+   */
+  PermuteLayer &operator=(PermuteLayer &&rhs) = default;
+
+  /**
+   * @copydoc Layer::forwarding(bool training)
+   */
+  void forwarding(bool training = true) override;
+
+  /**
+   * @copydoc Layer::calcDerivative()
+   */
+  void calcDerivative() override;
+
+  /**
+   * @brief     copy layer
+   * @param[in] l layer to copy
+   */
+  void copy(std::shared_ptr<Layer> l) override;
+
+  /**
+   * @brief     initialize layer
+   * @retval #ML_ERROR_NONE Successful.
+   * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
+   */
+  int initialize(Manager &manager) override;
+
+  /**
+   * @copydoc Layer::export_to(Exporter &exporter, ExportMethods method)
+   */
+  void export_to(
+    Exporter &exporter,
+    ExportMethods method = ExportMethods::METHOD_STRINGVECTOR) const override;
+
+  /**
+   * @copydoc Layer::getType()
+   */
+  const std::string getType() const override { return PermuteLayer::type; };
+
+  static const std::string type;
+
+  using Layer::setProperty;
+
+  /**
+   * @copydoc Layer::setProperty(std::vector<std::string> values);
+   */
+  int setProperty(std::vector<std::string> values) override;
+};
+
+} // namespace nntrainer
+#endif // __PERMUTE_LAYER_H__
index 6676c0a..8521684 100644 (file)
@@ -99,7 +99,9 @@ int TensorDim::setTensorDim(const std::string &input_shape) {
 TensorDim TensorDim::transpose(const std::string &direction) const {
   int dirs[MAXDIM - 1];
 
-  getValues(3, direction, dirs);
+  int status = getValues(3, direction, dirs);
+  NNTR_THROW_IF(status != ML_ERROR_NONE, std::invalid_argument)
+    << "parsing direction failed";
 
   const std::array<unsigned int, MAXDIM> axes{{0, (unsigned int)dirs[0] + 1,
                                                (unsigned int)dirs[1] + 1,
index 16455f6..69b191e 100644 (file)
@@ -28,13 +28,13 @@ template <typename T>
 using remove_cv_ref_t = std::remove_cv_t<std::remove_reference_t<T>>;
 /**
  * @brief property info to specialize functions based on this
- *
  * @tparam T property type
  */
 template <typename T> struct prop_info {
-  using prop_type = remove_cv_ref_t<T>;
-  using tag_type = typename prop_type::prop_tag;
-  using data_type = remove_cv_ref_t<decltype(std::declval<prop_type>().get())>;
+  using prop_type = remove_cv_ref_t<T>;          /** property type of T */
+  using tag_type = typename prop_type::prop_tag; /** Property tag of T */
+  using data_type = remove_cv_ref_t<decltype(
+    std::declval<prop_type>().get())>; /** Underlying datatype of T */
 };
 
 /**
index 230767a..1851ae5 100644 (file)
@@ -96,6 +96,19 @@ TEST(BasicProperty, tagCast) {
   }
 }
 
+TEST(BasicProperty, propInfo) {
+  { /**< prop_info test */
+    using prop_type = nntrainer::prop_info<QualityOfBanana>::prop_type;
+    ::testing::StaticAssertTypeEq<prop_type, QualityOfBanana>();
+
+    using tag_type = nntrainer::prop_info<QualityOfBanana>::tag_type;
+    ::testing::StaticAssertTypeEq<tag_type, nntrainer::str_prop_tag>();
+
+    using data_type = nntrainer::prop_info<QualityOfBanana>::data_type;
+    ::testing::StaticAssertTypeEq<data_type, std::string>();
+  }
+}
+
 /// @todo convert this to typed param test
 TEST(BasicProperty, valid_p) {
   { /** set -> get / to_string, int*/