[Cuse/Fix] Add ENABLE_CUSE macro instead of variable
authorDongju Chae <dongju.chae@samsung.com>
Fri, 24 Sep 2021 06:35:23 +0000 (15:35 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Mon, 27 Sep 2021 01:24:41 +0000 (10:24 +0900)
This patch explicitly adds ENABLE_CUSE macro rather than
using an internal variable.

Note that in case of .NET app running on the Tizen emulator,
cuse context's pid is not the calling process. So, the pid
info is shared via a file. But, this may not have any sync issue
because an emulator may not support concurrent executions.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
meson.build
meson_options.txt
packaging/npu-engine.spec
src/core/npu/NPUdrvAPI.h
src/core/npu/NPUdrvAPI_triv2.cc
utils/trinity_cuse/trinity-cuse.cc

index 7f77c34..b69b9cf 100644 (file)
@@ -100,6 +100,10 @@ if get_option('enable_npu_emul')
   add_project_arguments('-DENABLE_EMUL', language: ['c', 'cpp'])
 endif
 
+if get_option('enable_npu_cuse')
+  add_project_arguments('-DENABLE_CUSE', language: ['c', 'cpp'])
+endif
+
 if sysroot.startswith('/')
   sysroot_inc_cflags_template = '-I@0@/usr/include@1@'
   sysroot_inc = sysroot_inc_cflags_template.format(sysroot, '')
index 1ac4f9c..62acb8d 100644 (file)
@@ -8,6 +8,7 @@ option('log_level', type : 'string', value : '2')
 option('mute_stdout', type : 'boolean', value : false)
 option('target_platform', type : 'combo', choices : ['debian', 'tizen', 'fpga'], value : 'debian')
 option('enable_npu_emul', type : 'boolean', value : false)
+option('enable_npu_cuse', type : 'boolean', value : false)
 option('enable_data_manip', type : 'boolean', value : false)
 option('enable_buffering', type : 'boolean', value : false)
 option('enable_plugin_npumgr', type : 'boolean', value : false)
index ab42c3a..7edc286 100644 (file)
@@ -29,10 +29,6 @@ BuildRequires:       pkgconfig(libdrm)
 BuildRequires: pkgconfig(tinyxml2)
 BuildRequires: pkgconfig(dlog)
 
-%if 0%{?npu_cuse}
-BuildRequires: libmrpsim-devel
-%endif
-
 %if 0%{?npu_emul}
 BuildRequires: libmrpsim-devel
 %define enable_npu_emul -Denable_npu_emul=true
@@ -40,6 +36,13 @@ BuildRequires:       libmrpsim-devel
 %define enable_npu_emul -Denable_npu_emul=false
 %endif
 
+%if 0%{?npu_cuse}
+BuildRequires: libmrpsim-devel
+%define enable_npu_cuse -Denable_npu_cuse=true
+%else
+%define enable_npu_cuse -Denable_npu_cuse=false
+%endif
+
 %if 0%{?npumgr_plugin}
 BuildRequires: glib2-devel
 %define enable_plugin_npumgr -Denable_plugin_npumgr=true
@@ -69,7 +72,7 @@ meson --buildtype=plain --bindir=%{neexampledir} --prefix=%{_prefix} \
       --libdir=%{_libdir} --includedir=%{_includedir} \
       --datadir=%{_datadir} --sysconfdir=%{_sysconfdir} \
       -Dtarget_platform=tizen -Denable_data_manip=true \
-      %{enable_npu_emul} %{enable_plugin_npumgr} %{enable_plugin_nns} \
+      %{enable_npu_emul} %{enable_npu_cuse} %{enable_plugin_npumgr} %{enable_plugin_nns} \
       build
 ninja -C build %{?_smp_mflags}
 
index 31171e8..632ee9b 100644 (file)
@@ -115,7 +115,9 @@ class DriverAPI {
   static uint32_t api_level_; /**< Trinity API level */
 };
 
+#ifdef ENABLE_CUSE
 class CuseElement;
+#endif
 
 /** @brief Driver APIs for TRIV2 */
 class TrinityVision2API : public DriverAPI {
@@ -162,9 +164,9 @@ class TrinityVision2API : public DriverAPI {
   static const std::string dev_node_base;
   static std::bitset<CHAR_BIT> dev_bitset;
 
+#ifdef ENABLE_CUSE
   static ThreadSafeMap<int, CuseElement> cuse_map;
-
-  bool is_cuse_;
+#endif
 
   std::fstream dev_ios_;
 };
index 9d4780c..08939bd 100644 (file)
@@ -42,6 +42,7 @@ constexpr size_t default_buf_size = (256 * PAGE_SIZE);
 const std::string TrinityVision2API::dev_node_base = "triv2";
 std::bitset<CHAR_BIT> TrinityVision2API::dev_bitset = 0;
 
+#ifdef ENABLE_CUSE
 /** @brief Cuse-hwmem element */
 class CuseElement {
  public:
@@ -64,12 +65,13 @@ class CuseElement {
 };
 
 ThreadSafeMap<int, CuseElement> TrinityVision2API::cuse_map;
+#endif
 
 /**
  * @brief constructor of the API instance for Trinity Vision driver
  * @param[in] dev_id device id
  */
-TrinityVision2API::TrinityVision2API (int dev_id) : DriverAPI (dev_id), is_cuse_ (false) {
+TrinityVision2API::TrinityVision2API (int dev_id) : DriverAPI (dev_id) {
   int num_devs;
 
   if (dev_id > max_num_devs) {
@@ -108,6 +110,12 @@ TrinityVision2API::open () {
     return -ENODEV;
   }
 
+#ifdef ENABLE_CUSE
+  std::ofstream ofs ("/tmp/npu-engine-pid.txt");
+  ofs << getpid ();
+  ofs.close ();
+#endif
+
   path = "/dev/" + TrinityVision2API::dev_node_base + "-" + std::to_string (dev_id_);
   fd = ::open (path.c_str (), O_RDWR);
   if (fd < 0) {
@@ -131,10 +139,6 @@ TrinityVision2API::checkSanity () {
     return -ENODEV;
   }
 
-  /* Check if this device is using a cuse-based driver */
-  if (type == TRINITY_DEV_VISION2_CUSE)
-    this->is_cuse_ = true;
-
   min_ver &= ~TRINITY_MASK_DEV;
   /* Check if the major version numbers are same */
   if ((lib_ver & TRINITY_MASK_MAJOR_VER) != (min_ver & TRINITY_MASK_MAJOR_VER)) {
@@ -248,9 +252,7 @@ TrinityVision2API::alloc (size_t size, bool contiguous) const {
   if (ret < 0)
     IOCTL_RETURN_ERRNO (TRINITY_IOCTL_HWMEM_ALLOC);
 
-  if (!is_cuse_)
-    return ret;
-
+#ifdef ENABLE_CUSE
   CuseElement *elem;
   std::string shm_name;
   int dbuf_fd = ret;
@@ -277,6 +279,7 @@ TrinityVision2API::alloc (size_t size, bool contiguous) const {
     delete elem;
     return -EINVAL;
   }
+#endif
 
   return ret;
 }
@@ -299,18 +302,18 @@ TrinityVision2API::dealloc (int dmabuf, bool contiguous) const {
 
   hwmem.type = contiguous ? TRINITY_HWMEM_DMA_CONT : TRINITY_HWMEM_DMA_IOMMU;
 
+#ifdef ENABLE_CUSE
   /* translate dmabuf FDs to cuse-compatible ones */
-  if (is_cuse_) {
-    CuseElement *elem = cuse_map.find (dmabuf);
-    if (elem == nullptr)
-      return -ENOENT;
+  CuseElement *elem = cuse_map.find (dmabuf);
+  if (elem == nullptr)
+    return -ENOENT;
 
-    hwmem.dbuf_fd = elem->getDbufFD ();
+  hwmem.dbuf_fd = elem->getDbufFD ();
 
-    cuse_map.remove (dmabuf);
-  } else {
-    hwmem.dbuf_fd = dmabuf;
-  }
+  cuse_map.remove (dmabuf);
+#else
+  hwmem.dbuf_fd = dmabuf;
+#endif
 
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_HWMEM_DEALLOC, &hwmem);
   if (ret < 0)
@@ -436,30 +439,30 @@ TrinityVision2API::registerModel (model_config_t *model_config, uint64_t npu_ver
     }
   } /** else: don't care */
 
+#ifdef ENABLE_CUSE
   /* translate dmabuf FDs to cuse-compatible ones */
   int dbuf_fd = model_config->dbuf_fd;
   int metadata_dbuf_fd = model_config->metadata_dbuf_fd;
 
-  if (is_cuse_) {
-    CuseElement *prog = cuse_map.find (dbuf_fd);
-    if (prog == nullptr)
-      return -ENOENT;
+  CuseElement *prog = cuse_map.find (dbuf_fd);
+  if (prog == nullptr)
+    return -ENOENT;
 
-    CuseElement *meta = cuse_map.find (metadata_dbuf_fd);
-    if (meta == nullptr)
-      return -ENOENT;
+  CuseElement *meta = cuse_map.find (metadata_dbuf_fd);
+  if (meta == nullptr)
+    return -ENOENT;
 
-    model_config->dbuf_fd = prog->getDbufFD ();
-    model_config->metadata_dbuf_fd = meta->getDbufFD ();
-  }
+  model_config->dbuf_fd = prog->getDbufFD ();
+  model_config->metadata_dbuf_fd = meta->getDbufFD ();
+#endif
 
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_REGISTER_MODEL, model_config);
 
+#ifdef ENABLE_CUSE
   /* rollback FDs to prevent any side-effects */
-  if (is_cuse_) {
-    model_config->dbuf_fd = dbuf_fd;
-    model_config->metadata_dbuf_fd = metadata_dbuf_fd;
-  }
+  model_config->dbuf_fd = dbuf_fd;
+  model_config->metadata_dbuf_fd = metadata_dbuf_fd;
+#endif
 
   if (ret < 0)
     IOCTL_RETURN_ERRNO (TRINITY_IOCTL_REGISTER_MODEL);
@@ -503,39 +506,39 @@ TrinityVision2API::runInput (input_config_t *input_config) const {
     return -EINVAL;
   }
 
+#ifdef ENABLE_CUSE
   /* translate dmabuf FDs to cuse-compatible ones */
-  if (is_cuse_) {
-    CuseElement *elem;
-    void *segt;
+  CuseElement *elem;
+  void *segt;
 
-    elem = cuse_map.find (input_config->dbuf_fd);
-    if (elem == nullptr)
-      return -ENOENT;
+  elem = cuse_map.find (input_config->dbuf_fd);
+  if (elem == nullptr)
+    return -ENOENT;
+
+  segt = this->mmap (input_config->dbuf_fd, PAGE_SIZE);
+  if (segt == nullptr)
+    return -EINVAL;
 
-    segt = this->mmap (input_config->dbuf_fd, PAGE_SIZE);
-    if (segt == nullptr)
+  input_config->dbuf_fd = elem->getDbufFD ();
+  for (uint32_t i = 0; i < input_config->num_segments; i++) {
+    int dbuf_fd = ((int *) segt)[i];
+    if (dbuf_fd < 0) {
+      this->munmap (segt, PAGE_SIZE);
       return -EINVAL;
+    }
 
-    input_config->dbuf_fd = elem->getDbufFD ();
-    for (uint32_t i = 0; i < input_config->num_segments; i++) {
-      int dbuf_fd = ((int *) segt)[i];
-      if (dbuf_fd < 0) {
-        this->munmap (segt, PAGE_SIZE);
-        return -EINVAL;
-      }
-
-      elem = cuse_map.find (dbuf_fd);
-      if (elem == nullptr) {
-        this->munmap (segt, PAGE_SIZE);
-        return -ENOENT;
-      }
-
-      ((int *) segt)[i] = elem->getDbufFD ();
+    elem = cuse_map.find (dbuf_fd);
+    if (elem == nullptr) {
+      this->munmap (segt, PAGE_SIZE);
+      return -ENOENT;
     }
 
-    this->munmap (segt, PAGE_SIZE);
+    ((int *) segt)[i] = elem->getDbufFD ();
   }
 
+  this->munmap (segt, PAGE_SIZE);
+#endif
+
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_RUN_INPUT, input_config);
   if (ret < 0)
     IOCTL_RETURN_ERRNO (TRINITY_IOCTL_RUN_INPUT);
@@ -647,11 +650,11 @@ TrinityVision2API::getProfile (int req_id, npu_profile *profile) const {
   profile->num_layers = meta.total_ops;
   profile->layers = new npu_profile_layer[profile->num_layers];
 
-  if (is_cuse_) {
-    std::string prof_path = Conf::getInstance ().getPrefixProfile ();
-    prof_path += "/ne_profile." + std::to_string (req_id) + ".rec";
-    profile->prof_path = strdup (prof_path.c_str ());
-  }
+#ifdef ENABLE_CUSE
+  std::string prof_path = Conf::getInstance ().getPrefixProfile ();
+  prof_path += "/ne_profile." + std::to_string (req_id) + ".rec";
+  profile->prof_path = strdup (prof_path.c_str ());
+#endif
 
   buff.req_id = meta.req_id;
 
index 5a23b6e..45663f9 100644 (file)
@@ -14,6 +14,7 @@
 #define FUSE_USE_VERSION 29
 
 #include <iostream>
+#include <fstream>
 
 #include <cuse_lowlevel.h>
 #include <string.h>
@@ -46,6 +47,18 @@ find_ioctl_vtable (const std::string &dev_name) {
   return false;
 }
 
+int
+get_app_id (const fuse_req_t &req) {
+  int app_id = fuse_req_ctx (req)->pid;
+
+  /* FIXME: in .NET app, the ctx's pid is not the calling DLL process */
+  std::ifstream ifs ("/tmp/npu-engine-pid.txt");
+  if (ifs.is_open ())
+    ifs >> app_id;
+
+  return app_id;
+}
+
 /**
  * @brief impl. of .open ()
  */
@@ -54,7 +67,7 @@ trinity_cuse_open (fuse_req_t req, struct fuse_file_info *fi) {
   trinity_cuse_context *ctx;
 
   ctx = new trinity_cuse_context;
-  ctx->app_id = fuse_req_ctx (req)->pid;
+  ctx->app_id = get_app_id (req);
   ctx->prefix_share = Conf::getInstance ().getPrefixShare ();
   ctx->prefix_profile = Conf::getInstance ().getPrefixProfile ();