[Apptest] Add aging test mode and check mem leak
authorDongju Chae <dongju.chae@samsung.com>
Thu, 24 Jun 2021 09:20:09 +0000 (18:20 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Fri, 25 Jun 2021 06:13:44 +0000 (15:13 +0900)
This patch adds aging test mode and check mem leak.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
tests/apptests/tvn_triv2_aging.cc
tests/utils/ne_test_utils.cc
tests/utils/ne_test_utils.h

index fe8b432..b79a5ee 100644 (file)
@@ -20,18 +20,14 @@ using namespace std;
 /** @brief C++ class to describe how to use npu-engine library */
 class Tester : public UtilTRIV2 {
  public:
-  Tester () : model_id_ (0), num_iter_ (0) {}
+  Tester () : num_iter_ (0), mode_ (0) {}
 
   /** @brief initilize the device handle */
-  int init (string model_dir, string num_dir) {
-    if (model_dir == "" || num_dir == "")
+  int init (string model_dir) {
+    if (model_dir == "")
       return -EINVAL;
 
-    errno = 0;
-    num_iter_ = strtoul (num_dir.c_str (), NULL, 10);
-    if (errno != 0)
-      return -errno;
-
+    model_dir_ = model_dir;
     string model_path = model_dir + "/model.tvn";
     npubin_meta *meta = getNPUmodel_metadata (model_path.c_str (), false);
     if (meta == nullptr)
@@ -46,35 +42,101 @@ class Tester : public UtilTRIV2 {
       return status;
     }
 
-    return UtilTRIV2::loadModel (model_dir, &model_id_, NPU_PRIORITY_MID,
-                                 NPU_TIMEOUT_MS);
+    return 0;
   }
 
-  /** @brief run the inference */
-  int run () {
-    if (model_id_ == 0)
-      return test_ret_failure;
+  /** @brief configure testing mode */
+  int config (string mode, string num_iter) {
+    if (mode == "" || num_iter == "")
+      return -EINVAL;
 
-    int req_id = UtilTRIV2::createRequest (model_id_);
-    if (req_id < 0)
-      return req_id;
+    errno = 0;
+    num_iter_ = strtoul (num_iter.c_str (), NULL, 10);
+    if (errno != 0)
+      return -errno;
 
-    for (uint32_t i = 0; i < num_iter_; i++)
-      UtilTRIV2::submitRequest (model_id_);
+    errno = 0;
+    mode_ = strtoul (mode.c_str (), NULL, 10);
+    if (errno != 0)
+      return -errno;
 
-    UtilTRIV2::removeRequest (req_id);
-    return wait () == num_iter_ ? test_ret_success : test_ret_failure;
+    return test_ret_success;
+  }
+
+  /** @brief run the inference */
+  int run () {
+    uint32_t model_id;
+    if (mode_ == 1) {
+      int status = UtilTRIV2::loadModel (model_dir_, &model_id,
+                                         NPU_PRIORITY_MID, NPU_TIMEOUT_MS);
+      if (status != 0)
+        return status;
+
+      int req_id = UtilTRIV2::createRequest (model_id);
+      if (req_id < 0)
+        return req_id;
+
+      for (uint32_t i = 0; i < num_iter_; i++)
+        UtilTRIV2::submitRequest (model_id);
+
+      UtilTRIV2::removeRequest (req_id);
+      return wait () == num_iter_ ? test_ret_success : test_ret_failure;
+    } else if (mode_ == 2) {
+      for (uint32_t i = 0; i < num_iter_; i++) {
+        int status = UtilTRIV2::loadModel (model_dir_, &model_id,
+                                           NPU_PRIORITY_MID, NPU_TIMEOUT_MS);
+        if (status != 0)
+          return status;
+
+        int req_id = UtilTRIV2::createRequest (model_id);
+        if (req_id < 0)
+          return req_id;
+
+        status = UtilTRIV2::submitRequest (req_id);
+        if (status != 0) {
+          UtilTRIV2::removeRequest (req_id);
+          UtilTRIV2::unloadModel (model_id);
+          return status;
+        }
+
+        status = UtilTRIV2::removeRequest (req_id);
+        if (status != 0) {
+          UtilTRIV2::unloadModel (model_id);
+          return status;
+        }
+
+        status = UtilTRIV2::unloadModel (model_id);
+        if (status != 0)
+          return status;
+
+        size_t alloc_total = 0;
+        size_t free_total = 0;
+
+        status = UtilTRIV2::getMemoryStatus (&alloc_total, &free_total);
+        if (status != 0)
+          return status;
+
+        if (alloc_total != free_total)
+          cerr << "Possible memory leak..? (" << alloc_total << " vs. "
+               << free_total << ")\n";
+      }
+      return wait () == num_iter_ ? test_ret_success : test_ret_failure;
+    } else {
+      cerr << "Unsupported mode... use 1 (fast) or 2 (slow)\n";
+      return test_ret_failure;
+    }
   }
 
  private:
-  uint32_t model_id_;
+  string model_dir_;
   uint32_t num_iter_;
+  uint32_t mode_;
 };
 
 /** @brief apptest main  */
 int
 main (int argc, char **argv) {
-  const char *help = "model_dir num_iterations";
+  const char *help = "model_dir num_iterations test_mode";
   Tester tester;
   int status;
   int index;
@@ -83,14 +145,19 @@ main (int argc, char **argv) {
   if (status == test_ret_skipped || index < 0)
     goto skip;
 
-  if (argc < index + 2) {
+  if (argc < index + 3) {
     cerr << "Need additional argument..\n";
     tester.printUsage (argv[0], help);
     goto skip;
   }
 
   /** initialize triv2 device */
-  status = tester.init (argv[index], argv[index + 1]);
+  status = tester.init (argv[index]);
+  if (status < test_ret_success)
+    goto err;
+
+  /** configure testing */
+  status = tester.config (argv[index + 1], argv[index + 2]);
   if (status < test_ret_success)
     goto err;
 
index 0627ba1..84739e5 100644 (file)
@@ -427,6 +427,18 @@ free_meta:
   return status;
 }
 
+int
+UtilTrinity::unloadModel (uint32_t model_id) {
+  for (auto it = models_.begin (); it != models_.end (); it++) {
+    if ((*it)->getModelID () == model_id) {
+      unregisterNPUmodel (dev_, model_id);
+      models_.erase (it);
+      return 0;
+    }
+  }
+  return -ENOENT;
+}
+
 /** @brief find the utility model instance */
 UtilModel *
 UtilTrinity::findModel (uint32_t model_id) {
@@ -695,6 +707,11 @@ UtilTrinity::getProfile (int req_id, npu_profile *profile) {
   return getNPU_profile_opt (dev_, req_id, opt, profile);
 }
 
+int
+UtilTrinity::getMemoryStatus (size_t *alloc_total, size_t *free_total) {
+  return getNPU_memoryStatus (dev_, alloc_total, free_total);
+}
+
 /** @brief configure constraint for the model */
 int
 UtilTrinity::set_constraint (uint32_t model_id, uint32_t timeout,
index f7d3ad8..175826c 100644 (file)
@@ -119,6 +119,7 @@ class UtilTrinity {
   int loadModel (std::string dirpath, uint32_t *model_id,
                  npu_priority priority = NPU_PRIORITY_MID,
                  uint32_t timeout = 5000);
+  int unloadModel (uint32_t model_id);
 
   int createRequest (uint32_t model_id);
   int submitRequest (int req_id);
@@ -133,6 +134,7 @@ class UtilTrinity {
   int stopInternal (int req_id);
 
   int getProfile (int req_id, npu_profile *profile);
+  int getMemoryStatus (size_t *alloc_total, size_t *free_total);
 
   UtilModel *findModel (uint32_t model_id);