[API] Add an optional scheduler param when setting npu scheduler
authorDongju Chae <dongju.chae@samsung.com>
Tue, 13 Jul 2021 06:06:30 +0000 (15:06 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Tue, 13 Jul 2021 08:37:23 +0000 (17:37 +0900)
This patch adds an optional scheduler parameter when setting
NPU scheduler. Note that kernel requests do not require such a param.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
include/common/typedef.h
include/host/libnpuhost.h
src/core/ne-handler.cc
src/core/ne-handler.h
src/core/ne-host-input-service.cc
src/core/ne-hw-input-service.cc
src/core/ne-request.cc
src/core/ne-request.h
src/host/ne-host.cc
tests/unittests/ne_libnpuhost_test.cc

index b83b5cc..6b47945 100644 (file)
@@ -233,6 +233,9 @@ typedef enum {
   NPU_SCHEDULER_VD
 } npu_scheduler;
 
+/** @brief optional parameter for npu scheduler */
+typedef void *npu_scheduler_param;
+
 static const uint32_t default_timeout = 3000;
 static const npu_priority default_priority = NPU_PRIORITY_MID;
 static const npu_notimode default_notimode = NPU_INTERRUPT;
index 4b29edf..de35675 100644 (file)
@@ -554,12 +554,13 @@ int setNPU_requestConstraint (npudev_h dev, int req_id,
  * @brief [OPTIONAL] Set the request's scheduler
  * @param[in] dev The NPU device handle
  * @param[in] req_id The request ID
- * @param[in] scheduler npu scheduler
+ * @param[in] sched npu scheduler
+ * @param[in] [nullable] sched_param npu scheduler param
  * @return 0 if no error. Otherwise a negative errno
  * @note if this is not called, the default scheduler is used (see typedef.h).
  */
-int setNPU_requestScheduler (npudev_h dev, int req_id,
-                             npu_scheduler scheculder);
+int setNPU_requestScheduler (npudev_h dev, int req_id, npu_scheduler sched,
+                             npu_scheduler_param sched_param);
 
 /**
  * @brief Submit the request to the NPU
@@ -576,7 +577,8 @@ int submitNPU_request (npudev_h dev, int req_id);
  * @return 0 if no error. Otherwise a negative errno
  * @note this API ignores user-provided input and output data/info because
  *       the reserved kernel modules may provide input and output buffers.
- *       Also, data manipulation is not supported.
+ * @note any data manipulation such as layout conversion is not supported.
+ * @note only VD NPU Scheduler is supported for now.
  */
 int submitNPU_requestKernel (npudev_h dev, int req_id);
 
index 3eb1a36..ccd3bbe 100644 (file)
@@ -390,12 +390,14 @@ HostHandler::setRequestConstraint (int req_id, npu_constraint constraint) {
 /**
  * @brief Set the request's scheduler
  * @param[in] req_id The request ID
- * @param[in] scheduler npu scheduler
+ * @param[in] sched npu scheduler
+ * @param[in] sched_param npu scheduler param
  * @return 0 if no error. Otherwise a negative errno
  */
 int
-HostHandler::setRequestScheduler (int req_id, npu_scheduler scheduler) {
-  return device_->setRequestScheduler (req_id, scheduler);
+HostHandler::setRequestScheduler (int req_id, npu_scheduler sched,
+                                  npu_scheduler_param sched_param) {
+  return device_->setRequestScheduler (req_id, sched, sched_param);
 }
 
 /**
@@ -1327,14 +1329,15 @@ TrinityVision2::setRequestConstraint (int req_id, npu_constraint constraint) {
 }
 
 int
-TrinityVision2::setRequestScheduler (int req_id, npu_scheduler scheduler) {
+TrinityVision2::setRequestScheduler (int req_id, npu_scheduler sched,
+                                     npu_scheduler_param sched_param) {
   Request *req = scheduler_->findRequest (req_id);
   if (req == nullptr) {
     logerr (TAG, "Unable to find the request with ID (%d)\n", req_id);
     return -ENOENT;
   }
 
-  req->setScheduler (scheduler);
+  req->setScheduler (sched, sched_param);
 
   return 0;
 }
@@ -1423,6 +1426,8 @@ TrinityVision2::submitRequestKernel (int req_id) {
 
   segt = prepareSegmentTable (model, &input, &output);
 
+  if (req->getScheduler () != NPU_SCHEDULER_VD)
+    req->setScheduler (NPU_SCHEDULER_VD, nullptr);
   req->setOpmode (NPUINPUT_HW_RECURRING);
   req->setInferData (segt);
   return scheduler_->submitRequest (req);
index bf8e83f..43f2fa5 100644 (file)
@@ -70,7 +70,8 @@ class HostHandler {
   int setRequestCallback (int req_id, npuOutputNotify cb, void *data);
   int setRequestMode (int req_id, npu_infer_mode mode);
   int setRequestConstraint (int req_id, npu_constraint constraint);
-  int setRequestScheduler (int req_id, npu_scheduler scheduler);
+  int setRequestScheduler (int req_id, npu_scheduler sched,
+                           npu_scheduler_param sched_param);
 
   int submitRequest (int req_id);
   int submitRequestKernel (int req_id);
@@ -157,7 +158,8 @@ class Device {
                                   void *data) = 0;
   virtual int setRequestMode (int req_id, npu_infer_mode mode) = 0;
   virtual int setRequestConstraint (int req_id, npu_constraint constraint) = 0;
-  virtual int setRequestScheduler (int req_id, npu_scheduler scheduler) = 0;
+  virtual int setRequestScheduler (int req_id, npu_scheduler sched,
+                                   npu_scheduler_param param) = 0;
   virtual int submitRequest (int req_id) = 0;
   virtual int submitRequestKernel (int req_id) = 0;
 
@@ -219,7 +221,8 @@ class TrinityVision2 : public Device {
   int setRequestCallback (int req_id, npuOutputNotify cb, void *data);
   int setRequestMode (int req_id, npu_infer_mode mode);
   int setRequestConstraint (int req_id, npu_constraint constraint);
-  int setRequestScheduler (int req_id, npu_scheduler scheduler);
+  int setRequestScheduler (int req_id, npu_scheduler sched,
+                           npu_scheduler_param sched_param);
   int submitRequest (int req_id);
   int submitRequestKernel (int req_id);
 
index f15fafb..512029b 100644 (file)
@@ -96,14 +96,18 @@ invoke_buffer (const DriverAPI *api, const Request *req) {
   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_SR) {
-    input_config.task_handle = UINT32_MAX;
-    input_config.subtask_idx = UINT32_MAX;
-  } else {
-    input_config.task_handle = 0;
-    input_config.subtask_idx = 0;
+  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 */
@@ -137,14 +141,18 @@ invoke_segt (const DriverAPI *api, const Request *req) {
   input_config.dbuf_fd = segt->getDmabuf ();
   input_config.req_id = req->getID ();
   input_config.num_segments = segt->getNumTotalSegments ();
+  input_config.task_handle = UINT32_MAX;
+  input_config.subtask_idx = UINT32_MAX;
 
   /** FIXME: update input_config fields */
-  if (req->getScheduler () == NPU_SCHEDULER_SR) {
-    input_config.task_handle = UINT32_MAX;
-    input_config.subtask_idx = UINT32_MAX;
-  } else {
-    input_config.task_handle = 0;
-    input_config.subtask_idx = 0;
+  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;
+    }
   }
 
   /** set constraints */
index 2d54caa..75a2d1a 100644 (file)
@@ -96,14 +96,18 @@ invoke_segt (const DriverAPI *api, const Request *req) {
   input_config.dbuf_fd = segt->getDmabuf ();
   input_config.req_id = req->getID ();
   input_config.num_segments = segt->getNumTotalSegments ();
+  input_config.task_handle = UINT32_MAX;
+  input_config.subtask_idx = UINT32_MAX;
 
   /** FIXME: update input_config fields */
-  if (req->getScheduler () == NPU_SCHEDULER_SR) {
-    input_config.task_handle = UINT32_MAX;
-    input_config.subtask_idx = UINT32_MAX;
-  } else {
-    input_config.task_handle = 0;
-    input_config.subtask_idx = 0;
+  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;
+    }
   }
 
   /** set constraints */
index 45fdaa0..3a2c002 100644 (file)
@@ -27,7 +27,8 @@ Request::Request ()
       cb_ (nullptr),
       out_bufs_ (nullptr),
       infer_mode_ (NPU_INFER_BLOCKING /* default */),
-      sched_ (default_scheduler) {
+      sched_ (default_scheduler),
+      sched_param_ (nullptr) {
   request_id_ = Request::global_request_id_.fetch_add (1);
 }
 
index 03e1ccc..153a0a5 100644 (file)
@@ -62,8 +62,13 @@ class Request {
   void setInferMode (npu_infer_mode infer_mode) { infer_mode_ = infer_mode; }
   npu_infer_mode getInferMode () const { return infer_mode_; }
 
-  void setScheduler (const npu_scheduler &sched) { sched_ = sched; }
+  void setScheduler (const npu_scheduler &sched,
+                     const npu_scheduler_param &sched_param) {
+    sched_ = sched;
+    sched_param_ = sched_param;
+  }
   npu_scheduler getScheduler () const { return sched_; }
+  npu_scheduler_param getSchedulerParam () const { return sched_param_; }
 
  private:
   static std::atomic<int> global_request_id_;
@@ -83,7 +88,9 @@ class Request {
   std::string hw_dev_;       /**< HW device path */
 
   npu_infer_mode infer_mode_;
+
   npu_scheduler sched_;
+  npu_scheduler_param sched_param_;
 };
 
 #endif /* NE_REQUEST_H__ */
index 36de3d2..3137832 100644 (file)
@@ -811,15 +811,17 @@ setNPU_requestConstraint (npudev_h dev, int req_id, npu_constraint constraint) {
  * @brief [OPTIONAL] Set the request's scheduler
  * @param[in] dev The NPU device handle
  * @param[in] req_id The request ID
- * @param[in] scheduler npu scheduler
+ * @param[in] sched npu scheduler
+ * @param[in] [nullable] sched_param npu scheduler param
  * @return 0 if no error. Otherwise a negative errno
  * @note if this is not called, the default scheduler is used (see typedef.h).
  */
 int
-setNPU_requestScheduler (npudev_h dev, int req_id, npu_scheduler scheduler) {
+setNPU_requestScheduler (npudev_h dev, int req_id, npu_scheduler sched,
+                         npu_scheduler_param sched_param) {
   INIT_HOST_HANDLER (host_handler, dev);
 
-  return host_handler->setRequestScheduler (req_id, scheduler);
+  return host_handler->setRequestScheduler (req_id, sched, sched_param);
 }
 
 /**
index a214b00..f11231d 100644 (file)
@@ -827,7 +827,6 @@ TEST (ne_libnpuhost_test, request_decoupled_apis) {
   for (int i = 0; i < MAX_ITERS; i++) {
     EXPECT_EQ (createNPU_request (dev, modelid, &req_ids[i]), 0);
     EXPECT_EQ (setNPU_requestConstraint (dev, req_ids[i], constraint), 0);
-    EXPECT_EQ (setNPU_requestScheduler (dev, req_ids[i], NPU_SCHEDULER_VD), 0);
     EXPECT_EQ (submitNPU_requestKernel (dev, req_ids[i]), 0);
   }