[Req] use request id from kernel driver
authorDongju Chae <dongju.chae@samsung.com>
Mon, 19 Jul 2021 01:28:01 +0000 (10:28 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Mon, 19 Jul 2021 05:15:41 +0000 (14:15 +0900)
This patch uses request id from kernel drvier.
It makes system-wise unique request id.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
src/core/ne-handler.cc
src/core/ne-request.cc
src/core/ne-request.h
src/core/ne-scheduler.cc
src/core/npu/NPUdrvAPI.h
src/core/npu/NPUdrvAPI_emul.cc
src/core/npu/NPUdrvAPI_triv2.cc
tests/unittests/ne_core_inputservice_test.cc
tests/unittests/ne_core_sched_test.cc

index ccd3bbe..1447715 100644 (file)
@@ -1073,6 +1073,10 @@ TrinityVision2::run (npu_input_opmode opmode, const Model *model,
   }
 
   Request *req = scheduler_->createRequest ();
+  if (req == nullptr) {
+    logerr (TAG, "Failed to create a request\n");
+    return -EINVAL;
+  }
 
   req->setOpmode (NPUINPUT_HOST);
   req->setModel (model);
@@ -1174,6 +1178,11 @@ TrinityVision2::createRequest (const Model *model, int *req_id) {
   }
 
   req = scheduler_->createRequest ();
+  if (req == nullptr) {
+    logerr (TAG, "Failed to create a request\n");
+    return -EINVAL;
+  }
+
   req->setModel (model);
   req->setPreserved (true);
 
index 3a2c002..e6eb52b 100644 (file)
 
 #include "ne-request.h"
 
-std::atomic<int> Request::global_request_id_ (1);
-
 /** @brief constructor of request class */
-Request::Request ()
-    : opmode_ (NPUINPUT_HOST),
+Request::Request (int req_id)
+    : request_id_ (req_id),
+      opmode_ (NPUINPUT_HOST),
       force_stop_ (false),
       stopped_ (false),
       preserved_ (false),
@@ -28,9 +27,7 @@ Request::Request ()
       out_bufs_ (nullptr),
       infer_mode_ (NPU_INFER_BLOCKING /* default */),
       sched_ (default_scheduler),
-      sched_param_ (nullptr) {
-  request_id_ = Request::global_request_id_.fetch_add (1);
-}
+      sched_param_ (nullptr) {}
 
 /** @brief destructor of request class */
 Request::~Request () {
index 153a0a5..9cba57d 100644 (file)
@@ -25,7 +25,7 @@
 
 class Request {
  public:
-  Request ();
+  Request (int req_id = 0);
   ~Request ();
 
   void setModel (const Model *model) { model_ = model; }
@@ -71,7 +71,6 @@ class Request {
   npu_scheduler_param getSchedulerParam () const { return sched_param_; }
 
  private:
-  static std::atomic<int> global_request_id_;
   int request_id_; /**< request id */
 
   npu_input_opmode opmode_; /**< opmode of the request */
index 9dacc6a..921fa96 100644 (file)
@@ -84,7 +84,12 @@ Scheduler::handleStop (Request *req) {
  */
 Request *
 Scheduler::createRequest () {
-  Request *req = new Request;
+  int req_id;
+
+  if (api_ == nullptr || api_->getNextRequest (&req_id) != 0)
+    return nullptr;
+
+  Request *req = new Request (req_id);
   /** request ID is atomic value. So, should be successful */
   assert (request_map_.insert (req->getID (), req) == 0);
   return req;
index 385bc77..7d97b25 100644 (file)
@@ -57,6 +57,7 @@ class DriverAPI {
   virtual int getAPILevel (uint32_t *level) const { return -EPERM; }
   virtual int getTops (uint32_t *tops) const { return -EPERM; }
   virtual int getDspmSize (uint32_t *dspm) const { return -EPERM; }
+  virtual int getNextRequest (int32_t *req_id) const { return -EPERM; }
 
   virtual int checkSanity () { return 0; }
 
@@ -143,6 +144,7 @@ class TrinityVision2API : public DriverAPI {
   int getAPILevel (uint32_t *level) const;
   int getTops (uint32_t *tops) const;
   int getDspmSize (uint32_t *dspm) const;
+  int getNextRequest (int32_t *req_id) const;
 
   device_state_t isReady () const;
   uint32_t numRequests () const;
@@ -198,6 +200,8 @@ class TrinityEmulAPI : public DriverAPI {
   ~TrinityEmulAPI ();
 
   int open ();
+  int getNextRequest (int32_t *req_id) const;
+
   device_state_t isReady () const;
 
   int alloc (size_t size, bool contiguous) const;
index c0e5170..7e3a965 100644 (file)
@@ -24,7 +24,9 @@
 
 #include <iostream>
 
+#define TAG _N94
 #define MAX_EMUL_DEVICES (3)
+
 static uint64_t global_exec_seq = 0;
 
 class EmulReq {
@@ -215,6 +217,8 @@ class EmulReq {
     return true;
   }
 
+  static std::atomic<int> global_id;
+
  private:
   int req_id_;
   bool stop_;
@@ -324,7 +328,9 @@ ThreadSafeMap<int, EmulStat> TrinityEmulAPI::stat_map_;
 ThreadSafeMap<int, EmulReq> TrinityEmulAPI::req_map_;
 /** @brief element's global id */
 std::atomic<int> EmulElement::global_id_ (0);
-/** @brief element's global id */
+/** @brief request's global id */
+std::atomic<int> EmulReq::global_id (1);
+/** @brief api's global fd */
 std::atomic<int> TrinityEmulAPI::global_fd_ (0);
 /** @brief global lock for run */
 static std::mutex global_lock;
@@ -365,6 +371,23 @@ TrinityEmulAPI::open () {
 }
 
 /**
+ * @brief get next request id.
+ * @param[out] req_id reqeust id
+ * @return 0 if no error. otherwise a negative errno.
+ */
+int
+TrinityEmulAPI::getNextRequest (int32_t *req_id) const {
+  if (req_id == nullptr) {
+    logerr (TAG, "Invalid argument\n");
+    return -EINVAL;
+  }
+
+  *req_id = EmulReq::global_id.fetch_add (1);
+
+  return 0;
+}
+
+/**
  * @brief get number of available devices. should be enough
  * @return number of available devices.
  */
index cc77c6d..81de78d 100644 (file)
@@ -747,6 +747,32 @@ TrinityVision2API::getDspmSize (uint32_t *dspm) const {
   return ret;
 }
 
+/**
+ * @brief get next request id.
+ * @param[out] req_id reqeust id
+ * @return 0 if no error. otherwise a negative errno.
+ */
+int
+TrinityVision2API::getNextRequest (int32_t *req_id) const {
+  int ret;
+
+  if (!this->initialized ()) {
+    logerr (TAG, "Not yet initialized\n");
+    return -EPERM;
+  }
+
+  if (req_id == nullptr) {
+    logerr (TAG, "Invalid argument\n");
+    return -EINVAL;
+  }
+
+  ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_GET_NEXT_REQUEST, req_id);
+  if (ret != 0)
+    IOCTL_RETURN_ERRNO (TRINITY_IOCTL_GET_NEXT_REQUEST);
+
+  return ret;
+}
+
 int
 TrinityVision2API::getStatApps (npu_stat_apps *stat) const {
   struct trinity_ioctl_stat_apps stat_apps;
index d13f18b..0555036 100644 (file)
@@ -47,7 +47,7 @@ TEST (ne_core_inputservice_test, submit_host_service) {
   model->setDriverAPI (api.get ());
   EXPECT_EQ (model->alloc (4096), 0);
 
-  std::unique_ptr<Request> req (new Request ());
+  std::unique_ptr<Request> req (new Request (1));
   req->setOpmode (opmode);
   req->setModel (model.get ());
   req->setInferData (new SegmentTable (new HWmemDevice));
@@ -65,14 +65,14 @@ TEST (ne_core_inputservice_test, submit_host_service) {
 
   EXPECT_EQ (service.submit (api.get (), req.get (), callback), 0);
 
-  std::unique_ptr<Request> req2 (new Request ());
+  std::unique_ptr<Request> req2 (new Request (2));
   req2->setOpmode (opmode);
   req2->setModel (model.get ());
   req2->setInferData (new Buffer (new HWmemDevice));
 
   EXPECT_EQ (service.submit (api.get (), req2.get (), callback), 0);
 
-  std::unique_ptr<Request> req3 (new Request ());
+  std::unique_ptr<Request> req3 (new Request (3));
   req3->setOpmode (opmode);
   req3->setModel (model.get ());
   req3->setInferData (new SegmentTable (new HWmemDevice));
@@ -101,7 +101,7 @@ TEST (ne_core_inputservice_test, submit_host_service_args_n) {
   HostInputService &service = HostInputService::getInstance ();
 
   /** using buffer */
-  std::unique_ptr<Request> req (new Request ());
+  std::unique_ptr<Request> req (new Request (4));
   req->setOpmode (opmode);
   req->setModel (model.get ());
 
@@ -118,7 +118,7 @@ TEST (ne_core_inputservice_test, submit_host_service_args_n) {
   EXPECT_EQ (service.submit (api.get (), req.get ()), 0);
 
   /** using segment table */
-  std::unique_ptr<Request> req2 (new Request ());
+  std::unique_ptr<Request> req2 (new Request (5));
   req2->setOpmode (opmode);
   req2->setModel (model.get ());
 
@@ -155,7 +155,7 @@ TEST (ne_core_inputservice_test, submit_hw_service_args_n) {
   HwInputService &service = HwInputService::getInstance ();
 
   /** using segment table */
-  std::unique_ptr<Request> req (new Request ());
+  std::unique_ptr<Request> req (new Request (6));
   req->setOpmode (opmode);
   req->setModel (model.get ());
 
@@ -215,7 +215,7 @@ TEST (ne_core_inputservice_test, host_remove) {
   uint32_t num_threads = ThreadPool::getInstance ().getNumThreads ();
   int req_id = 0;
   for (uint32_t i = 0; i < num_threads + 1; i++) {
-    std::unique_ptr<Request> req (new Request ());
+    std::unique_ptr<Request> req (new Request (7 + i));
     req->setOpmode (opmode);
     req->setModel (model.get ());
     req->setInferData (new SegmentTable (new HWmemDevice));
index 46b3813..d774b0b 100644 (file)
@@ -160,6 +160,18 @@ TEST (ne_core_sched_test, submit_request) {
 }
 
 /**
+ * @brief test createRequest() with error handling
+ */
+TEST (ne_core_sched_test, create_request_args_n) {
+  /** no API provided */
+  Scheduler *sched = new Scheduler (nullptr);
+  Request *req = sched->createRequest ();
+  EXPECT_EQ (req, nullptr);
+
+  delete sched;
+}
+
+/**
  * @brief test submitRequest() with error handling
  */
 TEST (ne_core_sched_test, submit_request_args_n) {
@@ -178,8 +190,8 @@ TEST (ne_core_sched_test, submit_request_args_n) {
   std::mutex m;
   auto callback = std::bind (test_callback, &num_called, &m, &cv);
 
-  /** no API provided */
-  Scheduler *sched = new Scheduler (nullptr);
+  /** no request provided */
+  Scheduler *sched = new Scheduler (api.get ());
   Request *req = sched->createRequest ();
   ASSERT_NE (req, nullptr);
   req->setOpmode (NPUINPUT_HOST);
@@ -192,24 +204,6 @@ TEST (ne_core_sched_test, submit_request_args_n) {
   req->setInferData (buffer);
   req->setCallback (callback);
 
-  EXPECT_NE (sched->submitRequest (req), 0);
-  sched->removeRequest (req);
-  delete sched;
-
-  /** no request provided */
-  sched = new Scheduler (api.get ());
-  req = sched->createRequest ();
-  ASSERT_NE (req, nullptr);
-  req->setOpmode (NPUINPUT_HOST);
-
-  buffer = new Buffer (new HWmemDevice);
-  buffer->setDriverAPI (api.get ());
-  buffer->alloc (4096);
-
-  req->setModel (model.get ());
-  req->setInferData (buffer);
-  req->setCallback (callback);
-
   EXPECT_NE (sched->submitRequest (nullptr), 0);
   EXPECT_EQ (sched->submitRequest (req), 0);