[VD/NPUMGR] Implement the protoype of NPU Manager
authorDongju Chae <dongju.chae@samsung.com>
Fri, 9 Apr 2021 07:56:01 +0000 (16:56 +0900)
committer파리차이카푸르/On-Device Lab(SR)/Engineer/삼성전자 <pk.kapoor@samsung.com>
Tue, 27 Apr 2021 04:05:34 +0000 (13:05 +0900)
This patch implements the prototype of NPU Manager.

Because the VD NPU manager is GDBus-based thread application,
we can simply emulate the NPU manager using GDBus server, client,
and the corresponding test program.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
debian/control
packaging/npu-engine.spec
tests/apptests/meson.build
tests/apptests/npumgr/meson.build [new file with mode: 0644]
tests/apptests/npumgr/npumgr.cc [new file with mode: 0644]
tests/apptests/npumgr/npumgr_api.cc [new file with mode: 0644]
tests/apptests/npumgr/npumgr_api.h [new file with mode: 0644]
tests/apptests/npumgr/npumgr_device.h [new file with mode: 0644]
tests/apptests/npumgr/npumgr_test.cc [new file with mode: 0644]

index e774e50..379863e 100644 (file)
@@ -4,7 +4,7 @@ Priority: optional
 Maintainer: MyungJoo Ham <myungjoo.ham@samsung.com>
 Build-Depends: ninja-build, meson (>=0.50), debhelper (>=9),
  gcc-9 | gcc-8 | gcc-7 | gcc-6 | gcc-5, libgtest-dev, python,
- libiniparser-dev, pkg-config, cmake, libdrm-dev, libfuse-dev,
+ libiniparser-dev, pkg-config, cmake, libdrm-dev, libfuse-dev, libglib2.0-dev,
  linux-fvp-headers, libmrpsim-dev (>=2.3.4), libtinyxml2-dev, libncurses-dev
 Standards-Version: 3.8.2
 Homepage: https://research.samsung.com
index f0c7d25..34f16ba 100644 (file)
@@ -30,6 +30,8 @@ BuildRequires:        pkgconfig(tinyxml2)
 
 BuildRequires:  pkgconfig(dlog)
 
+BuildRequires:  glib2-devel
+
 %if 0%{?npu_emul}
 BuildRequires:  libmrpsim-devel
 %define enable_npu_emul -Denable_npu_emul=true
@@ -62,8 +64,7 @@ DESTDIR=%{buildroot} ninja install -C build %{?_smp_mflags}
 %files
 %manifest npu-engine.manifest
 %defattr(-,root,root,-)
-%{_libdir}/libnpu-engine.so
-%{_libdir}/libnpu-engine.a
+%{_libdir}/*.so
 %{_sysconfdir}/npu-engine.ini
 
 %package devel
@@ -76,6 +77,7 @@ This contains corresponding header files and .pc pkgconfig file.
 %manifest npu-engine.manifest
 %defattr(-,root,root,-)
 %{_includedir}/npu-engine/*.h
+%{_libdir}/*.a
 %{_libdir}/pkgconfig/*.pc
 
 %package example
index 2b6edd5..59ef7d0 100644 (file)
@@ -123,3 +123,5 @@ executable ('apptest_tvn_triv2_preempt',
   install_rpath : ne_libdir,
   install_dir : join_paths(ne_bindir, 'apptests')
 )
+
+subdir('npumgr')
diff --git a/tests/apptests/npumgr/meson.build b/tests/apptests/npumgr/meson.build
new file mode 100644 (file)
index 0000000..38ec772
--- /dev/null
@@ -0,0 +1,34 @@
+# Note that VD NPU Manager is a gdbus-based thread application
+glib_dep = dependency('glib-2.0', required: false)
+giounix_dep = dependency('gio-unix-2.0', required: false)
+if glib_dep.found() and giounix_dep.found()
+  npumgr_deps = [
+    glib_dep,
+    giounix_dep
+  ]
+
+  npumgr_lib = shared_library ('npumgr',
+    'npumgr_api.cc',
+    dependencies: npumgr_deps,
+    build_rpath : ne_libdir,
+    install : true,
+    install_rpath : ne_libdir,
+    install_dir : ne_libdir
+  )
+
+  executable ('apptest_npumgr',
+    'npumgr_test.cc',
+    link_with : npumgr_lib,
+    install : true,
+    install_rpath : ne_libdir,
+    install_dir : join_paths(ne_bindir, 'apptests', 'npumgr')
+  )
+
+  executable ('dummy_npumgr',
+    'npumgr.cc',
+    dependencies: npumgr_deps,
+    install : true,
+    install_rpath : ne_libdir,
+    install_dir : join_paths(ne_bindir, 'apptests', 'npumgr')
+  )
+endif
diff --git a/tests/apptests/npumgr/npumgr.cc b/tests/apptests/npumgr/npumgr.cc
new file mode 100644 (file)
index 0000000..f6d19a7
--- /dev/null
@@ -0,0 +1,184 @@
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr.cc
+ * @date 09 Apr 2021
+ * @brief GDBus-based implementation of VD NPU Manager (dummy)
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <cstdint>
+
+#include <gio/gio.h>
+
+/**
+ * @brief Class for NPU Manager Context
+ */
+class npumgrContext {
+ public:
+  npumgrContext () : device_id_ (-1), priority_ (-1) {}
+
+  /** @brief set device id */
+  void setDeviceID (int device_id) { device_id_ = device_id; }
+  /** @brief set priority */
+  void setPriority (int priority) { priority_ = priority; }
+
+ private:
+  int device_id_;
+  int priority_;
+};
+
+static GDBusNodeInfo *introspection_data = NULL;
+/* Introspection data for the npumgr service (NYI) */
+static const gchar introspection_xml[] =
+    " <node>"
+    "   <interface name='sr.odl.NPUManager.API'>"
+    "     <method name='ContextCreate'>"
+    "       <arg type='i' name='device_id' direction='in'/>"
+    "       <arg type='i' name='priority' direction='in'/>"
+    "       <arg type='t' name='context' direction='out'/>"
+    "     </method>"
+    "     <method name='ContextDestroy'>"
+    "       <arg type='t' name='context' direction='in'/>"
+    "     </method>"
+    "   </interface>"
+    " </node>";
+
+/**
+ * @brief Method callback
+ */
+static void
+handle_method_call (GDBusConnection *connection, const gchar *sender,
+                    const gchar *object_path, const gchar *interface_name,
+                    const gchar *method_name, GVariant *parameters,
+                    GDBusMethodInvocation *invocation, gpointer user_data) {
+  if (g_strcmp0 (method_name, "ContextCreate") == 0) {
+    int device_id = -1;
+    int priority = -1;
+
+    g_variant_get (parameters, "(ii)", &device_id, &priority);
+    if (device_id >= 0 && priority >= 0) {
+      npumgrContext *ctx = new npumgrContext;
+
+      ctx->setDeviceID (device_id);
+      ctx->setPriority (priority);
+
+      g_dbus_method_invocation_return_value (
+          invocation, g_variant_new ("(t)", reinterpret_cast<uintptr_t> (ctx)));
+    } else {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_INVALID_ARGS,
+                                             "Invalid arguments detected");
+    }
+  } else if (g_strcmp0 (method_name, "ContextDestroy") == 0) {
+    npumgrContext *ctx = NULL;
+
+    g_variant_get (parameters, "(t)", reinterpret_cast<uintptr_t *> (&ctx));
+    if (ctx != NULL) {
+      delete ctx;
+      g_dbus_method_invocation_return_value (invocation, NULL);
+    } else {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_INVALID_ARGS,
+                                             "Invalid arguments detected");
+    }
+  }
+}
+
+/**
+ * @brief Set property callback
+ */
+static GVariant *
+handle_get_property (GDBusConnection *connection, const gchar *sender,
+                     const gchar *object_path, const gchar *interface_name,
+                     const gchar *property_name, GError **error,
+                     gpointer user_data) {
+  /* NYI */
+  return NULL;
+}
+
+/**
+ * @brief Set property callback
+ */
+static gboolean
+handle_set_property (GDBusConnection *connection, const gchar *sender,
+                     const gchar *object_path, const gchar *interface_name,
+                     const gchar *property_name, GVariant *value,
+                     GError **error, gpointer user_data) {
+  /* NYI */
+  return FALSE;
+}
+
+/**
+ * @brief VTable of GDBus Interface
+ */
+static const GDBusInterfaceVTable interface_vtable = {
+    handle_method_call, handle_get_property, handle_set_property};
+
+/**
+ * @brief Callback on the bus connect has been obtained
+ */
+static void
+on_bus_acquired (GDBusConnection *connection, const gchar *name,
+                 gpointer user_data) {
+  guint reg_id;
+
+  reg_id = g_dbus_connection_register_object (
+      connection, "/sr/odl/NPUManager/APIObject",
+      introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL);
+  if (reg_id == 0)
+    g_critical ("Failed to register object");
+}
+
+/**
+ * @brief Callback on the name is acquired
+ */
+static void
+on_name_acquired (GDBusConnection *connection, const gchar *name,
+                  gpointer user_data) {}
+
+/**
+ * @brief Callback on the name is lost or connection has been closed
+ */
+static void
+on_name_lost (GDBusConnection *connection, const gchar *name,
+              gpointer user_data) {
+  exit (1);
+}
+
+/**
+ * @brief Main function for gdbus-based server
+ */
+int
+main (int argc, char *argv[]) {
+  guint owner_id;
+  GMainLoop *loop;
+
+#if !GLIB_CHECK_VERSION(2, 35, 0)
+  g_type_init ();
+#endif
+
+  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+  if (!introspection_data) {
+    g_critical ("Failed to build the introspection data structure");
+    return -1;
+  }
+
+  owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, "sr.odl.NPUManager.API",
+                             G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired,
+                             on_name_acquired, on_name_lost, NULL, NULL);
+
+  loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (loop);
+
+  g_bus_unown_name (owner_id);
+  g_dbus_node_info_unref (introspection_data);
+
+  return 0;
+}
diff --git a/tests/apptests/npumgr/npumgr_api.cc b/tests/apptests/npumgr/npumgr_api.cc
new file mode 100644 (file)
index 0000000..c7afe62
--- /dev/null
@@ -0,0 +1,374 @@
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr_api.cc
+ * @date 09 Apr 2021
+ * @brief GDBus-based implementation of VD NPU Manager APIs (dummy)
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include "npumgr_api.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <gio/gio.h>
+
+/** 1 second timeout */
+#define TIMEOUT 1
+
+void init_npumgr_api (void) __attribute__ ((constructor));
+void fini_npumgr_api (void) __attribute__ ((destructor));
+
+/** initialized once */
+static GDBusConnection *_connection;
+static GThread *_thread;
+static GMainLoop *_loop;
+static GMutex _mutex;
+static GCond _cond;
+static const gchar *_name_owner;
+
+/**
+ * @brief Wait until the gdbus session is connected
+ */
+static gboolean
+wait_until_connected () {
+  g_mutex_lock (&_mutex);
+  while (!_connection) {
+    gint64 end_time = g_get_monotonic_time () + TIMEOUT * G_TIME_SPAN_SECOND;
+    if (!g_cond_wait_until (&_cond, &_mutex, end_time)) {
+      g_mutex_unlock (&_mutex);
+      return FALSE;
+    }
+  }
+  g_mutex_unlock (&_mutex);
+
+  return TRUE;
+}
+
+/**
+ * @brief This API finds available devices on the platform.
+ */
+npumgr_status_e
+npumgr_device_get_available_list (npumgr_devices_id *pdev) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in context creation for using npumgr.
+ */
+npumgr_status_e
+npumgr_context_create (int device_id, int priority, npumgr_context *out_ctx) {
+  GDBusMessage *method_call;
+  GDBusMessage *method_reply;
+  npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+  GError *error = NULL;
+
+  g_return_val_if_fail (wait_until_connected (), NPUMGR_STATUS_ERR_TIMEOUT);
+
+  method_call = g_dbus_message_new_method_call (
+      _name_owner, "/sr/odl/NPUManager/APIObject", "sr.odl.NPUManager.API",
+      "ContextCreate");
+  g_dbus_message_set_body (method_call,
+                           g_variant_new ("(ii)", device_id, priority));
+
+  method_reply = g_dbus_connection_send_message_with_reply_sync (
+      _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
+      &error);
+
+  if (method_reply == NULL) {
+    status = NPUMGR_STATUS_ERR_FAIL;
+    goto out;
+  }
+
+  if (g_dbus_message_get_message_type (method_reply) ==
+      G_DBUS_MESSAGE_TYPE_ERROR) {
+    g_dbus_message_to_gerror (method_reply, &error);
+    g_critical ("error: %s\n", error->message);
+    g_error_free (error);
+    status = NPUMGR_STATUS_ERR_FAIL;
+    goto out;
+  }
+
+  g_variant_get (g_dbus_message_get_body (method_reply), "(t)", out_ctx);
+
+out:
+  g_object_unref (method_call);
+  g_object_unref (method_reply);
+
+  return status;
+}
+
+/**
+ * @brief This API helps in destroying the created context.
+ */
+npumgr_status_e
+npumgr_context_destroy (npumgr_context ctx) {
+  GDBusMessage *method_call;
+  GDBusMessage *method_reply;
+  npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+  GError *error = NULL;
+
+  g_return_val_if_fail (wait_until_connected (), NPUMGR_STATUS_ERR_TIMEOUT);
+
+  method_call = g_dbus_message_new_method_call (
+      _name_owner, "/sr/odl/NPUManager/APIObject", "sr.odl.NPUManager.API",
+      "ContextDestroy");
+  g_dbus_message_set_body (method_call, g_variant_new ("(t)", ctx));
+
+  method_reply = g_dbus_connection_send_message_with_reply_sync (
+      _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
+      &error);
+
+  if (method_reply == NULL) {
+    status = NPUMGR_STATUS_ERR_FAIL;
+    goto out;
+  }
+
+  if (g_dbus_message_get_message_type (method_reply) ==
+      G_DBUS_MESSAGE_TYPE_ERROR) {
+    g_dbus_message_to_gerror (method_reply, &error);
+    g_critical ("error: %s\n", error->message);
+    g_error_free (error);
+    status = NPUMGR_STATUS_ERR_FAIL;
+    goto out;
+  }
+
+out:
+  g_object_unref (method_call);
+  g_object_unref (method_reply);
+
+  return status;
+}
+
+/**
+ * @brief This API helps in network creation.
+ */
+npumgr_status_e
+npumgr_network_create (npumgr_context ctx, int num_files,
+                       npumgr_network_defn *input_files,
+                       npumgr_buffer_t in_buffer_type, int in_tensor_cnt,
+                       const char *const *input_tensor_names,
+                       npumgr_buffer_t out_buffer_type, int out_tensor_cnt,
+                       const char *const *output_tensor_names,
+                       npumgr_network *out_nw_handle) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in attaching a valid input buffer to the inputs of network.
+ */
+npumgr_status_e
+npumgr_network_set_attribute (npumgr_context ctx, npumgr_network nw_handle,
+                              uint32_t wcet_ns, uint32_t deadline_ns,
+                              uint32_t period_ns, uint32_t yield_ns) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in attaching a valid input buffer to the inputs of network.
+ */
+npumgr_status_e
+npumgr_network_set_input (npumgr_context ctx, npumgr_network nw_handle,
+                          int index, npumgr_buffer *input_buffer) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in attaching a valid output buffer to the outputs of network.
+ */
+npumgr_status_e
+npumgr_network_set_output (npumgr_context ctx, npumgr_network nw_handle,
+                           int index, npumgr_buffer *output_buffer) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in preparing network and making it ready to run on hardware.
+ */
+npumgr_status_e
+npumgr_network_prepare (npumgr_context ctx, npumgr_network nw_handle) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in destroying the network and releasing all the resources allocated for this network.
+ */
+npumgr_status_e
+npumgr_network_destroy (npumgr_context ctx, npumgr_network nw_handle) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in buffer creation.
+ */
+npumgr_status_e
+npumgr_buffer_create (npumgr_context ctx,
+                      npumgr_query_tensor_attr *create_param,
+                      npumgr_buffer *buf) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in destroying the creatd buffer.
+ */
+npumgr_status_e
+npumgr_buffer_destroy (npumgr_context ctx, npumgr_buffer *buf) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in mapping the buffer to get the CPU accessible address for read or write.
+ */
+npumgr_status_e
+npumgr_buffer_map (npumgr_context ctx, npumgr_buffer *buf,
+                   uint8_t **mapped_addr) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in unmapping the mapped buffer.
+ */
+npumgr_status_e
+npumgr_buffer_unmap (npumgr_context ctx, npumgr_buffer *buf) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in querying the network for no. of inputs and outputs.
+ */
+npumgr_status_e
+npumgr_query_network (npumgr_context ctx, npumgr_network nw_handle,
+                      npumgr_query_inout_num *data) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in querying the properties of a specific input of a network
+ */
+npumgr_status_e
+npumgr_query_input (npumgr_context ctx, npumgr_network nw_handle, int index,
+                    npumgr_query_tensor_attr *data) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in querying the properties of a specific output of a network
+ */
+npumgr_status_e
+npumgr_query_output (npumgr_context ctx, npumgr_network nw_handle, int index,
+                     npumgr_query_tensor_attr *data) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API is similar to npumgr_run_network except that it returns immediately
+ *        without waiting for HW to complete the commands i.e. it is a non-blocking call.
+ */
+npumgr_status_e
+npumgr_execute_trigger (npumgr_context ctx, npumgr_network nw_handle) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in explicitly wait for HW to finish executing the submitted commands.
+ */
+npumgr_status_e
+npumgr_execute_wait (npumgr_context ctx, npumgr_network nw_handle) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This API helps in running the network.
+ */
+npumgr_status_e
+npumgr_execute_run (npumgr_context ctx, npumgr_network nw_handle) {
+  /* NYI */
+  return NPUMGR_STATUS_SUCCESS;
+}
+
+/**
+ * @brief Callback on connetion success
+ */
+static void
+on_name_appeared (GDBusConnection *connection, const gchar *name,
+                  const gchar *name_owner, gpointer user_data) {
+  g_mutex_lock (&_mutex);
+  _connection = connection;
+  _name_owner = name_owner;
+  g_cond_broadcast (&_cond);
+  g_mutex_unlock (&_mutex);
+}
+
+/**
+ * @brief Callback on connetion failures
+ */
+static void
+on_name_vanished (GDBusConnection *connection, const gchar *name,
+                  gpointer user_data) {
+  g_mutex_lock (&_mutex);
+  _thread = NULL;
+  g_mutex_unlock (&_mutex);
+  g_thread_exit (NULL);
+}
+
+/**
+ * @brief Worker for gdbus client main loop
+ */
+static gpointer
+npumgr_thread (gpointer data) {
+  guint watcher_id;
+
+  watcher_id =
+      g_bus_watch_name (G_BUS_TYPE_SESSION, "sr.odl.NPUManager.API",
+                        G_BUS_NAME_WATCHER_FLAGS_NONE, on_name_appeared,
+                        on_name_vanished, NULL, NULL);
+
+  _loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (_loop);
+
+  g_bus_unwatch_name (watcher_id);
+
+  return NULL;
+}
+
+/**
+ * @brief Constructor of npumgr API library
+ */
+void
+init_npumgr_api (void) {
+  _connection = NULL;
+  _loop = NULL;
+  _thread = g_thread_new (NULL, npumgr_thread, NULL);
+}
+
+/**
+ * @brief Destructor of npumgr APi library
+ */
+void
+fini_npumgr_api (void) {
+  if (_thread) {
+    g_main_loop_quit (_loop);
+    g_thread_join (_thread);
+  }
+}
diff --git a/tests/apptests/npumgr/npumgr_api.h b/tests/apptests/npumgr/npumgr_api.h
new file mode 100644 (file)
index 0000000..89f66a7
--- /dev/null
@@ -0,0 +1,579 @@
+/**
+* @file                        npumgr_api.h
+* @interfacetype       Module \n
+* @privlevel           Non-privilege \n
+* @privilege           None \n
+* @product                     TV \n
+* @SDK_Support                 N \n
+* @version                     1.0
+* 
+* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#ifndef __NPUMGR_API_H__
+#define __NPUMGR_API_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/*
+ * Definition of flag for npumgr_init
+ * */
+
+/**
+* It is a flag for creating a context with low priority, can fallback to CPU and will not be scheduled on NPU if realtime context is ON.
+*/
+#define NPUMGR_FLAG_PRIORITY_DEFAULT           0x00000000
+
+/**
+* It is a flag for creating a context with medium priority, can fallback to CPU and maybe be scheduled on NPU, if device support dynamic cpu app in its id table, (basically has app_id/nw_id which can be assigned) 
+*/
+#define NPUMGR_FLAG_PRIORITY_MEDIUM            0x00000001
+
+/**
+* It is a flag for creating a context with Realtime priority, RT spplications are always scheduled on NPU.
+*/
+#define NPUMGR_FLAG_PRIORITY_REALTIME          0x00000002
+
+/**
+* It is a flag for creating a context with exclusive priority, it is specially for NRT camera applications. RT applications stop working under this flag.
+*/
+#define NPUMGR_FLAG_PRIORITY_DEFAULT_EXCLUSIVE                 0xFFFFFFFF
+
+/**
+*  Error code returned by NPUMGR API.
+
+* This enum basically consists of all the possible
+* error meassages that could be returned by NPUMGR APIs.
+*/
+typedef enum _npumgr_status {
+
+       NPUMGR_STATUS_ERR_FAIL                  = -8,
+       NPUMGR_STATUS_ERR_TIMEOUT               = -7,
+       NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE    = -6,
+       NPUMGR_STATUS_ERR_OUT_OF_MEMORY         = -5,
+       NPUMGR_STATUS_ERR_CTX_INVALID           = -4,
+       NPUMGR_STATUS_ERR_PARAM_INVALID         = -3,
+       NPUMGR_STATUS_ERR_MODEL_INVALID         = -2,
+       NPUMGR_STATUS_ERR_NOT_SUPPORTED         = -1,
+       NPUMGR_STATUS_SUCCESS                   =  0,
+
+
+       NPUMGR_STATUS_MAX
+}npumgr_status_e;
+
+/*
+ * Definition of tensor
+*/
+
+/** This macro tellis the maximum possible dim of tensor.*/
+#define NPUMGR_MAX_DIMS                16
+
+/** This macro tells the maximum name length of tensor.*/
+#define NPUMGR_MAX_NAME_LEN            256
+
+
+/*
+ * Definition of device id
+ */
+
+/** This macro tells the maximum number of possible devices.*/
+#define NPUMGR_MAX_DEVICES             8
+
+/** This macro tells the maximum possible id /type length of device.*/
+#define NPUMGR_MAX_DEVICE_LEN          64
+
+/*
+ * Definition of network model and weights  fd
+ */
+
+/** This macro tells the maximum number of possible network file.*/
+#define NPUMGR_MAX_NETWORK_FILE        2
+
+/**
+* Available device for job.
+
+* This enum basiclly provides the device that would be
+* used for the job i.e. NPU, GPU, DSP etc.
+*/
+typedef enum _npumgr_device_type {
+       NPUMGR_DEVICE_TYPE_NONE = -1,           /**< No. available device at this time. */
+
+       NPUMGR_DEVICE_TYPE_AUTO,                /**< Automatically assign device for job. */
+       NPUMGR_DEVICE_TYPE_CPU,                 /**< Use CPU to run context (if available). */
+       NPUMGR_DEVICE_TYPE_GPU,                 /**< Use GPU to run context (if available). */
+       NPUMGR_DEVICE_TYPE_DSP,                 /**< Use DSD to run context (if available). */
+       NPUMGR_DEVICE_TYPE_NPU,                 /**< Use NPU to run context (should be always available). */
+
+       NPUMGR_DEVICE_TYPE_MAX
+}npumgr_device_type_t;
+
+
+/**
+* Different tensor data types.
+
+* This enum provides the info about different
+* tensor data types.
+*/
+typedef enum _npumgr_tensor_data_type {
+       NPUMGR_TENSOR_DATA_FLOAT32 = 0, /**< Data type is float32. */
+       NPUMGR_TENSOR_DATA_FLOAT16,             /**< Data type is float16. */
+       NPUMGR_TENSOR_DATA_INT8,                        /**< Data type is int8. */
+       NPUMGR_TENSOR_DATA_UINT8,               /**< Data type is uint8. */
+       NPUMGR_TENSOR_DATA_INT16,               /**< Data type is int16. */
+       NPUMGR_TENSOR_DATA_UINT16,              /**< Data type is uint16. */
+       NPUMGR_TENSOR_DATA_UINT24,              /**< Data type is 24bit. */
+
+       NPUMGR_TENSOR_DATA_TYPE_MAX
+}npumgr_tensor_data_t;
+
+/**
+* Quantization type
+
+* This enum denotes the different types of quantisation.
+*/
+typedef enum _npumgr_tensor_qnt_type {
+       NPUMGR_TENSOR_QNT_NONE = 0,     /**< None. */
+       NPUMGR_TENSOR_QNT_DFP,          /**< Dynamic fixed point. */
+       NPUMGR_TENSOR_QNT_AFFINE_ASYMM,  /**< Assymetric affine. */
+
+       NPUMGR_TENSOR_QNT_MAX
+}npumgr_tensor_qnt_t;
+
+
+/**
+* Tensor data format.
+
+* This enum tells about two tensor format availables.
+*/
+typedef enum _npumgr_tensor_fmt {
+       NPUMGR_TENSOR_FMT_NCHW = 0,
+       NPUMGR_TENSOR_FMT_NHWC,
+
+       NPUMGR_TENSOR_FMT_MAX
+}npumgr_tensor_fmt_t;
+
+/**
+*      IN/OUT information for QUERY API.
+*/
+typedef struct _npumgr_query_inout_num {
+    uint32_t n_input;                                   /**< The number of input. */
+    uint32_t n_output;                                  /**< The number of output. */
+} npumgr_query_inout_num;
+
+/**
+* Information for QUERY API.
+*/
+typedef struct _npumgr_query_tensor_attr {
+       uint32_t        n_dims;                         /**< The number of dimensions. */
+       uint32_t    dims[NPUMGR_MAX_DIMS];              /**< The dims array. */
+       char            name[NPUMGR_MAX_NAME_LEN];      /**< The name of tensor. */
+       uint32_t        strides[NPUMGR_MAX_DIMS-1];     /**< The strides of tensor. */
+       uint32_t        plane;                          /**< The Plane. */
+
+       uint32_t        size;                           /**< The bytes size of tensor. */
+
+       npumgr_tensor_fmt_t  fmt;                       /**< The data format of the tensor. */
+       npumgr_tensor_data_t type;                      /**< The data type of tensor. */
+       npumgr_tensor_qnt_t  quant_type;                /**< The quantization type of the tensor. */
+
+       union {
+               struct {
+                       uint8_t fixed_point_pos; /**< \brief Specifies the fixed point position when the input element type is int16, if 0 calculations are performed in integer math. */
+               } dfp;
+
+               struct {
+                       float scale;       /**< \brief Scale value for the quantized value. */
+                       uint32_t zeroPoint;  /**< \brief  A 32 bit integer, in range [0, 255]. */
+               } affine;
+     }
+     quant_data; /**< \brief The union of quantization information. */
+}npumgr_query_tensor_attr;
+
+/**
+* Information for finding device type and its ID.
+*/
+typedef struct _npumgr_devices_id {
+       uint32_t             n_devices;                         /**< Number of devices, index into types[]. */
+       npumgr_device_type_t types[NPUMGR_MAX_DEVICES];         /**< array of device type. */
+       uint32_t             id[NPUMGR_MAX_DEVICES];            /**< array of device_id. */
+}npumgr_devices_id;
+
+/**
+* Context to work with npumgr api.
+*/
+typedef uint64_t npumgr_context;
+
+/**
+* Network file support.
+
+* This enum gives info about different types of network file
+* supportef by npumgr.
+*/
+typedef enum _npumgr_network_file_type {
+       NPUMGR_NETWORK_FILE_NBG = 0,                    /**< Network file of type nbg (VeriSilicon). */
+       NPUMGR_NETWORK_FILE_NCP,                        /**< Network file of type ncp. (Exynos)*/
+       NPUMGR_NETWORK_FILE_TFLITE,                     /**< Network file of type tflite. */
+
+       NPUMGR_NETWORK_FILE_CAFFE_MODEL_FILE,   /**< Network file of type caffe. */
+       NPUMGR_NETWORK_FILE_CAFFE_WEIGHTS_FILE, /**< Network file of type caffe weights. */
+
+
+       NPUMGR_NETWORK_TYPE_MAX
+}npumgr_network_file_t;
+
+/**
+* Network definition.
+*/
+typedef struct _npumgr_network_defn {
+       npumgr_network_file_t type;             /**< Type of network file. */
+       int                   fd;                       /**< File descriptor. */
+}npumgr_network_defn;
+
+/**
+* Handle to npumgr network api.
+*/
+typedef uint64_t npumgr_network;
+
+/**
+* Handle to npumgr buffer api.
+*/
+typedef uint64_t npumgr_buffer_h;
+
+/**
+* Buffer type.
+*
+* This enum gives the info about different types of buffer options available to us.
+*/
+typedef enum _npumgr_buffer_type {
+       NPUMGR_BUF_TYPE_DRIVER = 0, /**< This type of buffer is allocated by device - npu memory or exportable memory. */
+       NPUMGR_BUF_TYPE_DMABUF, /**< This type of buffer os imported by dmabuf fd or importable memory. */
+       NPUMGR_BUF_TYPE_CUSTOM_INDEX, /**< DPB Buffer (custom) index for memory. */
+       NPUMGR_BUF_TYPE_PATCH, /**< This type of buffer is not allocated but it is patched by npumgr with help from other drivers. */
+       NPUMGR_BUT_TYPE_MAX
+}npumgr_buffer_t;
+
+/**
+* Handle to npumgr buffer api.
+*/
+typedef struct _npumgr_buffer {
+       npumgr_buffer_t  buf_type; /**< Type of buffer. */
+       npumgr_buffer_h  buf_handle; /**< (OUT) A handle to buffer. */
+       uint32_t         buf_fd; /**< Handle(device-node/fd/gem-name) to the buffer, IN/OUT (OUT for NPUMGR_BUG_TYPE_DRIVER) IN otherwise. */
+       uint32_t         buf_size; /**< OUT size of buffer. */
+       uint32_t         buf_offset; /**< OUT offset of buffer. */
+}npumgr_buffer;
+
+/**
+* A DEVICE API.
+*
+* It finds available devices on the platform.
+* @param [out] pdev : A npumgr_devices_id pointer type argument that returns the id of available device.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre None
+* @post
+* @exception None
+*/
+npumgr_status_e npumgr_device_get_available_list (npumgr_devices_id *pdev);
+
+
+/* Create a context to use npumgr */
+
+/*
+ * params -
+ * optional : device_id : from npumgr_device_get_available_list () , set to -1
+ * optional : priority : NPUMGR_FLAG_PRIORITY_DEFAULT set to 0
+ */
+
+/**
+* A CONTEXT API.
+*
+* This API helps in context creation for using npumgr.
+* @param [in] device_id : ID for the avaialble device(NPU in this case) over the hardware.
+* @param [in] priority : Priority of the context to be created.
+* @param [out] out_ctx : Pointer to the context created.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_device_get_available_list
+* @post npumgr_context_destroy
+* @exception None
+*/
+npumgr_status_e npumgr_context_create(int device_id, int priority, npumgr_context *out_ctx);
+
+/**
+* A CONTEXT API.
+*
+* This API helps in destroying the created context.
+* @param [in] ctx : Context to be destroyed.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_context_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_context_destroy(npumgr_context ctx);
+
+
+/**
+* A NETWORK API.
+*
+* This API helps in network creation.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] num_files : No. of network files.
+* @param [in] input_files : Pointer to newtwork definition containing fd and network type.
+* @param [in] in_buffer_type : Type of input buffer.
+* @param [in] in_tensor_cnt : Input tesnor count.
+* @param [in] input_tensor_names : Input tensor name.
+* @param [in] out_buffer_type : Type of output buffer.
+* @param [in] out_tensor_cnt : Output tensor count.
+* @param [in] output_tensor_names : Output tensor name.
+* @param [out] out_nw_handle : Handle to the network created.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_context_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_network_create(npumgr_context ctx, int num_files, npumgr_network_defn *input_files, npumgr_buffer_t in_buffer_type, int in_tensor_cnt, const char * const*input_tensor_names, npumgr_buffer_t out_buffer_type, int out_tensor_cnt, const char * const* output_tensor_names, npumgr_network *out_nw_handle);
+
+/**
+* A NETWORK API.
+*
+* This API helps in setting network attribute i.e. wcet, deadline, period and yield time for context with priority > NPUMGR_FLAG_PRIORITY_DEFAULT
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network created from \link npumgr_network_create npumgr_network_create \endlink .
+* @param [in] wcet_ns : Worst case execution time in ns.
+* @param [in] deadline_ns : Deadline in ns. 
+* @param [in] period_ns : Period in ns.
+* @param [in] yield_ns : Yield time in ns.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_network_set_attribute(npumgr_context ctx, npumgr_network nw_handle, uint32_t wcet_ns, uint32_t deadline_ns, uint32_t period_ns, uint32_t yield_ns);
+
+/**
+* A NETWORK API.
+*
+* This API helps in attaching a valid input buffer to the inputs of network.
+* When attaching an input buffer to the network, driver would patch the network command buffer to fill in this input buffer address.
+* This api could be called multiple times to let application update the input buffers before next network execution.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network for which network is to be set.
+* @param [in] index : The index specify which input in the network will be set.
+* @param [in] input_buffer : Input buffer that will be attached to the network input.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_network_set_input(npumgr_context ctx, npumgr_network nw_handle, int index, npumgr_buffer *input_buffer);
+
+/**
+* A NETWORK API.
+*
+* This API helps in attaching a valid input buffer to the outputs of network.
+* When attaching an output buffer to the network, driver would patch the network command buffer to fill in this output buffer address.
+* This api could be called multiple times to let application update the output buffers before next network execution.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network for which network is to be set.
+* @param [in] index : an int type argument taking index as input.
+* @param [in] output_buffer : a npumgr_buffer type pointer argument.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_network_set_output(npumgr_context ctx, npumgr_network nw_handle, int index, npumgr_buffer *output_buffer);
+
+/* allocate resources and bind npumgr_buffer */
+/**
+* A NETWORK API.
+*
+* This API helps in preparing network and making it ready to run on hardware. It will allocate internal memory resource for this network, deploy all operation's resource
+* to internal memory pool, allocate/generate command buffer for this network, patch command buffer for the resource in the internal memory allocations.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network which is to be prepared for execution.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_network_prepare(npumgr_context ctx, npumgr_network nw_handle);
+
+/**
+* A NETWORK API.
+*
+* This API helps in destroying the network and releasing all the resources allocated for this network.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network to be destroyed.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_prepare
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_network_destroy(npumgr_context ctx, npumgr_network nw_handle);
+
+
+/* BUFFER API */
+ /* create() be used as create_from_handle if buf_type != DRIVER */
+/**
+* BUFFER API
+*
+* This API helps in buffer creation.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] create_param : Pointer to query tensor attribute that contains the value all parameters i.e. n_dims, dims, size, type etc required for buffer creation.
+* @param [out] buf : Pointer to the buffer created.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_query_input or npumgr_query_output
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_buffer_create(npumgr_context ctx, npumgr_query_tensor_attr *create_param, npumgr_buffer *buf);
+
+/**
+* BUFFER API
+*
+* This API helps in destroying the creatd buffer.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] buf : Pointer to the buffer to be destroyed.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_buffer_unmap
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_buffer_destroy(npumgr_context ctx, npumgr_buffer *buf);
+
+/**
+* BUFFER API
+*
+* This API helps in mapping the buffer to get the CPU accessible address for read or write.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] buf : Pointer to the buffer to be mapped.
+* @param [out] mapped_addr : Address of the mapped buffer.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_buffer_create
+* @post npumgr_buffer_unmap
+* @exception None
+*/
+npumgr_status_e npumgr_buffer_map(npumgr_context ctx, npumgr_buffer *buf, uint8_t **mapped_addr);
+
+/**
+* BUFFER API
+*
+* This API helps in unmapping the mapped buffer.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] buf : Pointer to the buffer to be unmapped.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_buffer_map
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_buffer_unmap(npumgr_context ctx, npumgr_buffer *buf);
+
+
+/* QUERY API */
+/**
+* QUERY API.
+*
+* This API helps in querying the network for no. of inputs and outputs.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network to be queried.
+* @param [out] data : Pointer to a structure that will store the no. of inputs and outputs for the network.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_query_network(npumgr_context ctx, npumgr_network nw_handle, npumgr_query_inout_num *data);
+
+/**
+* QUERY API.
+*
+* This API helps in querying the properties of a specific input of a netwokr i.e. input size, dim, type etc.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network whose input is to be queried.
+* @param [in] index : Specifying the index of the input from the network to be queried`.
+* @param [out] data : Pointer to a structure that will store the queried properties i.e. size, dim, type etc of the network input specified.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_query_input(npumgr_context ctx, npumgr_network nw_handle, int index,  npumgr_query_tensor_attr *data);
+
+/**
+* QUERY API.
+*
+* This API helps in querying the properties of a specific output of a netwokr i.e. input size, dim, type etc.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network whose output is to be queried.
+* @param [in] index : Specifying the index of the output from the network to be queried`.
+* @param [out] data : Pointer to a structure that will store the queried properties i.e. size, dim, type etc of the network output specified.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_create
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_query_output(npumgr_context ctx, npumgr_network nw_handle, int index,  npumgr_query_tensor_attr *data);
+
+
+/* EXECUTION API */
+/**
+* EXECUTION API.
+*
+* This API is similar to npumgr_run_network except that it returns immediately without waiting for HW to complete the commands i.e. it is a non-blocking call.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network to be executed.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_set_input, npumgr_network_set_output and npumgr_network_prepare
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_execute_trigger(npumgr_context ctx, npumgr_network nw_handle);
+
+/**
+* EXECUTION API.
+*
+* This API helps in explicitly wait for HW to finish executing the submitted commands.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network to be executed.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_execute_trigger
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_execute_wait (npumgr_context ctx, npumgr_network nw_handle);
+
+/**
+* EXECUTION API.
+*
+* This API helps in running the network. It can be called multiple times and it would do inference with currrent attached input and output buffers. It is a blocking call.
+* @param [in] ctx : npumgr context created from \link npumgr_context_create npumgr_context_create \endlink .
+* @param [in] nw_handle : Handle to the network to be executed.
+* @return Success : NPUMGR_STATUS_SUCCESS or refer \link _npumgr_status npumgr_status \endlink enum
+* @pre npumgr_network_set_input, npumgr_network_set_output and npumgr_network_prepare
+* @post None
+* @exception None
+*/
+npumgr_status_e npumgr_execute_run (npumgr_context ctx, npumgr_network nw_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NPUMGR_API_H__ */
diff --git a/tests/apptests/npumgr/npumgr_device.h b/tests/apptests/npumgr/npumgr_device.h
new file mode 100644 (file)
index 0000000..d3cb683
--- /dev/null
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <glib-object.h>
+#include <npumgr_api.h>
+
+G_BEGIN_DECLS
+
+// !Bitwise
+#define NPUMGR_DEVICE_CAPABILITY_MMAP             (0x1 << 0)
+#define NPUMGR_DEVICE_CAPABILITY_MULTICONTEXT  (0x1 << 1)
+#define NPUMGR_DEVICE_CAPABILITY_MMU              (0x1 << 2)
+#define NPUMGR_DEVICE_CAPABILITY_REALTIME         (0x1 << 3)
+
+typedef enum _npumgr_device_state {
+       NPUMGR_DEVICE_STATE_IDLE = 0,
+       NPUMGR_DEVICE_STATE_NON_REALTIME = 1,
+       NPUMGR_DEVICE_STATE_REALTIME = 2,
+       NPUMGR_DEVICE_STATE_MAX
+}npumgr_device_state_e;
+
+/*  If app_id/nw_id value is -1, it means plugin need to allocate indices appropriately in table*/
+#define NPUMGR_REALTIME_ID_DYNAMIC ((uint32_t)-1)
+
+#define NPUMGR_TYPE_DEVICE (npumgr_device_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (NpumgrDevice, npumgr_device, NPUMGR, DEVICE, GObject)
+
+struct _NpumgrDeviceClass
+{
+  GObjectClass parent;
+
+  /* virtual table */
+
+  npumgr_status_e (*device_get_capabilities) (NpumgrDevice *device, uint32_t *caps, npumgr_device_type_t *ptype);
+  npumgr_status_e (*device_get_fd) (NpumgrDevice *device, uint32_t *device_fd, uint32_t *mem_fd);
+  npumgr_status_e (*device_get_memory_info) (NpumgrDevice *device, uint32_t *device_memory);
+  npumgr_status_e (*device_get_preload_path) (NpumgrDevice *device, char **vconf_parent_dir);
+  npumgr_status_e (*device_get_mem_iface_path) (NpumgrDevice *device, char **path_to_mem_module);
+  npumgr_status_e (*device_set_state) (NpumgrDevice *device, npumgr_device_state_e state);
+
+  npumgr_status_e (*context_create) (NpumgrDevice *device, int device_id, int priority, npumgr_context *out_ctx);
+  npumgr_status_e (*context_destroy) (NpumgrDevice *device, npumgr_context ctx);
+
+  npumgr_status_e (*network_create) (NpumgrDevice *device, npumgr_context ctx, int num_files, npumgr_network_defn *input_files, 
+                                                                               npumgr_buffer_t in_buffer_type, int in_tensor_cnt, char **input_tensor_names, 
+                                                                               npumgr_buffer_t out_buffer_type, int out_tensor_cnt, char **output_tensor_names, npumgr_network *out_nw_handle);
+  npumgr_status_e (*network_set_input) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, int index, npumgr_buffer *input_buffer);
+  npumgr_status_e (*network_set_output) (NpumgrDevice *device,  npumgr_context ctx, npumgr_network nw_handle, int index, npumgr_buffer *output_buffer);
+  npumgr_status_e (*network_prepare) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+  npumgr_status_e (*network_destroy) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+
+  npumgr_status_e (*network_set_realtime) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, uint32_t *app_id, uint32_t *nw_id, uint32_t *ppu_id);
+  npumgr_status_e (*network_unset_realtime) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+
+  npumgr_status_e (*buffer_create) (NpumgrDevice *device, npumgr_context ctx, npumgr_query_tensor_attr *create_param, npumgr_buffer *buf);
+  npumgr_status_e (*buffer_destroy) (NpumgrDevice *device, npumgr_context ctx, npumgr_buffer *buf);
+  npumgr_status_e (*buffer_map) (NpumgrDevice *device, npumgr_context ctx, npumgr_buffer *buf, uint8_t **mapped_addr);
+  npumgr_status_e (*buffer_unmap) (NpumgrDevice *device, npumgr_context ctx, npumgr_buffer *buf);
+  npumgr_status_e (*query_network) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, npumgr_query_inout_num *data);
+  npumgr_status_e (*query_input) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, int index,  npumgr_query_tensor_attr *data);
+  npumgr_status_e (*query_output) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, int index,  npumgr_query_tensor_attr *data);
+  npumgr_status_e (*execute_trigger) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+  npumgr_status_e (*execute_wait ) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+  npumgr_status_e (*execute_run ) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+
+  /*  if app_id, nw_id == NPUMGR_REALTIME_ID_DYNAMIC , that means dynamic allocation */
+  npumgr_status_e (*execute_realtime) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, uint32_t task_handle, uint32_t subtask_id);
+  npumgr_status_e (*execute_wait_realtime) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, uint32_t *golden_val, uint32_t **golden_addr);
+  npumgr_status_e (*execute_completed_realtime) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+  
+  npumgr_status_e (*profiler_get_network_meminfo) (NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle, 
+                                                                               uint32_t *input_memory, uint32_t *output_memory,  uint32_t *intermediate_memory);
+
+  /*  for future  */
+  gpointer padding[12];
+};
+
+G_END_DECLS
diff --git a/tests/apptests/npumgr/npumgr_test.cc b/tests/apptests/npumgr/npumgr_test.cc
new file mode 100644 (file)
index 0000000..8b0fc2f
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr_test.cc
+ * @date 09 Apr 2021
+ * @brief AppTest to test the I/F of VD NPU Manager
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <iostream>
+#include "npumgr_api.h"
+
+int
+main (int argc, char **argv) {
+  npumgr_context ctx;
+  npumgr_status_e status;
+
+  status = npumgr_context_create (0 /* device_id */, 0 /* priority */, &ctx);
+  if (status != NPUMGR_STATUS_SUCCESS) {
+    std::cerr << "Unable to create a npumgr context, " << status << "\n";
+    return status;
+  }
+
+  status = npumgr_context_destroy (ctx);
+  if (status != NPUMGR_STATUS_SUCCESS) {
+    std::cerr << "Unable to destroy the npumgr context, " << status << "\n";
+    return status;
+  }
+
+  return 0;
+}