This patch uses request id from kernel drvier.
It makes system-wise unique request id.
Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
}
Request *req = scheduler_->createRequest ();
+ if (req == nullptr) {
+ logerr (TAG, "Failed to create a request\n");
+ return -EINVAL;
+ }
req->setOpmode (NPUINPUT_HOST);
req->setModel (model);
}
req = scheduler_->createRequest ();
+ if (req == nullptr) {
+ logerr (TAG, "Failed to create a request\n");
+ return -EINVAL;
+ }
+
req->setModel (model);
req->setPreserved (true);
#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),
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 () {
class Request {
public:
- Request ();
+ Request (int req_id = 0);
~Request ();
void setModel (const Model *model) { model_ = model; }
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 */
*/
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;
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; }
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;
~TrinityEmulAPI ();
int open ();
+ int getNextRequest (int32_t *req_id) const;
+
device_state_t isReady () const;
int alloc (size_t size, bool contiguous) const;
#include <iostream>
+#define TAG _N94
#define MAX_EMUL_DEVICES (3)
+
static uint64_t global_exec_seq = 0;
class EmulReq {
return true;
}
+ static std::atomic<int> global_id;
+
private:
int req_id_;
bool stop_;
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;
}
/**
+ * @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.
*/
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;
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));
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));
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 ());
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 ());
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 ());
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));
}
/**
+ * @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) {
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);
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);