This patch adds API to submit requests for kernel modules.
Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
* @note The data and its data info are user-expected ones. When data format/type are
* different from the model-assumed ones, npu-engine performs data manipulation
* internally (e.g., NHWC <-> TRIV2).
+ * @note it's not necessary if you're going to use submitNPU_requestKernel()
*/
int setNPU_requestData (npudev_h dev, int req_id, input_buffers *input,
tensors_data_info *in_info, output_buffers *output,
* @param[in] cb The output callback handler
* @param[in] [nullable] data The data to pass to callback handler
* @return 0 if no error. Otherwise a negative errno
+ * @note it's not necessary if you're going to use submitNPU_requestKernel()
*/
int setNPU_requestCallback (npudev_h dev, int req_id, npuOutputNotify cb,
void *data);
* @param[in] req_id The request ID
* @param[in] mode Configures how this inference works.
* @return 0 if no error. Otherwise a negative errno
+ * @note it's not necessary if you're going to use submitNPU_requestKernel()
*/
int setNPU_requestMode (npudev_h dev, int req_id, npu_infer_mode mode);
*/
int submitNPU_request (npudev_h dev, int req_id);
+/**
+ * @brief Submit the request to the NPU working with kernel modules
+ * @param[in] dev The NPU device handle
+ * @param[in] req_id The request 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.
+ */
+int submitNPU_requestKernel (npudev_h dev, int req_id);
+
+/**
+ * @brief Stop the request submitted by submitNPU_requestKernel
+ * @param[in] dev The NPU device handle
+ * @param[in] req_id The request ID
+ * @return 0 if no error. Otherwise a negative errno
+ * @note after calling this, the request will be no longer valid.
+ */
+int stopNPU_requestKernel (npudev_h dev, int req_id);
+
#if defined(__cplusplus)
}
#endif
}
/**
+ * @brief Submit the request to the NPU working with kernel modules
+ * @param[in] req_id The request ID
+ * @return 0 if no error. Otherwise a negative errno
+ */
+int
+HostHandler::submitRequestKernel (int req_id) {
+ return device_->submitRequestKernel (req_id);
+}
+
+/**
+ * @brief Stop the request submitted by submitRequsetKernel
+ * @param[in] req_id The request ID
+ * @return 0 if no error. Otherwise a negative errno
+ * @note after calling this, the request will be no longer valid.
+ */
+int
+HostHandler::stopRequestKernel (int req_id) {
+ return device_->stopRequestKernel (req_id);
+}
+/**
* @brief Execute inference.
* @param[in] model_id The model id to be inferred
* @param[in] mode Configures how this inference works.
return status;
}
+int
+TrinityVision2::submitRequestKernel (int req_id) {
+ Request *req = scheduler_->findRequest (req_id);
+ if (req == nullptr) {
+ logerr (TAG, "Unable to find the request with ID (%d)\n", req_id);
+ return -ENOENT;
+ }
+
+ const Model *model = req->getModel ();
+ SegmentTable *segt = dynamic_cast<SegmentTable *> (req->getInferData ());
+ if (segt != nullptr) {
+ logwarn (TAG, "Segment table with user-provided data is destroyed\n");
+ delete segt;
+ }
+
+ /* dummy input/ouput */
+ input_buffers input = {0};
+ output_buffers output = {0};
+
+ input.num_buffers = 1;
+ input.bufs[0].type = BUFFER_DMABUF;
+ input.bufs[0].dmabuf = -1; /* indicator of kernel input */
+
+ output.num_buffers = 1;
+ output.bufs[0].type = BUFFER_DMABUF;
+ output.bufs[0].dmabuf = -2; /* indicator of kernel output */
+
+ segt = prepareSegmentTable (model, &input, &output);
+
+ req->setInferData (segt);
+ req->setPreserved (true);
+ return scheduler_->submitRequest (req);
+}
+
+int
+TrinityVision2::stopRequestKernel (int req_id) {
+ Request *req = scheduler_->findRequest (req_id);
+ if (req == nullptr) {
+ logerr (TAG, "Unable to find the request with ID (%d)\n", req_id);
+ return -ENOENT;
+ }
+
+ return scheduler_->stopRequestKernel (req);
+}
+
/** Implement data manipulation (each device may have different impl.) */
#ifdef ENABLE_MANIP
int setRequestConstraint (int req_id, npu_constraint constraint);
int setRequestNpumgrParam (int req_id, npumgr_param param);
int submitRequest (int req_id);
+ int submitRequestKernel (int req_id);
+ int stopRequestKernel (int req_id);
/** @brief get statistics */
int getMemoryStatus (size_t *alloc_total, size_t *free_total);
virtual int setRequestConstraint (int req_id, npu_constraint constraint) = 0;
virtual int setRequestNpumgrParam (int req_id, npumgr_param param) = 0;
virtual int submitRequest (int req_id) = 0;
+ virtual int submitRequestKernel (int req_id) = 0;
+ virtual int stopRequestKernel (int req_id) = 0;
protected:
/** the device instance has ownership of all related components */
int setRequestConstraint (int req_id, npu_constraint constraint);
int setRequestNpumgrParam (int req_id, npumgr_param param);
int submitRequest (int req_id);
+ int submitRequestKernel (int req_id);
+ int stopRequestKernel (int req_id);
private:
void callback (Request *req, npuOutputNotify cb, void *cb_data);
: opmode_ (opmode),
force_stop_ (false),
stopped_ (false),
+ preserved_ (false),
model_ (nullptr),
data_ (nullptr),
cb_ (nullptr),
callback ();
/** the request instance is also deleted here */
- removeRequest (req);
+ if (!req->isPreserved ())
+ removeRequest (req);
}
/**
/* thread-safe map */
return request_map_.find (req_id);
}
+
+int
+Scheduler::stopRequestKernel (Request *req) {
+ if (req == nullptr) {
+ logerr (TAG, "Invalid request to stop\n");
+ return -EINVAL;
+ }
+
+ SegmentTable *segt = dynamic_cast<SegmentTable *> (req->getInferData ());
+ if (segt != nullptr)
+ delete segt;
+ else
+ logwarn (TAG, "Unable to find the request's segment table\n");
+
+ removeRequest (req);
+ return 0;
+}
void setForceStop (bool force_stop) { force_stop_ = force_stop; }
bool getForceStop () { return force_stop_; }
+ void setPreserved (bool preserved) { preserved_ = preserved; }
+ bool isPreserved () { return preserved_; }
+
npu_input_opmode getOpmode () { return opmode_; }
int getID () { return request_id_; }
npu_input_opmode opmode_; /**< opmode of the request */
bool force_stop_; /**< indicates force stop */
bool stopped_; /**< stopped request */
+ bool preserved_; /**< preserved request */
const Model *model_; /**< model of the request */
HWmem *data_; /**< inference data of the request */
void removeRequest (Request *req);
int submitRequest (Request *req);
Request *findRequest (int req_id);
+ int stopRequestKernel (Request *req);
private:
/**
return host_handler->submitRequest (req_id);
}
+
+/**
+ * @brief Submit the request to the NPU working with kernel modules
+ * @param[in] dev The NPU device handle
+ * @param[in] req_id The request 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.
+ */
+int
+submitNPU_requestKernel (npudev_h dev, int req_id) {
+ INIT_HOST_HANDLER (host_handler, dev);
+
+ return host_handler->submitRequestKernel (req_id);
+}
+
+/**
+ * @brief Stop the request submitted by submitNPU_requestKernel
+ * @param[in] dev The NPU device handle
+ * @param[in] req_id The request ID
+ * @return 0 if no error. Otherwise a negative errno
+ * @note after calling this, the request will be no longer valid.
+ */
+int
+stopNPU_requestKernel (npudev_h dev, int req_id) {
+ INIT_HOST_HANDLER (host_handler, dev);
+
+ return host_handler->stopRequestKernel (req_id);
+}
std::unique_lock<std::mutex> lock (sync.m);
sync.cv.wait (lock, [&]() { return sync.done == true; });
+#ifndef ENABLE_EMUL
+ /* actual testing (kernel) */
+ constraint.priority = NPU_PRIORITY_HIGH;
+
+ /* dummy param */
+ npumgr_param param = {.task_handle = 1, .subtask_idx = 0};
+
+ EXPECT_EQ (createNPU_request (dev, modelid, &req_id), 0);
+ EXPECT_EQ (setNPU_requestConstraint (dev, req_id, constraint), 0);
+ EXPECT_EQ (setNPU_requestNpumgrParam (dev, req_id, param), 0);
+ EXPECT_GE (submitNPU_requestKernel (dev, req_id), 0);
+
+ sleep (1);
+
+ EXPECT_EQ (stopNPU_requestKernel (dev, req_id), 0);
+#endif
+
+ ASSERT_EQ (unregisterNPUmodel (dev, modelid), 0);
putNPUdevice (dev);
}