[Model/Tops] Check the TOPS which TRIV2 device supports
authorDongju Chae <dongju.chae@samsung.com>
Mon, 9 Nov 2020 09:08:46 +0000 (18:08 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Thu, 12 Nov 2020 02:37:39 +0000 (11:37 +0900)
This patch adds the routine to check the TOPS device supports.
It compares the device's TOPS and model-described TOPS.
For backward-compatability, if TOPS is zero, it's regarded as "don't care"

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

index ae3da99..24977fe 100644 (file)
@@ -1508,7 +1508,7 @@ TrinityVision2::setModel (const generic_buffer *model_buf, Model ** model_ptr)
     config.metadata_extra_addr = NPUBIN_META_SIZE;
     config.metadata_extra_size = model->getMetadata()->getMetaExtraSize ();
 
-    status = api_->registerModel (&config);
+    status = api_->registerModel (&config, model->getMetadata()->getNPUVersion());
     if (status != 0)
       goto delete_exit;
 
index 9b2411e..0f72d88 100644 (file)
@@ -95,6 +95,7 @@ class Metadata {
     uint32_t getMetaExtraSize () const { return NPUBIN_META_EXTRA_SIZE(meta_->magiccode); }
 
     int getVersion () const { return version_; }
+    uint64_t getNPUVersion () const { return meta_->npu_version; }
 
   protected:
     Metadata (npubin_meta *meta);
index 0f2d939..7cce3ea 100644 (file)
@@ -96,7 +96,8 @@ class DriverAPI {
     virtual int stop_target (int id) const { return -EPERM; }
 
     /** @brief register model config to the driver */
-    virtual int registerModel (model_config_t *model) const { return -EPERM; }
+    virtual int registerModel (model_config_t *model,
+        uint64_t npu_version = 0) const { return -EPERM; }
     virtual int deregisterModel (unsigned long long id) const { return -EPERM; }
 
 #if defined(ENABLE_FPGA_WORKAROUND)
@@ -140,7 +141,7 @@ class TrinityVisionAPI : public DriverAPI {
     int runInput (input_config_t *input) const;
     int stop () const;
 
-    int registerModel (model_config_t *model) const;
+    int registerModel (model_config_t *model, uint64_t npu_version) const;
     int deregisterModel (unsigned long long id) const;
 
   private:
@@ -175,7 +176,7 @@ class TrinityVision2API : public DriverAPI {
     int stop () const;
     int stop_target (int id) const;
 
-    int registerModel (model_config_t *model) const;
+    int registerModel (model_config_t *model, uint64_t npu_version) const;
     int deregisterModel (unsigned long long id) const;
 
 #if defined(ENABLE_FPGA_WORKAROUND)
@@ -233,7 +234,7 @@ class TrinityEmulAPI : public DriverAPI {
     int stop () const;
     int stop_target (int id) const;
 
-    int registerModel (model_config_t *model) const;
+    int registerModel (model_config_t *model, uint64_t npu_version) const;
     int deregisterModel (unsigned long long id) const;
 
     int getProfile (int task_id, void **profile_buf,
index b3532be..d203c5b 100644 (file)
@@ -318,10 +318,12 @@ TrinityEmulAPI::munmap (void *addr, size_t size) const
 /**
  * @brief register model config to the driver
  * @param[in] model_config model configuration to be registered
+ * @param[in] npu_version npu version described in the metadata
  * @return 0 if no error. otherwise a negative errno
  */
 int
-TrinityEmulAPI::registerModel (model_config_t *model_config) const
+TrinityEmulAPI::registerModel (model_config_t *model_config,
+    uint64_t npu_version) const
 {
   static std::atomic<uint64_t> global_internal_id (0);
 
index d0e8930..47ebf5d 100644 (file)
@@ -272,10 +272,12 @@ TrinityVisionAPI::munmap (void *addr, size_t size) const
 /**
  * @brief register model config to the driver
  * @param[in] model_config model configuration to be registered
+ * @param[in] npu_version npu version described in the metadata
  * @return 0 if no error. otherwise a negative errno
  */
 int
-TrinityVisionAPI::registerModel (model_config_t *model_config) const
+TrinityVisionAPI::registerModel (model_config_t *model_config,
+    uint64_t npu_version) const
 {
   int ret;
 
index a3cb5e0..ab18bbf 100644 (file)
@@ -9,6 +9,7 @@
 #include <iostream>
 
 #include "NPUdrvAPI.h"
+#include <npubinfmt.h>
 
 constexpr int max_num_devs = ((1<<CHAR_BIT) - 1);
 constexpr size_t max_buf_size = (256 * PAGE_SIZE);
@@ -271,16 +272,34 @@ TrinityVision2API::munmap (void *addr, size_t size) const
 /**
  * @brief register model config to the driver
  * @param[in] model_config model configuration to be registered
+ * @param[in] npu_version npu version described in the metadata
  * @return 0 if no error. otherwise a negative errno
  */
 int
-TrinityVision2API::registerModel (model_config_t *model_config) const
+TrinityVision2API::registerModel (model_config_t *model_config,
+    uint64_t npu_version) const
 {
+  uint32_t model_tops;
+  uint32_t device_tops;
   int ret;
 
   if (!this->initialized())
     return -EPERM;
 
+  if (NPU_VERSION_MAJOR(npu_version) != 2)
+    return -EINVAL;
+
+  model_tops = NPU_VERSION_TOPS(npu_version);
+  if (model_tops != 0) {
+    ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_GET_TOPS,
+        &device_tops);
+    if (ret != 0)
+      return -errno;
+
+    if (model_tops != device_tops)
+      return -EINVAL;
+  } /** else: don't care */
+
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_REGISTER_MODEL,
       model_config);
 
index 8c1e4de..905e55d 100644 (file)
@@ -23,6 +23,9 @@
 
 #include "ne_unittest_utils.h"
 
+/** 8-TOPS TRIV2 v2.2.1 */
+#define TEST_NPU_VERSION (0x08010202)
+
 /**
  * @brief check getNumDevices()
  */
@@ -567,7 +570,7 @@ TEST (ne_core_npu_test, run_inference_triv2)
   model.program_size = 0;
   model.metadata_dbuf_fd = model_dmabuf; /* dummy */
 
-  EXPECT_EQ (api->registerModel (&model), 0);
+  EXPECT_EQ (api->registerModel (&model, TEST_NPU_VERSION), 0);
 
   /** allocate input data */
   buffer_dmabuf = api->alloc (size);
@@ -624,7 +627,7 @@ TEST (ne_core_npu_test, run_inference_async0_triv2)
   model.program_size = 0;
   model.metadata_dbuf_fd = model_dmabuf; /* dummy */
 
-  EXPECT_EQ (api->registerModel (&model), 0);
+  EXPECT_EQ (api->registerModel (&model, TEST_NPU_VERSION), 0);
 
   int *buf = nullptr;
   int buffer_dmabuf = -1;
@@ -698,7 +701,7 @@ TEST (ne_core_npu_test, run_inference_async1_triv2)
         model.program_size = 0;
         model.metadata_dbuf_fd = ret; /* dummy */
 
-        ret = api->registerModel (&model);
+        ret = api->registerModel (&model, TEST_NPU_VERSION);
         if (ret < 0) {
           model.dbuf_fd = -1;
         }
@@ -763,7 +766,7 @@ TEST (ne_core_npu_test, run_inference_triv2_n)
   model.program_offset_addr = 0;
   model.program_size = 0;
 
-  EXPECT_EQ (api->registerModel (&model), 0);
+  EXPECT_EQ (api->registerModel (&model, TEST_NPU_VERSION), 0);
 
   /** allocate input data */
   buffer_dmabuf = api->alloc (size);