[nn] Apply input connection to compile/initialize
authorJihoon Lee <jhoon.it.lee@samsung.com>
Tue, 23 Nov 2021 12:11:26 +0000 (21:11 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Fri, 3 Dec 2021 06:54:34 +0000 (15:54 +0900)
**Changes proposed in this PR:**
- input connection is used for previous realizer/graph.initialize
- temporary string cast operator deleted

**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>
nntrainer/compiler/previous_input_realizer.cpp
nntrainer/compiler/previous_input_realizer.h
nntrainer/graph/network_graph.cpp
nntrainer/graph/network_graph.h
nntrainer/layers/common_properties.h
nntrainer/models/neuralnet.cpp
test/unittest/compiler/unittest_realizer.cpp

index 14cc205..5131e2f 100644 (file)
@@ -9,6 +9,7 @@
  * @author Jihoon Lee <jhoon.it.lee@samsung.com>
  * @bug No known bugs except for NYI items
  */
+#include "connection.h"
 #include <algorithm>
 #include <compiler_fwd.h>
 #include <memory>
@@ -22,7 +23,7 @@
 namespace nntrainer {
 
 PreviousInputRealizer::PreviousInputRealizer(
-  const std::vector<std::string> &identified_inputs_) :
+  const std::vector<Connection> &identified_inputs_) :
   identified_inputs(identified_inputs_) {}
 
 PreviousInputRealizer::~PreviousInputRealizer() {}
@@ -38,8 +39,9 @@ PreviousInputRealizer::realize(const GraphRepresentation &reference) {
    */
   auto is_actually_an_input_node = [this](const LayerNode &node) {
     return node.hasInputShapeProperty() or
-           std::any_of(identified_inputs.begin(), identified_inputs.end(),
-                       [&node](auto &name) { return node.getName() == name; });
+           std::any_of(
+             identified_inputs.begin(), identified_inputs.end(),
+             [&node](auto &conn) { return node.getName() == conn.getName(); });
   };
 
   for (auto iter = processed.begin(); iter != processed.end(); ++iter) {
index 15abc11..0251f8f 100644 (file)
@@ -15,6 +15,7 @@
 #include <memory>
 #include <vector>
 
+#include <connection.h>
 #include <realizer.h>
 
 namespace nntrainer {
@@ -33,7 +34,7 @@ public:
    * @param identified_inputs node that is identified as an input, this must not
    * connect to other nodes automatically
    */
-  PreviousInputRealizer(const std::vector<std::string> &identified_inputs);
+  PreviousInputRealizer(const std::vector<Connection> &identified_inputs);
 
   /**
    * @brief Destroy the Graph Realizer object
@@ -48,7 +49,7 @@ public:
   GraphRepresentation realize(const GraphRepresentation &reference) override;
 
 private:
-  std::vector<std::string> identified_inputs; /**< inputs are identified */
+  std::vector<Connection> identified_inputs; /**< inputs are identified */
 };
 
 } // namespace nntrainer
index c6c9745..85789f2 100644 (file)
@@ -19,6 +19,7 @@
 #include <addition_layer.h>
 #include <bn_layer.h>
 #include <concat_layer.h>
+#include <connection.h>
 #include <cross_entropy_loss_layer.h>
 #include <cross_entropy_sigmoid_loss_layer.h>
 #include <cross_entropy_softmax_loss_layer.h>
@@ -752,9 +753,8 @@ NetworkGraph::finalizeContext(const std::shared_ptr<LayerNode> &lnode,
   return outputs;
 }
 
-int NetworkGraph::initialize(
-  const std::vector<std::string> &model_input_names,
-  const std::vector<std::string> &model_label_names) {
+int NetworkGraph::initialize(const std::vector<Connection> &model_input_names,
+                             const std::vector<Connection> &model_label_names) {
 
   /**
    * this contains the map from node name to its input tensor names
@@ -890,9 +890,9 @@ int NetworkGraph::initialize(
     label_dims.push_back(node->getOutputDimensions()[0]);
   };
 
-  auto identify_external_tensors = [this](const std::vector<std::string> &names,
+  auto identify_external_tensors = [this](const std::vector<Connection> &conns,
                                           auto &&pred, auto &&identify) {
-    if (names.empty()) {
+    if (conns.empty()) {
       for (unsigned int i = 0; i < graph.size(); ++i) {
         auto lnode = getSortedLayerNode(i).get();
         if (!pred(lnode)) {
@@ -903,10 +903,10 @@ int NetworkGraph::initialize(
         identify(lnode);
       }
     } else {
-      for (auto &name : names) {
-        auto lnode = getLayerNode(name).get();
+      for (auto &conn : conns) {
+        auto lnode = getLayerNode(conn.getName()).get();
         NNTR_THROW_IF(!pred(lnode), std::invalid_argument)
-          << "given node is not of that kind, name: " << name;
+          << "given node is not of that kind, name: " << conn.getName();
         identify(lnode);
       }
       unsigned int num_node_of_kind = 0;
@@ -917,10 +917,10 @@ int NetworkGraph::initialize(
         }
         num_node_of_kind++;
       }
-      NNTR_THROW_IF(num_node_of_kind != names.size(), std::invalid_argument)
-        << "names given but there are not identified node of the kind, num "
+      NNTR_THROW_IF(num_node_of_kind != conns.size(), std::invalid_argument)
+        << "conns given but there are not identified node of the kind, num "
            "node of kind: "
-        << num_node_of_kind << " identifier size: " << names.size();
+        << num_node_of_kind << " identifier size: " << conns.size();
     }
   };
 
index d064b71..8ba7b88 100644 (file)
@@ -28,6 +28,7 @@
 
 namespace nntrainer {
 
+class Connection;
 /**
  * @class   NeuralNetwork Graph Class
  * @brief   NeuralNetwork Graph Class which manage layers
@@ -242,14 +243,14 @@ public:
   /**
    * @brief initialize network graph
    *
-   * @param model_input_names model input names if empty list given, all of node
-   * that can be inputs will be identified in the sort order
+   * @param model_input_names model input connection if empty list given, all of
+   * node that can be inputs will be identified in the sort order
    * @param model_label_names model label names if empty list given, all of node
    * that can be labels will be identified in the sort order
    * @return int ML_ERROR_NONE if successful
    */
-  int initialize(const std::vector<std::string> &model_input_names = {},
-                 const std::vector<std::string> &model_label_names = {});
+  int initialize(const std::vector<Connection> &model_input_names = {},
+                 const std::vector<Connection> &model_label_names = {});
 
   /**
    * @brief Create run layer context from the given init layer context
index aa5c6ce..64b2581 100644 (file)
@@ -165,24 +165,6 @@ public:
   static constexpr const char *key =
     "input_layers";                     /**< unique key to access */
   using prop_tag = connection_prop_tag; /**< property type */
-
-  /**
-   * @brief cast operator for property
-   * @todo deprecate this, this is needed to bridge input_layers(name) <-> input
-   * connections temporarily
-   *
-   * @return std::string value
-   */
-  operator const std::string &() const { return get().getName(); }
-
-  /**
-   * @brief cast operator for property
-   * @todo deprecate this, this is needed to bridge input_layers(name) <-> input
-   * connections temporarily
-   *
-   * @return std::string value
-   */
-  operator std::string &() { return get().getName(); }
 };
 
 /**
index e049d57..bc57ab4 100644 (file)
@@ -108,17 +108,9 @@ int NeuralNetwork::compile() {
                             ? std::string()
                             : std::get<props::LossType>(model_props);
 
-  auto &input_layer_prop =
-    std::get<std::vector<props::InputConnection>>(model_props);
+  auto &input_conn = std::get<std::vector<props::InputConnection>>(model_props);
   /// @note label layer might need to be treated in the similar way as well
 
-  /// @todo deprecate this instead directly pass connection to the realizer
-  std::vector<std::string> input_layers = {};
-  if (!input_layer_prop.empty()) {
-    input_layers = std::vector<std::string>(input_layer_prop.begin(),
-                                            input_layer_prop.end());
-  }
-
   /// @todo make NetworkGraph compiled at the construction instead of having
   /// graph.compile(), neuralnetwork have ownership of list of layer nodes,
   /// which will be passed at compile time.
@@ -136,7 +128,8 @@ int NeuralNetwork::compile() {
 
   std::vector<std::unique_ptr<GraphRealizer>> realizers;
 
-  realizers.emplace_back(new PreviousInputRealizer(input_layers));
+  realizers.emplace_back(new PreviousInputRealizer(
+    std::vector<Connection>(input_conn.begin(), input_conn.end())));
   realizers.emplace_back(new MultioutRealizer());
   realizers.emplace_back(new FlattenRealizer());
   realizers.emplace_back(new ActivationRealizer());
@@ -180,24 +173,22 @@ int NeuralNetwork::initialize() {
   model_graph.setBatchSize(
     std::get<props::TrainingBatchSize>(model_flex_props));
 
-  auto &input_layer_prop =
+  auto &input_conns =
     std::get<std::vector<props::InputConnection>>(model_props);
   auto &label_layer_prop =
     std::get<std::vector<props::LabelLayer>>(model_props);
 
-  std::vector<std::string> input_layers;
+  std::vector<Connection> input_layers(input_conns.begin(), input_conns.end());
   std::vector<std::string> label_layers;
 
-  if (!input_layer_prop.empty()) {
-    input_layers = std::vector<std::string>(input_layer_prop.begin(),
-                                            input_layer_prop.end());
-  }
   if (!label_layer_prop.empty()) {
     label_layers = std::vector<std::string>(label_layer_prop.begin(),
                                             label_layer_prop.end());
   }
 
-  status = model_graph.initialize(input_layers, label_layers);
+  status = model_graph.initialize(
+    std::vector<Connection>(input_conns.begin(), input_conns.end()),
+    std::vector<Connection>(label_layers.begin(), label_layers.end()));
   NN_RETURN_STATUS();
 
   // initialize optimizer and related variables
@@ -957,9 +948,12 @@ void NeuralNetwork::addWithReferenceLayers(
   auto start_layers_ = normalize(start_layers);
   auto end_layers_ = normalize(end_layers);
 
+  auto start_conns_ =
+    std::vector<Connection>(start_layers.begin(), start_layers.end());
+
   std::vector<std::unique_ptr<GraphRealizer>> realizers;
 
-  realizers.emplace_back(new PreviousInputRealizer(start_layers));
+  realizers.emplace_back(new PreviousInputRealizer(start_conns_));
   realizers.emplace_back(new SliceRealizer(start_layers_, end_layers_));
 
   if (!input_layers_.empty()) {
index af16f07..02881ae 100644 (file)
@@ -9,12 +9,12 @@
  * @author Jihoon Lee <jhoon.it.lee@samsung.com>
  * @bug No known bugs except for NYI items
  */
-
-#include "activation_realizer.h"
 #include <gtest/gtest.h>
 
 #include <vector>
 
+#include <activation_realizer.h>
+#include <connection.h>
 #include <flatten_realizer.h>
 #include <input_realizer.h>
 #include <multiout_realizer.h>
@@ -273,7 +273,7 @@ TEST(PreviousInputRealizer, previous_p) {
       {"fully_connected", {"name=fc3", "input_layers=fc1"}},
       {"fully_connected", {"name=fc4"}},
     };
-    PreviousInputRealizer r({"fc1", "fc4"});
+    PreviousInputRealizer r({Connection("fc1"), Connection("fc4")});
     realizeAndEqual(r, before, after);
   }
   { /// intermediate node is auto input