[Test/Preempt] Add an apptest to test the task preemption
authorDongju Chae <dongju.chae@samsung.com>
Wed, 17 Mar 2021 03:53:30 +0000 (12:53 +0900)
committer송욱/On-Device Lab(SR)/Staff Engineer/삼성전자 <wook16.song@samsung.com>
Thu, 18 Mar 2021 07:30:19 +0000 (16:30 +0900)
This patch adds an apptest to test the task preemption by comparing
vISA execution sequences.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
tests/apptests/meson.build
tests/apptests/tvn_triv2_preempt.cc [new file with mode: 0644]

index c6aeb19..2b6edd5 100644 (file)
@@ -113,3 +113,13 @@ executable ('apptest_tvn_triv2_profile',
   install_rpath : ne_libdir,
   install_dir : join_paths(ne_bindir, 'apptests')
 )
+
+executable ('apptest_tvn_triv2_preempt',
+  'tvn_triv2_preempt.cc',
+  include_directories : ne_apptest_inc,
+  dependencies : ne_test_utils_dep,
+  link_with : ne_library_shared,
+  install : true,
+  install_rpath : ne_libdir,
+  install_dir : join_paths(ne_bindir, 'apptests')
+)
diff --git a/tests/apptests/tvn_triv2_preempt.cc b/tests/apptests/tvn_triv2_preempt.cc
new file mode 100644 (file)
index 0000000..6457604
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file tvn_triv2_preempt.cc
+ * @date 15 Mar 2021
+ * @brief AppTest to test task preemption
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <ne_test_utils.h>
+
+#define NPU_TIMEOUT_MS  5000
+#define MID_MODEL_NAME  "MOBILENET_V1"
+#define HIGH_MODEL_NAME "MAX_POOL_2D_000"
+
+using namespace std;
+
+/** @brief C++ class to describe how to use npu-engine library */
+class Tester : public UtilTRIV2
+{
+  public:
+    Tester () : mid_model_id_ (0), high_model_id_ (0) {}
+
+    /** @brief initilize the device handle */
+    int init (std::string models_dir) {
+      int status = UtilTRIV2::init ();
+      if (status != test_ret_success) {
+        cerr << "Failed to initialize\n";
+        return status;
+      }
+
+      status = UtilTRIV2::loadModel (models_dir + "/" + MID_MODEL_NAME,
+          &mid_model_id_, NPU_PRIORITY_MID, NPU_TIMEOUT_MS);
+      if (status != test_ret_success) {
+        cerr << "Failed to find a model: " << MID_MODEL_NAME << "\n";
+        return status;
+      }
+
+      status = UtilTRIV2::loadModel (models_dir + "/" + HIGH_MODEL_NAME,
+          &high_model_id_, NPU_PRIORITY_HIGH, NPU_TIMEOUT_MS);
+      if (status != test_ret_success) {
+        cerr << "Failed to find a model: " << HIGH_MODEL_NAME << "\n";
+        return status;
+      }
+
+      return 0;
+    }
+
+    /** @brief run the inference */
+    int run () {
+      if (mid_model_id_ == 0 || high_model_id_ == 0)
+        return test_ret_failure;
+
+      int mid_task_id = UtilTRIV2::run (mid_model_id_);
+      if (mid_task_id < 0)
+        return mid_task_id;
+
+      int high_task_id = UtilTRIV2::run (high_model_id_);
+      if (high_task_id < 0)
+        return high_task_id;
+
+      int result = wait () == 2 ? test_ret_success : test_ret_failure;
+
+      if (result == test_ret_success) {
+        int64_t mid_last_seq = get_last_sequence (mid_task_id);
+        int64_t high_last_seq = get_last_sequence (high_task_id);
+
+        /** The expected execution order: mid --> high --> mid */
+        if (high_last_seq > mid_last_seq) {
+          cerr << "Unable to confirm the evidence of preemption\n";
+          result = test_ret_failure;
+        }
+      }
+
+      return result;
+    }
+
+    /** @brief get the last sequence */
+    int64_t get_last_sequence (int task_id) {
+      npu_profile profile;
+      int64_t sequence = -1;
+      int status;
+
+      status = UtilTRIV2::getProfile (task_id, &profile);
+      if (status == 0) {
+        if (profile.layers != nullptr)
+          sequence = profile.layers[profile.num_layers - 1].visa_exec_seq;
+
+        putNPU_profile (&profile);
+      } else {
+        cerr << "Failed to get profile: " << status << "\n";
+        sequence = status;
+      }
+
+      return sequence;
+    }
+
+  private:
+    uint32_t mid_model_id_;
+    uint32_t high_model_id_;
+};
+
+/** @brief apptest main  */
+int
+main (int argc, char **argv)
+{
+  Tester tester;
+  char * dir;
+  int status;
+
+  status = tester.parseArgs (argc, argv, &dir, "[models' dir]");
+  if (status == test_ret_skipped || dir == nullptr)
+    goto skip;
+  else if (status != test_ret_success)
+    goto err;
+
+  /** initialize triv2 device */
+  status = tester.init (dir);
+  if (status < test_ret_success)
+    goto err;
+
+  /** run the inference with the device */
+  status = tester.run ();
+  if (status < test_ret_success)
+    goto err;
+
+  cerr << "[APPTEST] " << argv[0] << ": PASSED\n";
+  return 0;
+
+err:
+  cerr << "[APPTEST] " << argv[0] << ": FAILED (" << status << ")\n";
+  return status;
+
+skip:
+  cerr << "[APPTEST] " << argv[0] << ": SKIPPED\n";
+  return 0;
+}