[TEST] Add execution order generator
authorJiho Chu <jiho.chu@samsung.com>
Tue, 14 Feb 2023 08:06:51 +0000 (17:06 +0900)
committerjijoong.moon <jijoong.moon@samsung.com>
Tue, 4 Apr 2023 01:39:05 +0000 (10:39 +0900)
It generate execution order golden file for each model.
Each golden data consists of execution orders of each tensors.

Signed-off-by: Jiho Chu <jiho.chu@samsung.com>
packaging/unittest_models_exeorder.tar.gz [new file with mode: 0644]
test/input_gen/genModelExeOrder.cpp [new file with mode: 0644]
test/input_gen/meson.build [new file with mode: 0644]
test/meson.build
test/unittest/meson.build

diff --git a/packaging/unittest_models_exeorder.tar.gz b/packaging/unittest_models_exeorder.tar.gz
new file mode 100644 (file)
index 0000000..2bfe840
Binary files /dev/null and b/packaging/unittest_models_exeorder.tar.gz differ
diff --git a/test/input_gen/genModelExeOrder.cpp b/test/input_gen/genModelExeOrder.cpp
new file mode 100644 (file)
index 0000000..bae8f77
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * Copyright (C) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file genModelExeOrder.cpp
+ * @date 14 February 2023
+ * @brief Generate execution order golden data for models
+ * @see        https://github.com/nnstreamer/nntrainer
+ * @author Jiho Chu <jiho.chu@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <cstdlib>
+
+#include <layer.h>
+#include <model.h>
+#include <vector>
+
+#include "neuralnet.h"
+#include "nntrainer_test_util.h"
+
+nntrainer::NeuralNetwork
+genModel(const std::vector<LayerRepresentation> &layers) {
+  auto model = nntrainer::NeuralNetwork();
+  auto graph = makeGraph(layers);
+
+  for (auto &layer : graph) {
+    model.addLayer(layer);
+  }
+
+  model.compile();
+  model.initialize();
+
+  return model;
+}
+
+void exportToFile(std::string name, nntrainer::NeuralNetwork &model) {
+  std::string file_name = name + ".exegolden";
+  std::ofstream file(file_name);
+
+  auto graph = model.getNetworkGraph();
+  for (unsigned int i = 0; i < graph.size(); ++i) {
+    auto layer = graph.getSortedLayerNode(i);
+    auto orders = graph.getLayerExecutionOrders(layer);
+    for (auto &[name, ords] : orders) {
+      file << name;
+      std::set<unsigned int> set_ords(ords.begin(), ords.end());
+      for (auto &o : set_ords) {
+        file << ", " << o;
+      }
+      file << std::endl;
+    }
+  }
+
+  file.close();
+}
+
+std::vector<std::tuple<std::string, nntrainer::NeuralNetwork>> test_models = {
+  {"fc3_mse", genModel({{"input", {"name=in", "input_shape=1:1:3"}},
+                        {"fully_connected",
+                         {"name=fc1", "input_layers=in", "unit=10",
+                          "activation=relu", "trainable=true"}},
+                        {"fully_connected",
+                         {"name=fc2", "input_layers=fc1", "unit=10",
+                          "activation=relu", "trainable=true"}},
+                        {"fully_connected",
+                         {"name=fc3", "input_layers=fc2", "unit=2",
+                          "activation=sigmoid", "trainable=true"}},
+                        {"mse", {"name=mse", "input_layers=fc3"}}})},
+  {"fc3_mse_nt1", genModel({{"input", {"name=in", "input_shape=1:1:3"}},
+                            {"fully_connected",
+                             {"name=fc1", "input_layers=in", "unit=10",
+                              "activation=relu", "trainable=false"}},
+                            {"fully_connected",
+                             {"name=fc2", "input_layers=fc1", "unit=10",
+                              "activation=relu", "trainable=true"}},
+                            {"fully_connected",
+                             {"name=fc3", "input_layers=fc2", "unit=2",
+                              "activation=sigmoid", "trainable=true"}},
+                            {"mse", {"name=mse", "input_layers=fc3"}}})},
+  {"fc3_mse_nt2", genModel({{"input", {"name=in", "input_shape=1:1:3"}},
+                            {"fully_connected",
+                             {"name=fc1", "input_layers=in", "unit=10",
+                              "activation=relu", "trainable=true"}},
+                            {"fully_connected",
+                             {"name=fc2", "input_layers=fc1", "unit=10",
+                              "activation=relu", "trainable=false"}},
+                            {"fully_connected",
+                             {"name=fc3", "input_layers=fc2", "unit=2",
+                              "activation=sigmoid", "trainable=true"}},
+                            {"mse", {"name=mse", "input_layers=fc3"}}})},
+  {"fc3_mse_nt3", genModel({{"input", {"name=in", "input_shape=1:1:3"}},
+                            {"fully_connected",
+                             {"name=fc1", "input_layers=in", "unit=10",
+                              "activation=relu", "trainable=true"}},
+                            {"fully_connected",
+                             {"name=fc2", "input_layers=fc1", "unit=10",
+                              "activation=relu", "trainable=true"}},
+                            {"fully_connected",
+                             {"name=fc3", "input_layers=fc2", "unit=2",
+                              "activation=sigmoid", "trainable=false"}},
+                            {"mse", {"name=mse", "input_layers=fc3"}}})},
+};
+
+int main(int argc, char **argv) {
+  for (auto &[name, model] : test_models) {
+    exportToFile(name, model);
+  }
+
+  return EXIT_SUCCESS;
+}
diff --git a/test/input_gen/meson.build b/test/input_gen/meson.build
new file mode 100644 (file)
index 0000000..8b9c48a
--- /dev/null
@@ -0,0 +1,21 @@
+
+input_gen_dep = [
+  nntrainer_dep,
+  nntrainer_ccapi_dep,
+  nntrainer_testutil_dep
+]
+
+gen_target = [
+  ['genModelExeOrder', []],
+]
+
+foreach target: gen_target
+  exe = executable(
+    target[0],
+    [target[0] + '.cpp'] + target[1],
+    # below is temporary measure, we will eventually remove unittest_nntrainer_models
+    include_directories: nntrainer_test_inc,
+    dependencies: input_gen_dep
+  )
+endforeach
+
index 5a9d4911f41d7b18e433295b575f5e045202a06a..b3d99e92cfafdfb050bd6db7fc4568346d9a86ae 100644 (file)
@@ -36,6 +36,7 @@ if enable_capi
 endif
 
 if enable_ccapi
+  subdir('input_gen')
   subdir('ccapi')
   subdir('unittest')
 endif
index 00415d168f4590a814c8a8bef22300b687df3589..34a92ea992a47d9018d07c20604bbf616d8340e6 100644 (file)
@@ -17,6 +17,7 @@ unzip_target = [
   ['unittest_models_v2.tar.gz', 'unittest_models'],
   ['unittest_models_v3.tar.gz', 'unittest_models'],
   ['unittest_models_multiout.tar.gz', 'unittest_models'],
+  ['unittest_models_exeorder.tar.gz', 'unittest_models'],
 ]
 
 src_path = meson.source_root() / 'packaging'