From c3ed64564878dc7ddae5479bcf3f4168c150f81d Mon Sep 17 00:00:00 2001 From: Parichay Kapoor Date: Fri, 19 Jul 2019 19:53:26 +0900 Subject: [PATCH] [NE-scheduler] Interface between N3 and N4 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 --- core/npu-engine/src/ne-scheduler.c | 106 +++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 17 deletions(-) diff --git a/core/npu-engine/src/ne-scheduler.c b/core/npu-engine/src/ne-scheduler.c index c32109b..4a1bc68 100644 --- a/core/npu-engine/src/ne-scheduler.c +++ b/core/npu-engine/src/ne-scheduler.c @@ -24,8 +24,10 @@ /** @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; } -- 2.7.4