[NE-scheduler] Interface between N3 and N4
authorParichay Kapoor <pk.kapoor@samsung.com>
Fri, 19 Jul 2019 10:53:26 +0000 (19:53 +0900)
committer함명주/On-Device Lab(SR)/Principal Engineer/삼성전자 <myungjoo.ham@samsung.com>
Mon, 29 Jul 2019 02:23:35 +0000 (11:23 +0900)
N3's interface takes in the input_mode op along with list of submodels or a model
However, N4C interface takes in the n4_opmode which points to the device to be run
This patch links the two interface in N3 implementation

Signed-off-by: Parichay Kapoor <pk.kapoor@samsung.com>
core/npu-engine/src/ne-scheduler.c

index c32109b..4a1bc68 100644 (file)
 
 /** @brief private structure for N3 */
 typedef struct {
-  n4_opmode cur_opmode;
+  n4_opmode input_opmode;
   output_ready n2_cb;
+  model *model;
+  list running_ops;
 } scheduler_priv;
 
 /** @brief N3 internal private data */
@@ -39,7 +41,7 @@ void init_ne_scheduler (void) __attribute__ ((constructor));
  * @param[in] op npu_input_opmode
  * @return n4_opmode
  */
-static n4_opmode 
+static n4_opmode
 opmode_npu_to_n4 (npu_input_opmode op)
 {
   switch (op) {
@@ -55,22 +57,74 @@ opmode_npu_to_n4 (npu_input_opmode op)
 }
 
 /**
- * @brief request configure() for all submodels to N4
+ * @brief request stop() for all submodels to N4
+ * @param[in] op n4_opmode
+ * @param[in] stop_cond stopping condition for n4x
+ * @return 0 if ok, otherwise a negative errrno
+ */
+static int
+stop_all_services (model *model, stop_condition stop_cond)
+{
+  submodel *smodel;
+  int err = 0;
+  n4_opmode op;
+
+  assert (model);
+
+  list_for_each_entry (smodel, model->submodels, list) {
+    op = (n4_opmode) smodel->meta->type;
+    if ((err = n4_stop (op, stop_cond)) < 0) {
+      logerr (TAG, "Error stopping the model with op %d\n", op);
+    }
+  }
+
+  return 0;
+}
+
+/**
+ * @brief request start() for all submodels to N4
  * @param[in] op n4_opmode
+ * @return 0 if ok, otherwise a negative errrno
+ */
+static int
+start_all_services (model *model)
+{
+  submodel *smodel;
+  int err;
+  n4_opmode op;
+
+  assert (model);
+
+  list_for_each_entry (smodel, model->submodels, list) {
+    op = (n4_opmode) smodel->meta->type;
+    if ((err = n4_start (op)) < 0) {
+      stop_all_services (model, STOP_PREEMPT);
+      return err;
+    }
+  }
+
+  return 0;
+}
+
+/**
+ * @brief request configure() for all submodels to N4
+ * @param[in] input_op input service op
  * @param[in] model model
  * @param[in] cb output ready callback
  * @param[in] cb_data callback data
  * @return 0 if ok, otherwise a negative errrno
  */
 static int
-config_all_submodels (n4_opmode op, model *model, output_ready cb, void *cb_data)
+config_all_services (model *model, output_ready cb, void *cb_data)
 {
   submodel *smodel;
   int err;
+  n4_opmode op;
 
   assert (model);
 
   list_for_each_entry (smodel, model->submodels, list) {
+    op = (n4_opmode) smodel->meta->type;
     if ((err = n4_configure (op, smodel, cb, cb_data)) < 0)
       return err;
   }
@@ -101,47 +155,59 @@ n3_cb (buffer *buf, uint64_t offset, uint64_t size, void *data)
 int n3_setOpMode(npu_input_opmode op, int force, model *model,
                  output_ready cb, void *cb_data)
 {
-  n4_opmode n4_op;
+  n4_opmode n4_input_op;
   int err;
+  stop_condition stop_cond;
 
   if (!model) {
     logerr (TAG, "A valid model was not provided\n");
     return -EINVAL;
   }
 
+  stop_cond = force ? STOP_PREEMPT : STOP_TRY;
   if (op == NPUINPUT_STOP) {
-    if (spriv.cur_opmode == N4_OPS_END) {
+    if (spriv.input_opmode == N4_OPS_END) {
       logerr (TAG, "No input service was working\n");
       return -EINVAL;
     }
 
-    if ((err = n4_stop (spriv.cur_opmode, force ? STOP_PREEMPT : STOP_TRY)) == 0)
-      spriv.cur_opmode = N4_OPS_END;
+    if ((err = stop_all_services (spriv.model, stop_cond)) != 0) {
+      logerr (TAG, "Error stopping the model\n");
+    }
+    spriv.input_opmode = N4_OPS_END;
+    spriv.model = NULL;
 
     return err;
   }
 
   /* start */
-  n4_op = opmode_npu_to_n4 (op);
-  if (n4_op == N4_OPS_END) {
+  n4_input_op = opmode_npu_to_n4 (op);
+  if (n4_input_op == N4_OPS_END) {
     logerr (TAG, "Unknown npu input opmode (%d)\n", op);
     return -EINVAL;
   }
 
-  if (spriv.cur_opmode != N4_OPS_END) {
+  if (spriv.input_opmode != N4_OPS_END) {
     /* wait or preempt the previous one */
-    if ((err = n4_stop (spriv.cur_opmode, force ? STOP_PREEMPT : STOP_WAIT)) != 0)
+    if ((err = stop_all_services (spriv.model, stop_cond)) != 0) {
+      logerr (TAG, "Error stopping the model\n");
       return err;
+    }
   }
 
   spriv.n2_cb = cb;
-  if ((err = config_all_submodels (n4_op, model, n3_cb, cb_data)) < 0)
+  if ((err = config_all_services (model, n3_cb, cb_data)) < 0) {
+    logerr (TAG, "Error configuring the submodels\n");
     return err;
+  }
 
-  if ((err = n4_start (n4_op)) < 0)
+  if ((err = start_all_services (model)) < 0) {
+    logerr (TAG, "Error starting the submodels\n");
     return err;
+  }
 
-  spriv.cur_opmode = n4_op;
+  spriv.input_opmode = n4_input_op;
+  spriv.model = model;
 
   return 0;
 }
@@ -152,11 +218,16 @@ int n3_setOpMode(npu_input_opmode op, int force, model *model,
  */
 int n3_dataReady(void)
 {
-  if (spriv.cur_opmode == N4_OPS_END) {
+  if (spriv.input_opmode == N4_OPS_END) {
     logerr (TAG, "No input service yet\n");
     return -EINVAL;
   }
 
+  if (spriv.input_opmode != N4_OPS_HOST_INPUT) {
+    logerr (TAG, "Operation only permitted for host input mode\n");
+    return -EPERM;
+  }
+
   return n4_dataReady ();
 }
 
@@ -176,6 +247,7 @@ buffer *n3_getNextBuffer(buffer_role role, int *err)
  */
 void init_ne_scheduler (void)
 {
-  spriv.cur_opmode = N4_OPS_END;
+  spriv.input_opmode = N4_OPS_END;
   spriv.n2_cb = NULL;
+  spriv.model = NULL;
 }