[API/Profile] Implement getNPU_profile_opt()
authorDongju Chae <dongju.chae@samsung.com>
Tue, 4 May 2021 10:00:56 +0000 (19:00 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Thu, 6 May 2021 06:24:51 +0000 (15:24 +0900)
This patch implements `getNPU_profile_opt()`, which is a variant of
the existing `getNPU_profile()`.

It requires an extra argument called `npu_profile_opt`.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
include/common/typedef.h
include/host/libnpuhost.h
src/core/ne-handler.cc
src/core/ne-handler.h
src/core/ne-profiler.cc
src/core/ne-profiler.h
src/host/ne-host.cc

index 358adb5..55d0947 100644 (file)
@@ -374,4 +374,16 @@ typedef struct {
   npu_profile_layer *layers;
 } npu_profile;
 
+typedef enum {
+  PROFILE_LEVEL_EXT_META = 0, /**< Depends on extended metadata */
+  PROFILE_LEVEL_VISA,         /**< vISA-level profiling */
+  PROFILE_LEVEL_LAYER, /**< Layer-level profiling (requires the extended meta) */
+  PROFILE_LEVEL_MAX
+} profile_level_type;
+
+typedef struct {
+  profile_level_type level;
+  /* TODO: Add more options if needed */
+} npu_profile_opt;
+
 #endif /* NPU_TYPEDEF_H__ */
index 4c96652..27b7eee 100644 (file)
@@ -378,11 +378,27 @@ int cleanNPU_genericBuffers (npudev_h dev, generic_buffers *buffers);
  * @param[in] req_id Identifier for each inference (obtained by runNPU_*)
  * @param[out] profile Profile instance
  * @return 0 if no error, otherwise a negative errno.
- * @note Internal data of npu_profile is valid until putNPU_profile is called
+ * @note This is one-shot API. Don't call multiple times for the same infernece.
+ * @note Internal data of npu_profile is valid until putNPU_profile is called.
+ * @note The existence of model's extended metadata decides its profiling level.
+ * (e.g., if extended metadata does not exist, it performs vISA-level profiling.)
  */
 int getNPU_profile (npudev_h dev, int req_id, npu_profile *profile);
 
 /**
+ * @brief Get the profile information from NPU with optional requirements
+ * @param[in] dev NPU device handle
+ * @param[in] req_id Identifier for each inference (obtained by runNPU_*)
+ * @param[in] opt Profile options
+ * @param[out] profile Profile instance
+ * @return 0 if no error, otherwise a negative errno.
+ * @note This is one-shot API. Don't call multiple times for the same infernece.
+ * @note Internal data of npu_profile is valid until putNPU_profile is called.
+ */
+int getNPU_profile_opt (npudev_h dev, int req_id, const npu_profile_opt opt,
+                        npu_profile *profile);
+
+/**
  * @brief Free the profile instance obtained by getNPU_profile().
  * @param[in] profile Profile instance
  */
index 8ee9d86..2d0c909 100644 (file)
@@ -118,11 +118,13 @@ HostHandler::unregisterModels () {
 /**
  * @brief Get the profile information from NPU
  * @param[in] req_id The identifier for each inference
+ * @param[in] opt Profile options
  * @param[out] profile The profile instance
  * @return 0 if no error, otherwise a negative errno.
  */
 int
-HostHandler::getProfile (int req_id, npu_profile *profile) {
+HostHandler::getProfile (int req_id, const npu_profile_opt &opt,
+                         npu_profile *profile) {
   if (req_id < 0 || profile == nullptr) {
     logerr (TAG, "Invalid parameter provided\n");
     return -EINVAL;
@@ -132,7 +134,7 @@ HostHandler::getProfile (int req_id, npu_profile *profile) {
   profile->layers = nullptr;
   profile->prof_path = nullptr;
 
-  return profiler_->getProfile (req_id, profile);
+  return profiler_->getProfile (req_id, opt, profile);
 }
 
 /**
index 46021f7..a5736b2 100644 (file)
@@ -36,7 +36,7 @@ class HostHandler {
   int unregisterModel (uint32_t modelid);
   int unregisterModels ();
 
-  int getProfile (int req_id, npu_profile *profile);
+  int getProfile (int req_id, const npu_profile_opt &opt, npu_profile *profile);
   int getAPILevel (uint32_t *level);
   int getTops (uint32_t *tops);
   int getDspmSize (uint32_t *dspm);
index 88e9174..fa6bc65 100644 (file)
@@ -26,7 +26,8 @@ ModelProfiler::appendRequest (int req_id, const Model *model) {
 }
 
 int
-ModelProfiler::getProfile (int req_id, npu_profile *profile) {
+ModelProfiler::getProfile (int req_id, const npu_profile_opt &opt,
+                           npu_profile *profile) {
   ProfileData *data = profile_map_.find (req_id);
   if (data == nullptr)
     return -ENOENT;
@@ -39,12 +40,16 @@ ModelProfiler::getProfile (int req_id, npu_profile *profile) {
   if (status != 0)
     return status;
 
-  HWmem *extended = model->getExtendedMetadata ();
-  if (extended != nullptr)
-    manipulateProfile (extended, profile);
+  if (opt.level == PROFILE_LEVEL_EXT_META || opt.level == PROFILE_LEVEL_LAYER) {
+    HWmem *extended = model->getExtendedMetadata ();
+    if (extended != nullptr)
+      manipulateProfile (extended, profile);
+    else if (opt.level == PROFILE_LEVEL_LAYER)
+      status = -EINVAL;
+  }
 
   profile_map_.remove (req_id);
-  return 0;
+  return status;
 }
 
 void
index 61a26ba..c7581dd 100644 (file)
@@ -35,7 +35,7 @@ class ModelProfiler {
   ~ModelProfiler ();
 
   int appendRequest (int req_id, const Model *model);
-  int getProfile (int req_id, npu_profile *profile);
+  int getProfile (int req_id, const npu_profile_opt &opt, npu_profile *profile);
 
   void manipulateProfile (HWmem *extended, npu_profile *profile);
 
index be74d58..533eb33 100644 (file)
@@ -179,16 +179,35 @@ getNPU_dspmSize (npudev_h dev, uint32_t *dspm) {
 
 /**
  * @brief Get the profile information from NPU
- * @param[in] dev The NPU device handle
- * @param[in] task_id The identifier for each inference
- * @param[out] profile The profile instance
+ * @param[in] dev NPU device handle
+ * @param[in] req_id Identifier for each inference (obtained by runNPU_*)
+ * @param[out] profile Profile instance
+ * @return 0 if no error, otherwise a negative errno.
+ * @note Internal data of npu_profile is valid until putNPU_profile is called
+ * @note The profiling level depends on the target model's extended metadata.
+ */
+int
+getNPU_profile (npudev_h dev, int req_id, npu_profile *profile) {
+  const npu_profile_opt opt = {.level = PROFILE_LEVEL_EXT_META};
+
+  return getNPU_profile_opt (dev, req_id, opt, profile);
+}
+
+/**
+ * @brief Get the profile information from NPU with optional requirements
+ * @param[in] dev NPU device handle
+ * @param[in] req_id Identifier for each inference (obtained by runNPU_*)
+ * @param[in] opt Profile options
+ * @param[out] profile Profile instance
  * @return 0 if no error, otherwise a negative errno.
+ * @note Internal data of npu_profile is valid until putNPU_profile is called
  */
 int
-getNPU_profile (npudev_h dev, int task_id, npu_profile *profile) {
+getNPU_profile_opt (npudev_h dev, int req_id, const npu_profile_opt opt,
+                    npu_profile *profile) {
   INIT_HOST_HANDLER (host_handler, dev);
 
-  return host_handler->getProfile (task_id, profile);
+  return host_handler->getProfile (req_id, opt, profile);
 }
 
 /**