[Unittest] Add network_graph unit test
authorDonghak PARK <donghak.park@samsung.com>
Mon, 21 Oct 2024 05:50:29 +0000 (14:50 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 22 Oct 2024 01:40:32 +0000 (10:40 +0900)
Add More unit test on network_graph
- add reinitialize
- catch exceptions

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

Signed-off-by: Donghak PARK <donghak.park@samsung.com>
test/unittest/unittest_nntrainer_graph.cpp

index 9d461c8a29cdfcf88928e76a320991a9f6737541..efca1c31d68c5f3164e81774eeb6ef2d6f564786 100644 (file)
 
 #include "nntrainer_test_util.h"
 
+using LayerRepresentation = std::pair<std::string, std::vector<std::string>>;
+using LayerHandle = std::shared_ptr<ml::train::Layer>;
+using ModelHandle = std::unique_ptr<ml::train::Model>;
+using ml::train::createLayer;
+
+/**
+ * @brief make "key=value" from key and value
+ *
+ * @tparam T type of a value
+ * @param key key
+ * @param value value
+ * @return std::string with "key=value"
+ */
+template <typename T>
+static std::string withKey(const std::string &key, const T &value) {
+  std::stringstream ss;
+  ss << key << "=" << value;
+  return ss.str();
+}
+
+template <typename T>
+static std::string withKey(const std::string &key,
+                           std::initializer_list<T> value) {
+  if (std::empty(value)) {
+    throw std::invalid_argument("empty data cannot be converted");
+  }
+
+  std::stringstream ss;
+  ss << key << "=";
+
+  auto iter = value.begin();
+  for (; iter != value.end() - 1; ++iter) {
+    ss << *iter << ',';
+  }
+  ss << *iter;
+
+  return ss.str();
+}
+
 namespace initest {
 typedef enum {
-  LOAD = 1 << 0, /**< should fail at load */
-  INIT = 1 << 1, /**< should fail at init */
+  LOAD = 1 << 0,   /**< should fail at load */
+  INIT = 1 << 1,   /**< should fail at init */
+  REINIT = 1 << 2, /**< should fail at reinit */
 } IniFailAt;
 };
 
@@ -53,6 +93,8 @@ protected:
 
   bool failAtInit() { return failAt & initest::IniFailAt::INIT; }
 
+  bool failAtReinit() { return failAt & initest::IniFailAt::REINIT; }
+
   nntrainer::NeuralNetwork NN;
 
 private:
@@ -94,6 +136,13 @@ TEST_P(nntrainerGraphTest, loadConfig) {
     EXPECT_EQ(status, ML_ERROR_NONE);
   }
 
+  status = NN.reinitialize();
+  if (failAtLoad()) {
+    EXPECT_NE(status, ML_ERROR_NONE);
+  } else {
+    EXPECT_EQ(status, ML_ERROR_NONE);
+  }
+
   status = NN.allocate();
   if (failAtLoad()) {
     EXPECT_NE(status, ML_ERROR_NONE);
@@ -246,6 +295,77 @@ GTEST_PARAMETER_TEST(nntrainerIniAutoTests, nntrainerGraphTest,
                         addition1, conv2d14, pooling3, fclayer0, fclayer1},
                        SUCCESS)));
 
+TEST(nntrainerGraphUnitTest, cross_with_relu) {
+  auto input0 = LayerRepresentation("input", {"name=in0", "input_shape=1:1:1"});
+  auto relu0 = LayerRepresentation(
+    "activation", {"name=relu0", "activation=relu", "input_layers=in0"});
+
+  auto g = makeGraph({input0, relu0});
+
+  nntrainer::NetworkGraph ng;
+
+  ModelHandle nn_model = ml::train::createModel(
+    ml::train::ModelType::NEURAL_NET, {withKey("loss", "cross")});
+
+  for (auto &node : g) {
+    EXPECT_NO_THROW(nn_model->addLayer(node));
+  }
+
+  EXPECT_NE(nn_model->compile(), ML_ERROR_NONE);
+  EXPECT_NE(nn_model->initialize(), ML_ERROR_NONE);
+}
+
+TEST(nntrainerGraphUnitTest, compile_twice) {
+  auto input0 = LayerRepresentation("input", {"name=in0", "input_shape=1:1:1"});
+  auto relu0 = LayerRepresentation(
+    "activation", {"name=relu0", "activation=softmax", "input_layers=in0"});
+
+  auto g = makeGraph({input0, relu0});
+
+  nntrainer::NetworkGraph ng;
+
+  ModelHandle nn_model = ml::train::createModel(
+    ml::train::ModelType::NEURAL_NET, {withKey("loss", "cross")});
+
+  for (auto &node : g) {
+    EXPECT_NO_THROW(nn_model->addLayer(node));
+  }
+
+  EXPECT_EQ(nn_model->compile(), ML_ERROR_NONE);
+  EXPECT_EQ(nn_model->initialize(), ML_ERROR_NONE);
+  try {
+    nn_model->compile();
+  } catch (const std::exception &e) {
+    EXPECT_STREQ(e.what(), "cannot remap identifiers after finalized");
+  }
+}
+
+TEST(nntrainerGraphUnitTest, call_functions) {
+  auto input0 = LayerRepresentation("input", {"name=in0", "input_shape=1:1:1"});
+  auto relu0 = LayerRepresentation(
+    "activation", {"name=relu0", "activation=softmax", "input_layers=in0"});
+
+  auto g = makeGraph({input0, relu0});
+
+  nntrainer::NetworkGraph ng;
+
+  ModelHandle nn_model = ml::train::createModel(
+    ml::train::ModelType::NEURAL_NET, {withKey("loss", "cross")});
+
+  for (auto &node : g) {
+    EXPECT_NO_THROW(nn_model->addLayer(node));
+  }
+
+  EXPECT_EQ(nn_model->compile(), ML_ERROR_NONE);
+  try {
+    for (auto &node : g) {
+      nn_model->addLayer(node);
+    }
+  } catch (const std::exception &e) {
+    EXPECT_STREQ(e.what(), "Cannot modify graph after compile");
+  }
+}
+
 int main(int argc, char **argv) {
   int result = -1;