[Converage] Increase code coverage for input services
authorDongju Chae <dongju.chae@samsung.com>
Fri, 6 Aug 2021 02:42:37 +0000 (11:42 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Fri, 6 Aug 2021 06:50:24 +0000 (15:50 +0900)
This patch increases code coverage for input services.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
src/core/ne-host-input-service.cc
src/core/ne-hw-input-service.cc
src/core/npu/NPUdrvAPI_emul.cc
tests/unittests/ne_core_inputservice_test.cc
tests/unittests/ne_libnpuhost_test.cc

index 512029b..d43a0b4 100644 (file)
@@ -73,52 +73,6 @@ HostInputService::remove (const DriverAPI *api, int id) {
 }
 
 /**
- * @brief invoke inference with the buffer (TRIV-1)
- * @param[in] api device driver api
- * @param[in] req request instance
- * @return 0 if no erorr. otherwise a negative errno
- */
-static int
-invoke_buffer (const DriverAPI *api, const Request *req) {
-  /** internal logic error */
-  assert (api != nullptr);
-  assert (req != nullptr);
-
-  Buffer *buffer = dynamic_cast<Buffer *> (req->getInferData ());
-  assert (buffer != nullptr);
-
-  const Model *model = req->getModel ();
-  assert (model != nullptr);
-
-  input_config_t input_config;
-  input_config.model_id = model->getInternalID ();
-  input_config.dbuf_fd = buffer->getDmabuf ();
-  input_config.req_id = req->getID ();
-  input_config.activation_offset_addr0 = buffer->getOffset ();
-  input_config.activation_offset_addr1 = buffer->getOffset ();
-  input_config.task_handle = UINT32_MAX;
-  input_config.subtask_idx = UINT32_MAX;
-
-  /** FIXME: update input_config fields */
-  if (req->getScheduler () == NPU_SCHEDULER_VD) {
-    if (req->getSchedulerParam ()) {
-      memcpy (&input_config.task_handle, req->getSchedulerParam (),
-              sizeof (uint32_t) * 2);
-    } else {
-      input_config.task_handle = 0;
-      input_config.subtask_idx = 0;
-    }
-  }
-
-  /** run the inference with the input */
-  int ret = api->runInput (&input_config);
-  if (ret < 0 && ret != -ECANCELED)
-    logerr (TAG, "Failed to run the NPU inference: %d\n", ret);
-
-  return ret;
-}
-
-/**
  * @brief invoke inference with the segment table (TRIV-2)
  * @param[in] api device driver api
  * @param[in] req request instance
@@ -213,9 +167,7 @@ HostInputService::invoke (const DriverAPI *api, const Request *req,
   }
 
   data = req->getInferData ();
-  if (dynamic_cast<Buffer *> (data))
-    ret = invoke_buffer (api, req);
-  else if (dynamic_cast<SegmentTable *> (data))
+  if (dynamic_cast<SegmentTable *> (data))
     ret = invoke_segt (api, req);
   else /* no inference data; skip */
     ret = 0;
index 75a2d1a..1f202a5 100644 (file)
@@ -105,8 +105,7 @@ invoke_segt (const DriverAPI *api, const Request *req) {
       memcpy (&input_config.task_handle, req->getSchedulerParam (),
               sizeof (uint32_t) * 2);
     } else {
-      input_config.task_handle = 0;
-      input_config.subtask_idx = 0;
+      input_config.task_id = req->getID ();
     }
   }
 
index 8f65f33..8f96b7b 100644 (file)
@@ -31,30 +31,18 @@ static uint64_t global_exec_seq = 0;
 
 class EmulReq {
  public:
-  EmulReq (int req_id)
-      : req_id_ (req_id),
-        stop_ (false),
-        first_run_ (false),
-        cout_orig_ (nullptr) {}
+  EmulReq (int req_id) : req_id_ (req_id), cout_orig_ (nullptr) {}
 
   const char *get_profile_path () const { return prof_path_.c_str (); }
 
   void run_emul (char *prog, char **segt, char *metadata, std::string cmd_path,
                  std::string prof_path) {
-    first_run_ = true;
-
     prof_path_ = prof_path + ".rec";
-    while (!stop_ || first_run_) {
-      setMute (true);
-      run_triv2_emul (prog, segt, metadata, cmd_path.c_str (),
-                      prof_path.c_str ());
-      setMute (false);
-
-      first_run_ = false;
 
-      if (!stop_)
-        std::this_thread::sleep_for (std::chrono::seconds (1));
-    };
+    setMute (true);
+    run_triv2_emul (prog, segt, metadata, cmd_path.c_str (),
+                    prof_path.c_str ());
+    setMute (false);
 
     delete[] segt;
   }
@@ -73,12 +61,7 @@ class EmulReq {
     }
   }
 
-  void run (std::function<void()> func) { req_ = std::thread (func); }
-
-  void stop () {
-    stop_ = true;
-    req_.join ();
-  }
+  void run (std::function<void()> func) { func (); }
 
   bool get_profile (npu_profile *profile) {
     std::ifstream ifs (prof_path_, std::ios::binary);
@@ -221,11 +204,7 @@ class EmulReq {
 
  private:
   int req_id_;
-  bool stop_;
-  bool first_run_;
-  std::thread req_;
   std::string prof_path_;
-
   std::streambuf *cout_orig_;
   std::ofstream ofs_null_;
 };
@@ -656,20 +635,27 @@ TrinityEmulAPI::runInput (input_config_t *input_config) const {
 
     uint32_t num_segs = input_config->num_segments;
     char **segment_table = new char *[num_segs];
+    bool is_kernel = false;
 
     for (uint32_t i = 0; i < num_segs; i++) {
       int32_t dmabuf = reinterpret_cast<int32_t *> (addr_input)[i];
       uint32_t offset = reinterpret_cast<uint32_t *> (
           addr_input + elem_input->getSize () / 2)[i];
 
-      EmulElement *elem = elem_map_.find (dmabuf);
-      if (elem == nullptr) {
-        delete[] segment_table;
-        return -EINVAL;
-      }
+      /** Check it's a kernel request */
+      if (input_config->input_mode != TRINITY_INPUT_HW) {
+        EmulElement *elem = elem_map_.find (dmabuf);
+        if (elem == nullptr) {
+          delete[] segment_table;
+          return -EINVAL;
+        }
 
-      /** Here, set virtual address for emulations */
-      segment_table[i] = static_cast<char *> (elem->getAddr ()) + offset;
+        /** Here, set virtual address for emulations */
+        segment_table[i] = static_cast<char *> (elem->getAddr ()) + offset;
+      } else {
+        is_kernel = true;
+        break;
+      }
     }
 
     std::string cmd_path (prefix_share_);
@@ -700,10 +686,8 @@ TrinityEmulAPI::runInput (input_config_t *input_config) const {
                            static_cast<char *> (elem_metadata->getAddr ()),
                            cmd_path, prof_path);
 
-    req->run (func);
-
-    if (input_config->input_mode != TRINITY_INPUT_HW)
-      req->stop ();
+    if (!is_kernel)
+      req->run (func);
   }
 
   return 0;
@@ -718,15 +702,6 @@ TrinityEmulAPI::stop () const {
   if (!initialized ())
     return -EPERM;
 
-#if 0
-  if ((dev_type_ & DEVICETYPE_MASK) == DEVICETYPE_TRIV) {
-    return stop_triv_emul ();
-  } else if ((dev_type_ & DEVICETYPE_MASK) == DEVICETYPE_TRIV2) {
-    return stop_triv2_emul ();
-  }
-
-  return -EPERM;
-#endif
   return 0;
 }
 
@@ -739,7 +714,6 @@ TrinityEmulAPI::stop_target (int req_id) const {
   if (req == nullptr)
     return -ENOENT;
 
-  req->stop ();
   req_map_.remove (req_id);
 
   return 0;
index 0555036..5e08f81 100644 (file)
@@ -138,7 +138,31 @@ TEST (ne_core_inputservice_test, submit_host_service_args_n) {
 }
 
 /**
- * @brief test features of submit() with error handling
+ * @brief test features of submit() with error handling (model)
+ */
+TEST (ne_core_inputservice_test, submit_hw_service_model_n) {
+  std::unique_ptr<DriverAPI> api;
+  npu_input_opmode opmode = NPUINPUT_HW_RECURRING;
+
+  api = DriverAPI::createDriverAPI (NPUCOND_TRIV2_CONN_SOCIP, 0);
+  ASSERT_NE (api.get (), nullptr);
+
+  /** create dummy model */
+  std::unique_ptr<Model> model (new Model (new HWmemDevice));
+  model->setDriverAPI (api.get ());
+  EXPECT_EQ (model->alloc (4096), 0);
+
+  std::unique_ptr<Request> req (new Request (1));
+  req->setOpmode (opmode);
+  req->setModel (model.get ());
+  req->setInferData (new SegmentTable (new HWmemDevice));
+
+  HwInputService &service = HwInputService::getInstance ();
+  EXPECT_NE (service.submit (api.get (), req.get ()), 0);
+}
+
+/**
+ * @brief test features of submit() with error handling (args)
  */
 TEST (ne_core_inputservice_test, submit_hw_service_args_n) {
   std::unique_ptr<DriverAPI> api;
index f11231d..c65be48 100644 (file)
@@ -815,26 +815,33 @@ TEST (ne_libnpuhost_test, request_decoupled_apis) {
 
   EXPECT_EQ (removeNPU_request (dev, req_id), 0);
 
-#ifndef ENABLE_EMUL
   /* actual testing (kernel) */
   constraint.priority = NPU_PRIORITY_HIGH;
 
-#define MAX_ITERS 10
-
-  /* dummy param */
-  int req_ids[MAX_ITERS];
+  const uint32_t max_iters = 10;
+  int req_ids[max_iters];
 
-  for (int i = 0; i < MAX_ITERS; i++) {
+  /* nobody will invoke the requests */
+  for (int i = 0; i < max_iters; i++) {
     EXPECT_EQ (createNPU_request (dev, modelid, &req_ids[i]), 0);
+    /* regardless of setting which scheduler, kernel requests will use the VD scheculder */
+    if ((i % 3) == 1) {
+      EXPECT_EQ (
+          setNPU_requestScheduler (dev, req_ids[i], NPU_SCHEDULER_SR, nullptr),
+          0);
+    } else if ((i % 3) == 2) {
+      EXPECT_EQ (
+          setNPU_requestScheduler (dev, req_ids[i], NPU_SCHEDULER_VD, nullptr),
+          0);
+    }
     EXPECT_EQ (setNPU_requestConstraint (dev, req_ids[i], constraint), 0);
     EXPECT_EQ (submitNPU_requestKernel (dev, req_ids[i]), 0);
   }
 
   sleep (1);
 
-  for (int i = 0; i < MAX_ITERS; i++)
+  for (int i = 0; i < max_iters; i++)
     EXPECT_EQ (removeNPU_request (dev, req_ids[i]), 0);
-#endif
 
   ASSERT_EQ (unregisterNPUmodel (dev, modelid), 0);
   putNPUdevice (dev);