[DSPM] Check the model's DSPM size
authorDongju Chae <dongju.chae@samsung.com>
Fri, 23 Jul 2021 02:05:15 +0000 (11:05 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Fri, 23 Jul 2021 04:43:07 +0000 (13:43 +0900)
This patch handles the minimum DSPM size that a model assumes.
If NPU does not have enough DSPM size, the request's denied.

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

index 3d626d3..792197c 100644 (file)
@@ -857,6 +857,34 @@ delete_segt:
 }
 
 /**
+ * @brief check minimum DSPM size that model requires
+ * @param[in] model the model instance
+ * @return 0 if no error, otherwise a negative errno
+ */
+int
+TrinityVision2::checkDspmSize (const Model *model) {
+  uint32_t model_dspm_size = model->getDspmSize ();
+  if (model_dspm_size == 0)
+    /* skip the checking for backward-compatibility */
+    return 0;
+
+  uint32_t npu_dspm_size;
+  int status = api_->getDspmSize (&npu_dspm_size);
+  if (status != 0) {
+    logerr (TAG, "Unable to get the NPU's DSPM size: %d\n", status);
+    return status;
+  }
+
+  if (npu_dspm_size < model_dspm_size) {
+    logerr (TAG, "The minimum DSPM size of model is %u KiB (NPU: %u KiB)\n",
+            model_dspm_size / 1024, npu_dspm_size / 1024);
+    return -ENOMEM;
+  }
+
+  return 0;
+}
+
+/**
  * @brief implementation of TRIV2's setModel ()
  * @param[in] model_buf the model generic buffer
  * @param[out] model the model instance
@@ -905,6 +933,11 @@ TrinityVision2::setModel (const generic_buffer *model_buf, Model **model_ptr) {
   if (status != 0)
     goto delete_exit;
 
+  /** check minimum DSPM Size that a model requires */
+  status = checkDspmSize (model);
+  if (status != 0)
+    goto delete_exit;
+
   /** allocate program (optional; NOP) */
   if (model->getMetadata ()->getProgramSize () > 0) {
     HWmem *hwmem_prog = new HWmem (new HWmemDevice);
index c32b026..39c8f7e 100644 (file)
@@ -207,6 +207,7 @@ class TrinityVision2 : public Device {
 
   int getTensorSize (const Model *model, bool input, uint32_t index,
                      uint32_t *size);
+  int checkDspmSize (const Model *model);
 
   int run (npu_input_opmode opmode, const Model *model,
            const input_buffers *input, output_buffers *output = nullptr,
index 0e9f331..35797c8 100644 (file)
@@ -101,7 +101,7 @@ sanity_violation:
 /** @brief constructor of npubinfmt v2 */
 Metadata_v2::Metadata_v2 (npubin_meta *meta) : Metadata (meta) {}
 
-/** @brief create npubinfmt v1 instance with sanity check */
+/** @brief create npubinfmt v2 instance with sanity check */
 Metadata_v2 *
 Metadata_v2::createInstance (npubin_meta *meta) {
   Metadata_v2 *metadata = new Metadata_v2 (meta);
@@ -199,7 +199,7 @@ Metadata_v2::getOutputTensorSize (uint32_t idx, data_layout layout) const {
 /** @brief constructor of npubinfmt v3 */
 Metadata_v3::Metadata_v3 (npubin_meta *meta) : Metadata (meta) {}
 
-/** @brief create npubinfmt v1 instance with sanity check */
+/** @brief create npubinfmt v3 instance with sanity check */
 Metadata_v3 *
 Metadata_v3::createInstance (npubin_meta *meta) {
   Metadata_v3 *metadata = new Metadata_v3 (meta);
@@ -505,6 +505,16 @@ Model::getOutputTensorSize (uint32_t idx) const {
   return meta_->getOutputTensorSize (idx, layout);
 }
 
+uint32_t
+Model::getDspmSize () const {
+  if (meta_.get () == nullptr) {
+    logerr (TAG, "Invalid metadata\n");
+    return 0;
+  }
+
+  return meta_->getDspmSize ();
+}
+
 /**
  * @brief get the data info of input tensor
  * @param[in] idx input tensor index
index 3acb677..6a3d023 100644 (file)
@@ -106,6 +106,8 @@ class Metadata {
   virtual uint32_t getOutputEmodY (uint32_t idx) const { return 0; }
   virtual uint32_t getOutputEmodZ (uint32_t idx) const { return 0; }
 
+  virtual uint32_t getDspmSize () const { return 0; }
+
   uint64_t getSize () const { return meta_->size; }
   uint64_t getProgramSize () const { return meta_->program_size; }
   uint64_t getWeightSize () const { return meta_->weight_size; }
@@ -348,6 +350,8 @@ class Metadata_v3 : public Metadata {
     return meta_->output_seg_off[idx];
   }
 
+  uint32_t getDspmSize () const override { return meta_->dspm_size; }
+
   data_layout getInputSegmentLayout (uint32_t idx) const override {
     return meta_->input_seg_layout[idx];
   }
@@ -391,6 +395,8 @@ class Model : public HWmem {
   uint32_t getInputTensorSize (uint32_t idx) const;
   uint32_t getOutputTensorSize (uint32_t idx) const;
 
+  uint32_t getDspmSize () const;
+
   npuConstraint getConstraint () const { return constraint_; }
 
   const tensor_data_info *getInputDataInfo (uint32_t idx) const;
index e737ccb..141ce43 100644 (file)
@@ -202,6 +202,7 @@ class TrinityEmulAPI : public DriverAPI {
   int open ();
   int checkSanity ();
   int getNextRequest (int32_t *req_id) const;
+  int getDspmSize (uint32_t *dspm) const;
 
   device_state_t isReady () const;
 
index f6404e6..8f65f33 100644 (file)
@@ -393,6 +393,19 @@ TrinityEmulAPI::getNextRequest (int32_t *req_id) const {
   return 0;
 }
 
+int
+TrinityEmulAPI::getDspmSize (uint32_t *dspm) const {
+  if (dspm == nullptr) {
+    logerr (TAG, "Invalid argument\n");
+    return -EINVAL;
+  }
+
+  /* unlimited size */
+  *dspm = UINT32_MAX;
+
+  return 0;
+}
+
 /**
  * @brief get number of available devices. should be enough
  * @return number of available devices.