[Utils] Prototype of trinity-smi for management and monitoring
authorDongju Chae <dongju.chae@samsung.com>
Fri, 13 Nov 2020 10:39:11 +0000 (19:39 +0900)
committer우상정/On-Device Lab(SR)/Staff Engineer/삼성전자 <sangjung.woo@samsung.com>
Wed, 18 Nov 2020 10:57:29 +0000 (19:57 +0900)
This patch implements the prototype of trinity-smi, which is a
command line util for management and monitoring of trinity devices.

- trinity-smi (Trinity System Management Interface)

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
debian/control
debian/npu-engine-utils.install [new file with mode: 0644]
packaging/npu-engine.spec
utils/meson.build
utils/trinity_smi/meson.build [new file with mode: 0644]
utils/trinity_smi/trinity-smi.cc [new file with mode: 0644]

index e900c56..1f5c629 100644 (file)
@@ -36,6 +36,6 @@ Description: NPU Engine Example Package
 Package: npu-engine-utils
 Architecture: amd64
 Multi-Arch: same
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Depends: npu-engine, ${shlibs:Depends}, ${misc:Depends}
 Description: NPU Engine Utils Package
  This provides utility packages for NPU Engine, including metadata extraction of model files.
diff --git a/debian/npu-engine-utils.install b/debian/npu-engine-utils.install
new file mode 100644 (file)
index 0000000..1def65c
--- /dev/null
@@ -0,0 +1 @@
+/opt/trinity/bin/utils/*
index e332fee..d6040f7 100644 (file)
@@ -77,6 +77,7 @@ Example application package for NPU Engine, including UnitTests and AppTest with
 %{neexampledir}/apptests/*
 
 %package utils
+Requires:      npu-engine = %{version}-%{release}
 Summary:  NPU Engine Example Package
 %description utils
 This probides utility packages for NPU Engine, including metadata extraction of model files.
index d1c5885..510bd58 100644 (file)
@@ -1 +1,2 @@
 subdir('model_inspect')
+subdir('trinity_smi')
diff --git a/utils/trinity_smi/meson.build b/utils/trinity_smi/meson.build
new file mode 100644 (file)
index 0000000..46c5fc4
--- /dev/null
@@ -0,0 +1,8 @@
+utils_model_inspect = executable('trinity-smi',
+  ['trinity-smi.cc'],
+  include_directories: [ne_host_inc, ne_common_inc],
+  link_with : ne_library_shared,
+  install : true,
+  install_rpath : ne_libdir,
+  install_dir : join_paths(ne_bindir, 'utils')
+)
diff --git a/utils/trinity_smi/trinity-smi.cc b/utils/trinity_smi/trinity-smi.cc
new file mode 100644 (file)
index 0000000..b9075fe
--- /dev/null
@@ -0,0 +1,264 @@
+/**
+ * Proprietary
+ * Copyright (C) 2020 Samsung Electronics
+ * Copyright (C) 2020 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file trinity-smi.cc
+ * @date 13 Nov 2020
+ * @brief Utility for mangement and monitoring of trinity devices
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <libnpuhost.h>
+#include <npubinfmt.h>
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <chrono>
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+using namespace std;
+
+/** @brief Class of Trinity SMI (Trinity System Management Interface) */
+class TrinitySMI {
+  public:
+    TrinitySMI (const char *name) {
+      const char * last = strrchr (name, '/');
+      if (last != NULL) {
+        name_ = string (last + 1);
+      } else {
+        name_ = string (name);
+      }
+    }
+    ~TrinitySMI () {}
+
+    uint32_t get_api_level ();
+
+    void append_version ();
+    void append_help ();
+    void append_devices ();
+    void append_processes ();
+
+    void dump ();
+
+  private:
+    string name_;
+    stringstream ss_;
+};
+
+/** @brief get driver api level from any device */
+uint32_t
+TrinitySMI::get_api_level ()
+{
+  dev_type types[] = {NPUCOND_TRIV_CONN_SOCIP, NPUCOND_TRIV2_CONN_SOCIP};
+  uint32_t level = 0;
+
+  for (auto type : types) {
+    npudev_h dev;
+    int ret;
+
+    ret = getnumNPUdeviceByType (type);
+    if (ret > 0) {
+      ret = getNPUdeviceByType (&dev, type, 0);
+      if (ret != 0)
+        continue;
+
+      ret = getNPU_driverAPILevel (dev, &level);
+      putNPUdevice (dev);
+
+      if (ret == 0)
+        return level;
+      else
+        level = 0;
+    }
+  }
+
+  return level;
+}
+
+/** @brief show the version of npu-engine and driver */
+void
+TrinitySMI::append_version ()
+{
+  auto now = chrono::system_clock::now ();
+  time_t now_time = chrono::system_clock::to_time_t (now);
+  string smi_ver, lib_ver;
+
+  smi_ver += to_string (VER_NE_MAJOR) + ".";
+  smi_ver += to_string (VER_NE_MINOR) + ".";
+  smi_ver += to_string (VER_NE_EXTRA);
+
+  uint32_t major, minor, extra;
+
+  getVersion (&major, &minor, &extra);
+  lib_ver += to_string (major) + ".";
+  lib_ver += to_string (minor) + ".";
+  lib_ver += to_string (extra);
+
+  uint32_t api_level = get_api_level ();
+
+  ss_ << std::ctime (&now_time);
+  ss_ << "+--------------------------------------------------------+\n";
+  ss_ << "| TRINITY-SMI: " << smi_ver;
+  ss_ << "  NPU-ENGINE: " << lib_ver;
+  ss_ << "  DRIVER-API: ";
+  ss_ << setw (3);
+#ifdef ENABLE_EMUL
+  ss_ << "SIM";
+#else
+  ss_ << (api_level == 0 ? "INV" : to_string (api_level));
+#endif
+  ss_ << " |\n";
+  ss_ << "+--------------------------------------------------------+\n";
+}
+
+/** @brief show the list of trinity devices */
+void
+TrinitySMI::append_devices ()
+{
+  dev_type types[] = {
+    NPUCOND_TRIV_CONN_SOCIP,
+    NPUCOND_TRIV2_CONN_SOCIP,
+    NPUCOND_TRIA_CONN_SOCIP
+  };
+
+  ss_ << "+--------------------------------------------------------+\n";
+  ss_ << "| CLASS |  DEVICE NODE  | TOPS |  STATUS  |  # REQUESTS  |\n";
+  ss_ << "|========================================================|\n";
+
+  uint32_t count = 0;
+  for (auto type : types) {
+    string cls, node;
+
+    if (type & DEVICETYPE_TRIV) {
+      cls = string ("TRIV");
+      node = string ("/dev/triv");
+    } else if (type & DEVICETYPE_TRIV2) {
+      cls = string ("TRIV2");
+      node = string ("/dev/triv2");
+    } else if (type & DEVICETYPE_TRIA) {
+      cls = string ("TRIA");
+      node = string ("/dev/tria");
+    } else {
+      break;
+    }
+
+    for (int i = 0; i < getnumNPUdeviceByType (type); i++) {
+      string node_str = node + "-" + to_string (i);
+      string tops_str, status_str, num_str;
+
+#ifdef ENABLE_EMUL
+      tops_str = string ("emul");
+      status_str = string ("idle");
+      num_str = to_string (0);
+#else
+      uint32_t tops;
+      npudev_h dev;
+      npu_status status;
+      uint32_t num;
+
+      if (getNPUdeviceByType (&dev, type, i) != 0)
+        break;
+
+      if (getNPU_tops (dev, &tops) != 0) {
+        putNPUdevice (dev);
+        break;
+      }
+
+      if (getNPU_deviceStatus (dev, &status, &num) != 0) {
+        putNPUdevice (dev);
+        break;
+      }
+
+      tops_str = to_string (tops);
+      num_str = to_string (num);
+
+      if (status == NPU_READY)
+        status_str = string ("ready");
+      else if (status == NPU_IDLE)
+        status_str = string ("idle");
+      else
+        status_str = string ("error");
+
+      putNPUdevice (dev);
+#endif
+
+      ss_ << "| " << right << setw (5) << cls << " ";
+      ss_ << "| " << right << setw (13) << node_str << " ";
+      ss_ << "| " << right << setw (4) << tops_str << " ";
+      ss_ << "| " << right << setw (8) << status_str << " ";
+      ss_ << "| " << right << setw (12) << num_str << " |\n";
+      count++;
+    }
+  }
+  if (count == 0)
+    ss_ << "| " << left << setw (55) << "No available device detected" << "|\n";
+  ss_ << "+--------------------------------------------------------+\n";
+}
+
+/** @brief show the list of running processes */
+void
+TrinitySMI::append_processes ()
+{
+  /** TODO */
+  ss_ << "+--------------------------------------------------------+\n";
+  ss_ << "| " << left << setw (55) << "No running processes found" << "|\n";
+  ss_ << "+--------------------------------------------------------+\n";
+}
+
+/** @brief show the usage and help messages */
+void
+TrinitySMI::append_help ()
+{
+  ss_ << "\nUsage: " << name_ << " [options]\n";
+  ss_ << "Options:\n";
+  ss_ << "  -d \t\t Show list of trinity devices\n";
+  ss_ << "  -p \t\t Show list of running processes\n";
+  ss_ << "  -h \t\t Show help messages\n";
+}
+
+/** @brief show the appended string to screen */
+void
+TrinitySMI::dump ()
+{
+  cout << ss_.str ();
+}
+
+/** @brief main routine of trinity-smi */
+int main (int argc, char **argv)
+{
+  TrinitySMI smi (argv[0]);
+
+  smi.append_version ();
+
+  if (argc > 1) {
+    int c;
+
+    optind = 0;
+    opterr = 0;
+    while ((c = getopt (argc, argv, "dph")) != -1) {
+      switch (c) {
+        case 'd':
+          smi.append_devices ();
+          break;
+        case 'p':
+          smi.append_processes ();
+          break;
+        case 'h':
+          smi.append_help ();
+          break;
+      }
+    }
+  } else {
+    smi.append_help ();
+  }
+
+  smi.dump ();
+  return 0;
+}