[handler] implement each device's unsetModel() to call deregisterModel()
authorDongju Chae <dongju.chae@samsung.com>
Tue, 26 May 2020 06:58:46 +0000 (15:58 +0900)
committer송욱/On-Device Lab(SR)/Staff Engineer/삼성전자 <wook16.song@samsung.com>
Wed, 27 May 2020 01:03:44 +0000 (10:03 +0900)
This patch adds missing unsetModel() to call api->deregisterModel().

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
src/core/ne-handler.cc
src/core/ne-handler.h
src/core/npu/NPUdrvAPI.h
src/core/npu/NPUdrvAPI_emul.cc

index 5afde45..37a78b6 100644 (file)
@@ -535,6 +535,16 @@ HostHandler::registerModel (generic_buffer *model_buf, uint32_t *modelid)
 int
 HostHandler::unregisterModel (uint32_t modelid)
 {
+  Model *model = models_.find (modelid);
+  if (model == nullptr)
+    return -ENOENT;
+
+  int status = device_->unsetModel (model);
+  if (status != 0) {
+    logerr (TAG, "Failed to unset model: %d\n", status);
+    return status;
+  }
+
   return models_.remove (modelid);
 }
 
@@ -1146,6 +1156,30 @@ delete_exit:
 }
 
 /**
+ * @brief implementation of TRIV's unsetModel ()
+ * @param[in] model the model instance
+ * @return 0 if no error, otherwise a negative errno
+ */
+int
+TrinityVision::unsetModel (Model * model)
+{
+  if (!initialized ()) {
+    logerr (TAG, "Uninitialized device; should use libnpuhost APIs\n");
+    return -EPERM;
+  }
+
+  if (model == nullptr) {
+    logerr (TAG, "Invalid model instance\n");
+    return -EINVAL;
+  }
+
+  if (model->getMetadata()->getProgramSize() > 0)
+    return api_->deregisterModel (model->getInternalID ());
+
+  return 0;
+}
+
+/**
  * @brief implementation of TRIV's run()
  * @param[in] opmode input opmode
  * @param[in] model the model instance
@@ -1408,6 +1442,30 @@ delete_exit:
   return status;
 }
 
+/**
+ * @brief implementation of TRIV2's unsetModel ()
+ * @param[in] model the model instance
+ * @return 0 if no error, otherwise a negative errno
+ */
+int
+TrinityVision2::unsetModel (Model * model)
+{
+  if (!initialized ()) {
+    logerr (TAG, "Uninitialized device; should use libnpuhost APIs\n");
+    return -EPERM;
+  }
+
+  if (model == nullptr) {
+    logerr (TAG, "Invalid model instance\n");
+    return -EINVAL;
+  }
+
+  if (model->getMetadata()->getProgramSize() > 0)
+    return api_->deregisterModel (model->getInternalID ());
+
+  return 0;
+}
+
 /** @brief implementation of TRIV2's run() */
 int
 TrinityVision2::run (npu_input_opmode opmode, const Model *model,
index 86cc682..69f112f 100644 (file)
@@ -103,6 +103,8 @@ class Device {
 
     /** virtual methods to implement each device's behaviors */
     virtual int setModel (const generic_buffer *model, Model ** model_ptr) { return -EPERM; }
+    virtual int unsetModel (Model * model) { return -EPERM; }
+
     virtual int run (npu_input_opmode opmode, const Model *model,
         const input_buffers *input, npuOutputNotify cb = nullptr,
         void *cb_data = nullptr, uint64_t *sequence = nullptr) = 0;
@@ -144,6 +146,7 @@ class TrinityVision : public Device {
     Buffer * prepareInputBuffers (const Metadata *meta, const input_buffers *input);
 
     int setModel (const generic_buffer *model, Model ** model_ptr);
+    int unsetModel (Model * model);
     int run (npu_input_opmode opmode, const Model *model,
         const input_buffers *input, npuOutputNotify cb = nullptr,
         void *cb_data = nullptr, uint64_t *sequence = nullptr);
@@ -164,6 +167,7 @@ class TrinityVision2 : public Device {
     SegmentTable * prepareSegmentTable (const Model *model, const input_buffers *input);
 
     int setModel (const generic_buffer *model, Model ** model_ptr);
+    int unsetModel (Model * model);
     int run (npu_input_opmode opmode, const Model *model,
         const input_buffers *input, npuOutputNotify cb = nullptr,
         void *cb_data = nullptr, uint64_t *sequence = nullptr);
index cf14fdd..6de39b8 100644 (file)
@@ -195,6 +195,7 @@ class TrinityEmulAPI : public DriverAPI {
 
     int runInput (input_config_t *input) const;
     int registerModel (model_config_t *model) const;
+    int deregisterModel (unsigned long long id) const;
 
   private:
     static std::atomic<int> global_fd_;
index fec1326..d2b3b81 100644 (file)
@@ -65,11 +65,11 @@ class EmulElement {
     uint64_t getInternalId () const { return internal_id_; }
 
     void setModelConfig (model_config_t *model) {
-      model_ = *model;
+      model_.reset (model);
     }
 
-    model_config_t & getModelConfig () {
-      return model_;
+    model_config_t * getModelConfig () {
+      return model_.get();
     }
 
   private:
@@ -80,7 +80,7 @@ class EmulElement {
     size_t size_; /**< the allocated size */
     uint64_t internal_id_;
 
-    model_config_t model_;
+    std::unique_ptr<model_config_t> model_;
 };
 
 /**
@@ -96,7 +96,7 @@ EmulElement::EmulElement (size_t size)
   assert (addr_);
   memset (addr_, '\x00', size);
 
-  memset (&model_, '\x00', sizeof (model_config_t));
+  model_.reset(nullptr);
 
   size_ = size;
   dmabuf_ = global_id_.fetch_add (1);
@@ -305,8 +305,33 @@ TrinityEmulAPI::registerModel (model_config_t *model_config) const
   if (elem == nullptr)
     return -ENOENT;
 
-  elem->setModelConfig (model_config);
+  model_config_t * config = new model_config_t;
+
   model_config->id = elem->getInternalId ();
+  memcpy (config, model_config, sizeof (model_config_t));
+
+  elem->setModelConfig (config);
+
+  return 0;
+}
+
+/**
+ * @brief deregister model config to the driver
+ * @param[in] id the model id to be deregistered
+ * @return 0 if no error. otherwise a negative errno
+ */
+int
+TrinityEmulAPI::deregisterModel (unsigned long long id) const
+{
+  if (!initialized())
+    return -EPERM;
+
+  int dbuf_fd = id & TRINITY_MASK_MODEL_DBUF_FD;
+  EmulElement *elem = elem_map_.find (dbuf_fd);
+  if (elem == nullptr)
+    return -ENOENT;
+
+  elem->setModelConfig (nullptr);
 
   return 0;
 }
@@ -342,13 +367,13 @@ TrinityEmulAPI::runInput (input_config_t *input_config) const
   char * addr_model = static_cast<char *>(elem_model->getAddr ());
   char * addr_input = static_cast<char *>(elem_input->getAddr ());
 
-  model_config_t model = elem_model->getModelConfig ();
+  model_config_t model = elem_model->getModelConfig ();
 
   /**
    * call NPU C-emulation codes (AIP/NPU_SystemService_Emulator)
    */
   if ((dev_type_ & DEVICETYPE_MASK) == DEVICETYPE_TRIV) {
-    run_triv_emul (addr_model + model.program_offset_addr, model.program_size,
+    run_triv_emul (addr_model + model->program_offset_addr, model->program_size,
         addr_input);
   } else if ((dev_type_ & DEVICETYPE_MASK) == DEVICETYPE_TRIV2) {
     if (input_config->num_segments <= 0)
@@ -371,7 +396,7 @@ TrinityEmulAPI::runInput (input_config_t *input_config) const
       segment_table[i] = static_cast<char *>(elem->getAddr ()) + offset;
     }
 
-    run_triv2_emul (addr_model + model.program_offset_addr, model.program_size,
+    run_triv2_emul (addr_model + model->program_offset_addr, model->program_size,
         segment_table, num_segs);
     delete [] segment_table;
   }