| |-- unittests Source files for Unit Tests
| |-- apptests Source files for App Tests
| `-- utils Source files for Test Utils
+|-- plugins/
+| |-- npumgr Reference plugin codes for NPU Manager
+| `-- nnstreamer Reference plugin codes for NNStreamer
|-- packaging/ Tizen Packaging Files (i.e., FastModel or FPGA)
|-- debian/ Debian Packaging Files (i.e., Ubuntu 18.04)
`-- docs/ Documentation using hotdoc
subdir('src')
subdir('tests')
subdir('utils')
+subdir('plugins')
# Set configuration to install .ini
ne_install_conf = configuration_data()
option('enable_npu_emul', type : 'boolean', value : false)
option('enable_data_manip', type : 'boolean', value : false)
option('enable_buffering', type : 'boolean', value : false)
-option('enable_vd_npumgr', type : 'boolean', value : false)
+option('enable_plugin_npumgr', type : 'boolean', value : false)
+option('enable_plugin_nns', type : 'boolean', value : false)
option('kernel_hdr_dir', type : 'string', value : '')
BuildRequires: gtest-devel
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(tinyxml2)
-
-BuildRequires: pkgconfig(dlog)
-
-BuildRequires: glib2-devel
+BuildRequires: pkgconfig(dlog)
%if 0%{?npu_emul}
-BuildRequires: libmrpsim-devel
+BuildRequires: libmrpsim-devel
%define enable_npu_emul -Denable_npu_emul=true
%else
%define enable_npu_emul -Denable_npu_emul=false
%endif
-%if 0%{?vd_npumgr}
-BuildRequires: tizen-npumanager-devel
-%define enable_vd_npumgr -Denable_vd_npumgr=true
+%if 0%{?npumgr_plugin}
+BuildRequires: glib2-devel
+%define enable_plugin_npumgr -Denable_plugin_npumgr=true
+%else
+%define enable_plugin_npumgr -Denable_plugin_npumgr=false
+%endif
+
+%if 0%{?nns_plugin}
+BuildRequires: nnstreamer-devel
+%define enable_plugin_nns -Denable_plugin_nns=true
%else
-%define enable_vd_npumgr -Denable_vd_npumgr=false
+%define enable_plugin_nns -Denable_plugin_nns=false
%endif
%global debug_package %{nil}
--libdir=%{_libdir} --includedir=%{_includedir} \
--datadir=%{_datadir} --sysconfdir=%{_sysconfdir} \
-Dtarget_platform=tizen -Denable_data_manip=true \
- %{enable_npu_emul} %{enable_vd_npumgr} \
+ %{enable_npu_emul} %{enable_plugin_npumgr} %{enable_plugin_nns} \
build
ninja -C build %{?_smp_mflags}
%defattr(-,root,root,-)
%{neexampledir}/unittests/*
%{neexampledir}/apptests/*
-%{_libdir}/libnpumgr*.so
-%{_datadir}/dbus-1/system.d/*
%package utils
Requires: npu-engine = %{version}-%{release}
%defattr(-,root,root,-)
%{neexampledir}/utils/*
+%if 0%{?npumgr_plugin}
+%package -n npumgr-srnpu
+Summary: Tizen NPU Manager plugin for SR-NPU device family
+Requires: npu-engine
+%description -n npumgr-srnpu
+Reference implementation of Tizen NPU Manager TRIV2 plugin, including a dummy NPU Manager module.
+%files -n npumgr-srnpu
+%manifest npu-engine.manifest
+%{neexampledir}/plugins/npumgr/*
+%{_libdir}/libnpumgr*.so
+%{_datadir}/dbus-1/system.d/*
+%endif
+
+%if 0%{?nns_plugin}
+%package -n nnstreamer-srnpu
+Summary: NNStreamer subplugin for SR-NPU device family
+Requires: npu-engine
+Requires: nnstreamer
+%description -n nnstreamer-srnpu
+Reference implementation of NNStreamer filter subplugin for SR-NPU (for now, TRIV2 only).
+%files -n nnstreamer-srnpu
+%manifest npu-engine.manifest
+%{neexampledir}/plugins/nnstreamer/*
+%{_prefix}/lib/nnstreamer/filters/libnnstreamer_filter_srnpu.so
+%{_prefix}/lib/nnstreamer/unittest/nnstreamer_filter_srnpu/*
+%endif
+
%changelog
* Fri Jul 02 2021 Dongju Chae <dongju.chae@samsung.com>
- npu-engine v2.3.12 release; See ./CHANGES for details
--- /dev/null
+if get_option('enable_plugin_nns')
+ subdir('nnstreamer')
+endif
+if get_option('enable_plugin_npumgr')
+ if target_platform == 'tizen'
+ subdir('npumgr')
+ else
+ error('npumgr is available only on Tizen env.')
+ endif
+endif
--- /dev/null
+# Placeholder of NNStreamer TRIV2 subplugin
--- /dev/null
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr_common.h
+ * @date 10 May 2021
+ * @brief npumgr common header
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#ifndef __NPUMGR_COMMON_H__
+#define __NPUMGR_COMMON_H__
+
+#include <sys/mman.h>
+#include <sys/user.h> /* PAGE_SIZE */
+
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT (12)
+#endif
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#endif
+
+#ifndef PFN_UP
+#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
+#endif
+
+#define ALIGNED_SIZE(x) (PFN_UP (x) * PAGE_SIZE)
+
+#endif
--- /dev/null
+# Note that VD NPU Manager is a gdbus-based thread application
+gmodule_dep = dependency('gmodule-2.0', required: false)
+giounix_dep = dependency('gio-unix-2.0', required: false)
+if gmodule_dep.found() and giounix_dep.found()
+ npumgr_deps = [
+ glib_dep,
+ gmodule_dep,
+ giounix_dep
+ ]
+
+ if target_platform == 'tizen'
+ npumgr_deps += dependency('dlog')
+ endif
+
+ npumgr_lib = shared_library ('npumgr',
+ 'npumgr_api.cc',
+ include_directories : [npumgr_common_inc],
+ dependencies: npumgr_deps,
+ build_rpath : ne_libdir,
+ install : true,
+ install_rpath : ne_libdir,
+ install_dir : ne_libdir
+ )
+ npumgr_dep = declare_dependency (link_with : npumgr_lib,
+ include_directories : include_directories('.')
+ )
+
+ npumgr_triv2_lib = shared_library ('npumgr_triv2',
+ ['npumgr_triv2.cc', 'npumgr_device.cc'],
+ include_directories : [ne_common_inc, ne_host_inc],
+ dependencies: npumgr_deps,
+ link_with : ne_library_shared,
+ build_rpath : ne_libdir,
+ install : true,
+ install_rpath : ne_libdir,
+ install_dir : ne_libdir
+ )
+
+ executable ('dummy_npumgr',
+ ['npumgr.cc', 'npumgr_device.cc'],
+ dependencies: npumgr_deps,
+ install : true,
+ install_rpath : ne_libdir,
+ install_dir : join_paths(ne_bindir, 'apptests', 'npumgr')
+ )
+
+ install_data ('sr.odl.NPUManager.conf',
+ install_dir: join_paths(get_option('datadir'), 'dbus-1', 'system.d')
+ )
+endif
--- /dev/null
+/**
+ * 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 <vector>
+#include <string>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <gmodule.h>
+#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
+
+#include <npumgr_api.h>
+#include <npumgr_device.h>
+
+#define NPUMGR_DAEMON_NAME "npumgr-dummy"
+#define NPUMGR_DEVICE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), NPUMGR_TYPE_DEVICE, NpumgrDeviceClass))
+
+#ifdef __TIZEN__
+#include <dlog.h>
+#define TAG_NAME NPUMGR_DAEMON_NAME
+#define logi(...) dlog_print (DLOG_INFO, TAG_NAME, __VA_ARGS__)
+#define logw(...) dlog_print (DLOG_WARN, TAG_NAME, __VA_ARGS__)
+#define loge(...) dlog_print (DLOG_ERROR, TAG_NAME, __VA_ARGS__)
+#else
+#include <syslog.h>
+#define logi(...) syslog (LOG_INFO, __VA_ARGS__)
+#define logw(...) syslog (LOG_WARNING, __VA_ARGS__)
+#define loge(...) syslog (LOG_ERR, __VA_ARGS__)
+#endif
+
+/**
+ * @brief Internal data structure for NPU Manager Context
+ */
+typedef struct {
+ NpumgrDevice *device;
+ npumgr_context handle;
+} NpumgrContext;
+
+G_LOCK_DEFINE_STATIC (mutex);
+static GHashTable *ctx_table;
+
+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='DeviceGetAvailableList'>"
+ " <arg type='u' name='num_devices' direction='out'/>"
+ " <arg type='ai' name='device_type' direction='out'/>"
+ " <arg type='au' name='device_id' direction='out'/>"
+ " </method>"
+ " <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>"
+ " <method name='NetworkCreate'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='i' name='num_files' direction='in'/>"
+ " <arg type='at' name='input_files' direction='in'/>"
+ " <arg type='i' name='in_buffer_type' direction='in'/>"
+ " <arg type='i' name='in_tensor_cnt' direction='in'/>"
+ " <arg type='v' name='in_tensor_names' direction='in'/>"
+ " <arg type='i' name='out_buffer_type' direction='in'/>"
+ " <arg type='i' name='out_tensor_cnt' direction='in'/>"
+ " <arg type='v' name='out_tensor_names' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='out'/>"
+ " </method>"
+ " <method name='NetworkSetInput'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " <arg type='i' name='index' direction='in'/>"
+ " <arg type='v' name='buffer' direction='in'/>"
+ " </method>"
+ " <method name='NetworkSetOutput'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " <arg type='i' name='index' direction='in'/>"
+ " <arg type='v' name='buffer' direction='in'/>"
+ " </method>"
+ " <method name='NetworkPrepare'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " </method>"
+ " <method name='NetworkDestroy'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " </method>"
+ " <method name='BufferCreate'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='v' name='param' direction='in'/>"
+ " <arg type='v' name='buffer' direction='out'/>"
+ " </method>"
+ " <method name='BufferMap'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='v' name='buffer' direction='in'/>"
+ " <arg type='v' name='buffer' direction='out'/>"
+ " </method>"
+ " <method name='BufferDestroy'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='v' name='buffer' direction='in'/>"
+ " </method>"
+ " <method name='QueryNetwork'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " <arg type='u' name='n_input' direction='out'/>"
+ " <arg type='u' name='n_output' direction='out'/>"
+ " </method>"
+ " <method name='QueryInput'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " <arg type='i' name='index' direction='in'/>"
+ " <arg type='v' name='data' direction='out'/>"
+ " </method>"
+ " <method name='QueryOutput'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " <arg type='i' name='index' direction='in'/>"
+ " <arg type='v' name='data' direction='out'/>"
+ " </method>"
+ " <method name='ExecuteTrigger'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " </method>"
+ " <method name='ExecuteWait'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " </method>"
+ " <method name='ExecuteRun'>"
+ " <arg type='t' name='ctx_handle' direction='in'/>"
+ " <arg type='t' name='nw_handle' direction='in'/>"
+ " </method>"
+ " </interface>"
+ " </node>";
+
+/**
+ * @brief Name of supported plugins
+ */
+static const char *supported_plugins[] = {
+ "triv2",
+};
+
+/**
+ * @brief Internal structure to hold plugin data
+ */
+typedef struct {
+ const char *name;
+ GModule *module;
+ NpumgrDevice *device;
+ uint32_t id;
+ uint32_t caps;
+ npumgr_device_type_t ptype;
+} plugin_pdata;
+
+/**
+ * @brief Registered plugins
+ */
+static GSList *registered_plugins;
+
+static void
+append_device (gpointer data, gpointer user_data) {
+ plugin_pdata *pdata = (plugin_pdata *) data;
+ npumgr_devices_id *devices = (npumgr_devices_id *) user_data;
+ NpumgrDevice *device = pdata->device;
+
+ NPUMGR_DEVICE_GET_CLASS (device)->device_get_capabilities (
+ device, &pdata->caps, &pdata->ptype);
+
+ devices->types[devices->n_devices] = pdata->ptype;
+ devices->id[devices->n_devices] = pdata->id;
+ devices->n_devices++;
+}
+
+/**
+ * @brief Insert npumgr context created
+ */
+static gboolean
+insert_context (npumgr_context handle, NpumgrContext *context) {
+ gboolean result;
+
+ G_LOCK (mutex);
+ result = g_hash_table_insert (ctx_table, GSIZE_TO_POINTER (handle), context);
+ G_UNLOCK (mutex);
+
+ return result;
+}
+
+/**
+ * @brief Remove the npumgr context
+ */
+static gboolean
+remove_context (npumgr_context handle) {
+ gboolean result;
+
+ G_LOCK (mutex);
+ result = g_hash_table_remove (ctx_table, GSIZE_TO_POINTER (handle));
+ G_UNLOCK (mutex);
+
+ return result;
+}
+
+/**
+ * @brief Find npumgr context created
+ */
+static NpumgrContext *
+find_context (npumgr_context handle) {
+ NpumgrContext *context;
+
+ G_LOCK (mutex);
+ context = (NpumgrContext *) g_hash_table_lookup (ctx_table,
+ GSIZE_TO_POINTER (handle));
+ G_UNLOCK (mutex);
+
+ return context;
+}
+
+/**
+ * @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, "DeviceGetAvailableList") == 0) {
+ GVariantBuilder builder, builder_arr;
+ npumgr_devices_id devices = {.n_devices = 0};
+
+ g_slist_foreach (registered_plugins, append_device, &devices);
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(uaiau)"));
+ g_variant_builder_add (&builder, "u", devices.n_devices);
+
+ g_variant_builder_init (&builder_arr, G_VARIANT_TYPE ("ai"));
+ for (int i = 0; i < devices.n_devices; i++)
+ g_variant_builder_add (&builder_arr, "i", ((int *) devices.types)[i]);
+ g_variant_builder_add_value (&builder,
+ g_variant_builder_end (&builder_arr));
+
+ g_variant_builder_init (&builder_arr, G_VARIANT_TYPE ("au"));
+ for (int i = 0; i < devices.n_devices; i++)
+ g_variant_builder_add (&builder_arr, "u", ((int *) devices.id)[i]);
+ g_variant_builder_add_value (&builder,
+ g_variant_builder_end (&builder_arr));
+
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_builder_end (&builder));
+ } else 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) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments detected");
+ return;
+ }
+
+ plugin_pdata *pdata =
+ (plugin_pdata *) g_slist_nth_data (registered_plugins, device_id);
+ if (pdata == NULL) {
+ g_dbus_method_invocation_return_error (
+ invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Invalid device id");
+ return;
+ }
+
+ NpumgrDevice *device = pdata->device;
+ npumgr_context handle;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->context_create (
+ device, device_id, priority, &handle);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ NpumgrContext *ctx;
+
+ ctx = g_new0 (NpumgrContext, 1);
+ ctx->handle = handle;
+ ctx->device = device;
+
+ if (insert_context (handle, ctx)) {
+ g_dbus_method_invocation_return_value (invocation,
+ g_variant_new ("(t)", handle));
+ } else {
+ g_dbus_method_invocation_return_error (
+ invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Unable to add context: same context handle detected");
+ NPUMGR_DEVICE_GET_CLASS (device)->context_destroy (device, handle);
+ g_free (ctx);
+ }
+ } else {
+ g_dbus_method_invocation_return_error (
+ invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Unable to add context: internal errors");
+ }
+ } else if (g_strcmp0 (method_name, "ContextDestroy") == 0) {
+ npumgr_context handle = 0;
+
+ g_variant_get (parameters, "(t)", &handle);
+ if (handle > 0) {
+ if (remove_context (handle))
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ else
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ } 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, "NetworkCreate") == 0) {
+ npumgr_context ctx_handle = 0;
+ int num_files;
+ GVariantIter *input_files_iter;
+ npumgr_buffer_t in_buffer_type, out_buffer_type;
+ int in_tensor_cnt, out_tensor_cnt;
+ GVariant *in_tensor_names_var;
+ GVariant *out_tensor_names_var;
+
+ g_variant_get (parameters, "(tiatiiviiv)", &ctx_handle, &num_files,
+ &input_files_iter, &in_buffer_type, &in_tensor_cnt,
+ &in_tensor_names_var, &out_buffer_type, &out_tensor_cnt,
+ &out_tensor_names_var);
+
+ if (ctx_handle > 0 && num_files > 0 && in_tensor_cnt < NPUMGR_MAX_DIMS &&
+ out_tensor_cnt < NPUMGR_MAX_DIMS) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context == NULL) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to find context");
+ return;
+ }
+ NpumgrDevice *device = context->device;
+ GDBusMessage *message = g_dbus_method_invocation_get_message (invocation);
+ GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list (message);
+
+ std::vector<npumgr_network_defn> input_files_vec;
+ npumgr_network_defn input_file;
+ while (g_variant_iter_loop (input_files_iter, "t", &input_file)) {
+ input_file.fd = g_unix_fd_list_get (fd_list, 0, NULL);
+ input_files_vec.push_back (input_file);
+ }
+ g_variant_iter_free (input_files_iter);
+
+ gchar **in_tensor_names = g_variant_dup_strv (in_tensor_names_var, NULL);
+ gchar **out_tensor_names =
+ g_variant_dup_strv (out_tensor_names_var, NULL);
+
+ npumgr_network nw_handle;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->network_create (
+ device, ctx_handle, num_files, input_files_vec.data (),
+ in_buffer_type, in_tensor_cnt, in_tensor_names, out_buffer_type,
+ out_tensor_cnt, out_tensor_names, &nw_handle);
+
+ g_strfreev (in_tensor_names);
+ g_strfreev (out_tensor_names);
+ g_variant_unref (in_tensor_names_var);
+ g_variant_unref (out_tensor_names_var);
+
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(t)", nw_handle));
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to add network");
+ }
+ } 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, "NetworkSetInput") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+ GVariant *variant = NULL;
+ int index = -1;
+
+ g_variant_get (parameters, "(ttiv)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle, &index, &variant);
+ if (ctx_handle > 0 && nw_handle > 0 && index >= 0 && variant != NULL) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+ npumgr_buffer buffer;
+ GBytes *bytes;
+
+ bytes = g_variant_get_data_as_bytes (variant);
+ if (g_bytes_get_size (bytes) != sizeof (buffer)) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments detected");
+ g_bytes_unref (bytes);
+ return;
+ }
+
+ memcpy (&buffer, g_bytes_get_data (bytes, NULL), sizeof (buffer));
+ g_bytes_unref (bytes);
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->network_set_input (
+ device, ctx_handle, nw_handle, index, &buffer);
+ if (status == NPUMGR_STATUS_SUCCESS)
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ else
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to set the input");
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "NetworkSetOutput") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+ GVariant *variant = NULL;
+ int index = -1;
+
+ g_variant_get (parameters, "(ttiv)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle, &index, &variant);
+ if (ctx_handle > 0 && nw_handle > 0 && index >= 0 && variant != NULL) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+ npumgr_buffer buffer;
+ GBytes *bytes;
+
+ bytes = g_variant_get_data_as_bytes (variant);
+ if (g_bytes_get_size (bytes) != sizeof (buffer)) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments detected");
+ g_bytes_unref (bytes);
+ return;
+ }
+
+ memcpy (&buffer, g_bytes_get_data (bytes, NULL), sizeof (buffer));
+ g_bytes_unref (bytes);
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->network_set_output (
+ device, ctx_handle, nw_handle, index, &buffer);
+ if (status == NPUMGR_STATUS_SUCCESS)
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ else
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to set the output");
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "NetworkPrepare") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+
+ g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle);
+ if (ctx_handle > 0 && nw_handle > 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->network_prepare (
+ device, ctx_handle, nw_handle);
+ if (status == NPUMGR_STATUS_SUCCESS)
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ else
+ g_dbus_method_invocation_return_error (
+ invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to prepare network execution");
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "NetworkDestroy") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+
+ g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle);
+ if (ctx_handle > 0 && nw_handle > 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->network_destroy (
+ device, ctx_handle, nw_handle);
+ if (status == NPUMGR_STATUS_SUCCESS)
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ else
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the network");
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "QueryNetwork") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+
+ g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle);
+ if (ctx_handle > 0 && nw_handle > 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ npumgr_query_inout_num data;
+ status = NPUMGR_DEVICE_GET_CLASS (device)->query_network (
+ device, ctx_handle, nw_handle, &data);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(uu)", data.n_input, data.n_output));
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the network");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "QueryInput") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+ int index = -1;
+
+ g_variant_get (parameters, "(tti)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle, &index);
+ if (ctx_handle > 0 && nw_handle > 0 && index >= 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ npumgr_query_tensor_attr data;
+ status = NPUMGR_DEVICE_GET_CLASS (device)->query_input (
+ device, ctx_handle, nw_handle, index, &data);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ GBytes *bytes = g_bytes_new (&data, sizeof (data));
+ GVariant *variant =
+ g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(v)", variant));
+ g_bytes_unref (bytes);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to find input attr");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "QueryOutput") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+ int index = -1;
+
+ g_variant_get (parameters, "(tti)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle, &index);
+ if (ctx_handle > 0 && nw_handle > 0 && index >= 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ npumgr_query_tensor_attr data;
+ status = NPUMGR_DEVICE_GET_CLASS (device)->query_output (
+ device, ctx_handle, nw_handle, index, &data);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ GBytes *bytes = g_bytes_new (&data, sizeof (data));
+ GVariant *variant =
+ g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(v)", variant));
+ g_bytes_unref (bytes);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to find output attr");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "BufferCreate") == 0) {
+ npumgr_context ctx_handle = 0;
+ GVariant *variant = NULL;
+
+ g_variant_get (parameters, "(tv)", (guint64 *) &ctx_handle, &variant);
+ if (ctx_handle > 0 && variant != NULL) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_query_tensor_attr param;
+ npumgr_buffer buf;
+ npumgr_status_e status;
+
+ GBytes *bytes = g_variant_get_data_as_bytes (variant);
+ if (g_bytes_get_size (bytes) != sizeof (param)) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments detected");
+ g_bytes_unref (bytes);
+ return;
+ }
+
+ memcpy (¶m, g_bytes_get_data (bytes, NULL), sizeof (param));
+ g_bytes_unref (bytes);
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->buffer_create (
+ device, ctx_handle, ¶m, &buf);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ bytes = g_bytes_new (&buf, sizeof (buf));
+ variant =
+ g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_method_invocation_return_value (
+ invocation, g_variant_new ("(v)", variant));
+ g_bytes_unref (bytes);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to create buffer");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "BufferMap") == 0) {
+ npumgr_context ctx_handle = 0;
+ GVariant *variant = NULL;
+
+ g_variant_get (parameters, "(tv)", (guint64 *) &ctx_handle, &variant);
+ if (ctx_handle > 0 && variant != NULL) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_buffer buf;
+ uint8_t *addr;
+ npumgr_status_e status;
+
+ GBytes *bytes = g_variant_get_data_as_bytes (variant);
+ if (g_bytes_get_size (bytes) != sizeof (buf)) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments detected");
+ g_bytes_unref (bytes);
+ return;
+ }
+
+ memcpy (&buf, g_bytes_get_data (bytes, NULL), sizeof (buf));
+ g_bytes_unref (bytes);
+
+ /* TODO: how to deliver this addr to client? */
+ status = NPUMGR_DEVICE_GET_CLASS (device)->buffer_map (
+ device, ctx_handle, &buf, &addr);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ GUnixFDList *fd_list = g_unix_fd_list_new ();
+ g_unix_fd_list_append (fd_list, buf.buf_fd, NULL);
+
+ bytes = g_bytes_new (&buf, sizeof (buf));
+ variant =
+ g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_method_invocation_return_value_with_unix_fd_list (
+ invocation, g_variant_new ("(v)", variant), fd_list);
+ g_bytes_unref (bytes);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to map buffer");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "BufferDestroy") == 0) {
+ npumgr_context ctx_handle = 0;
+ GVariant *variant = NULL;
+
+ g_variant_get (parameters, "(tv)", (guint64 *) &ctx_handle, &variant);
+ if (ctx_handle > 0 && variant != NULL) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_buffer buf;
+ npumgr_status_e status;
+
+ GBytes *bytes = g_variant_get_data_as_bytes (variant);
+ if (g_bytes_get_size (bytes) != sizeof (buf)) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments detected");
+ g_bytes_unref (bytes);
+ return;
+ }
+
+ memcpy (&buf, g_bytes_get_data (bytes, NULL), sizeof (buf));
+ g_bytes_unref (bytes);
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->buffer_destroy (
+ device, ctx_handle, &buf);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to destroy buffer");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "ExecuteTrigger") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+
+ g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle);
+ if (ctx_handle > 0 && nw_handle > 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->execute_trigger (
+ device, ctx_handle, nw_handle);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to execute network");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "ExecuteWait") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+
+ g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle);
+ if (ctx_handle > 0 && nw_handle > 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->execute_wait (
+ device, ctx_handle, nw_handle);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to finish execution");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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, "ExecuteRun") == 0) {
+ npumgr_context ctx_handle = 0;
+ npumgr_network nw_handle = 0;
+
+ g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
+ (guint64 *) &nw_handle);
+ if (ctx_handle > 0 && nw_handle > 0) {
+ NpumgrContext *context = find_context (ctx_handle);
+ if (context != NULL) {
+ NpumgrDevice *device = context->device;
+ npumgr_status_e status;
+
+ status = NPUMGR_DEVICE_GET_CLASS (device)->execute_run (
+ device, ctx_handle, nw_handle);
+ if (status == NPUMGR_STATUS_SUCCESS) {
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Unable to execute network");
+ }
+ } else {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_UNKNOWN_OBJECT,
+ "Unable to find the context");
+ }
+ } 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)
+ loge ("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) {
+ loge ("Unable to acquire name %s", name);
+ exit (EXIT_FAILURE);
+}
+
+/**
+ * @brief Destroy callback for freeing context instance
+ */
+static void
+ctx_destroy (gpointer data) {
+ NpumgrContext *ctx = static_cast<NpumgrContext *> (data);
+ NpumgrDevice *device;
+
+ g_return_if_fail (ctx != NULL);
+
+ device = ctx->device;
+ NPUMGR_DEVICE_GET_CLASS (device)->context_destroy (device, ctx->handle);
+
+ g_free (ctx);
+}
+
+static void
+plugin_pdata_free (gpointer *data) {
+ plugin_pdata *pdata = (plugin_pdata *) data;
+
+ g_module_close (pdata->module);
+ g_object_unref (pdata->device);
+ g_free (pdata);
+}
+
+/**
+ * @brief Initialize plugins
+ */
+static void
+init_plugins (void) {
+ typedef NpumgrDevice *(*NewFunc) (void);
+ GModule *module;
+ NewFunc func;
+
+ registered_plugins = NULL;
+
+ for (auto &name : supported_plugins) {
+ gchar *module_name = g_strdup_printf ("libnpumgr_%s", name);
+ module = g_module_open (module_name, G_MODULE_BIND_LAZY);
+ if (!module) {
+ logw ("Unable to open plugin %s", module_name);
+ g_free (module_name);
+ continue;
+ }
+ g_free (module_name);
+
+ gchar *module_symbol = g_strdup_printf ("npumgr_device_%s_new", name);
+ if (!g_module_symbol (module, module_symbol, (gpointer *) &func)) {
+ logw ("Unable to find symbol %s", module_symbol);
+ g_free (module_symbol);
+ continue;
+ }
+ g_free (module_symbol);
+
+ plugin_pdata *pdata = g_new0 (plugin_pdata, 1);
+ registered_plugins = g_slist_append (registered_plugins, pdata);
+
+ pdata->name = name;
+ pdata->module = module;
+ pdata->device = func ();
+ pdata->id = g_slist_index (registered_plugins, pdata);
+ }
+}
+
+/**
+ * @brief Main routine for gdbus-based npumgr daemon
+ */
+static int
+start_npumgr (void) {
+ 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) {
+ loge ("Failed to build the introspection data structure");
+ return -1;
+ }
+
+ init_plugins ();
+
+ ctx_table =
+ g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, ctx_destroy);
+ owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, "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);
+
+ g_hash_table_destroy (ctx_table);
+ g_slist_free_full (registered_plugins, (GDestroyNotify) plugin_pdata_free);
+
+ logi ("Stopping %s", NPUMGR_DAEMON_NAME);
+ return 0;
+}
+
+/**
+ * @brief Daemonize the program
+ */
+int
+main (int argc, char *argv[]) {
+ pid_t pid, sid;
+
+ pid = fork ();
+ if (pid > 0)
+ exit (EXIT_SUCCESS);
+ else if (pid < 0)
+ exit (EXIT_FAILURE);
+
+ umask (0);
+
+#ifndef __TIZEN__
+ openlog (NPUMGR_DAEMON_NAME, LOG_NOWAIT | LOG_PID, LOG_USER);
+#endif
+
+ sid = setsid ();
+ if (sid < 0) {
+ loge ("Unable to generate session ID for child process");
+ exit (EXIT_FAILURE);
+ }
+
+ if ((chdir ("/")) < 0) {
+ loge ("Unable to change the working directory");
+ exit (EXIT_FAILURE);
+ }
+
+ close (STDIN_FILENO);
+ close (STDOUT_FILENO);
+ close (STDERR_FILENO);
+
+ logi ("Starting %s", NPUMGR_DAEMON_NAME);
+
+ return start_npumgr ();
+}
--- /dev/null
+/**
+ * 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 <npumgr_common.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <gio/gio.h>
+#include <gio/gunixfdlist.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;
+static gboolean _running;
+
+/**
+ * @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) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GError *error = NULL;
+
+ g_return_val_if_fail (pdev != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ 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",
+ "DeviceGetAvailableList");
+ g_dbus_message_set_body (method_call, NULL);
+
+ 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;
+ }
+
+ {
+ GVariantIter *iter_type;
+ GVariantIter *iter_id;
+ uint32_t idx;
+
+ g_variant_get (g_dbus_message_get_body (method_reply), "(uaiau)",
+ &pdev->n_devices, &iter_type, &iter_id);
+
+ if (pdev->n_devices > NPUMGR_MAX_DEVICES) {
+ g_critical ("Too many devices: %u", pdev->n_devices);
+ status = NPUMGR_STATUS_ERR_FAIL;
+ goto out_iter;
+ }
+
+ idx = 0;
+ while (idx < NPUMGR_MAX_DEVICES &&
+ g_variant_iter_loop (iter_type, "i", &pdev->types[idx++]))
+ ;
+
+ idx = 0;
+ while (idx < NPUMGR_MAX_DEVICES &&
+ g_variant_iter_loop (iter_id, "u", &pdev->id[idx++]))
+ ;
+
+ out_iter:
+ g_variant_iter_free (iter_type);
+ g_variant_iter_free (iter_id);
+ }
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @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 *in_tensor_names,
+ npumgr_buffer_t out_buffer_type, int out_tensor_cnt,
+ const char *const *out_tensor_names,
+ npumgr_network *out_nw_handle) {
+ 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",
+ "NetworkCreate");
+
+ GVariantBuilder builder, builder_arr;
+ GUnixFDList *fd_list;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(tiatiiviiv)"));
+ g_variant_builder_init (&builder_arr, G_VARIANT_TYPE ("at"));
+
+ fd_list = g_unix_fd_list_new ();
+
+ /* build message body */
+ g_variant_builder_add (&builder, "t", ctx);
+ g_variant_builder_add (&builder, "i", num_files);
+ for (int i = 0; i < num_files; i++) {
+ g_unix_fd_list_append (fd_list, input_files[i].fd, NULL);
+ g_variant_builder_add (&builder_arr, "t", ((uint64_t *) input_files)[i]);
+ }
+ g_dbus_message_set_unix_fd_list (method_call, fd_list);
+
+ g_variant_builder_add_value (&builder, g_variant_builder_end (&builder_arr));
+ g_variant_builder_add (&builder, "i", in_buffer_type);
+ g_variant_builder_add (&builder, "i", in_tensor_cnt);
+ g_variant_builder_add (&builder, "v",
+ g_variant_new_strv (in_tensor_names, in_tensor_cnt));
+ g_variant_builder_add (&builder, "i", out_buffer_type);
+ g_variant_builder_add (&builder, "i", out_tensor_cnt);
+ g_variant_builder_add (&builder, "v",
+ g_variant_new_strv (out_tensor_names, out_tensor_cnt));
+
+ g_dbus_message_set_body (method_call, g_variant_builder_end (&builder));
+ 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_nw_handle);
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @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) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GBytes *bytes;
+ GVariant *variant;
+ 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",
+ "NetworkSetInput");
+
+ bytes = g_bytes_new (input_buffer, sizeof (*input_buffer));
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_message_set_body (
+ method_call, g_variant_new ("(ttiv)", ctx, nw_handle, index, variant));
+
+ 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 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) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GBytes *bytes;
+ GVariant *variant;
+ 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",
+ "NetworkSetOutput");
+
+ bytes = g_bytes_new (output_buffer, sizeof (*output_buffer));
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_message_set_body (
+ method_call, g_variant_new ("(ttiv)", ctx, nw_handle, index, variant));
+
+ 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 preparing network and making it ready to run on hardware.
+ */
+npumgr_status_e
+npumgr_network_prepare (npumgr_context ctx, npumgr_network nw_handle) {
+ 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",
+ "NetworkPrepare");
+ g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
+
+ 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 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) {
+ 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",
+ "NetworkDestroy");
+ g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
+
+ 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 buffer creation.
+ */
+npumgr_status_e
+npumgr_buffer_create (npumgr_context ctx,
+ npumgr_query_tensor_attr *create_param,
+ npumgr_buffer *buf) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GError *error = NULL;
+ GVariant *variant;
+ GBytes *bytes;
+
+ 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",
+ "BufferCreate");
+
+ bytes = g_bytes_new (create_param, sizeof (*create_param));
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_message_set_body (method_call, g_variant_new ("(tv)", ctx, variant));
+
+ method_reply = g_dbus_connection_send_message_with_reply_sync (
+ _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
+ &error);
+
+ g_bytes_unref (bytes);
+
+ 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), "(v)", &variant);
+ bytes = g_variant_get_data_as_bytes (variant);
+
+ if (g_bytes_get_size (bytes) != sizeof (*buf)) {
+ status = NPUMGR_STATUS_ERR_FAIL;
+ goto out_unref;
+ }
+
+ memcpy (buf, g_bytes_get_data (bytes, NULL), sizeof (*buf));
+
+out_unref:
+ g_bytes_unref (bytes);
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @brief This API helps in destroying the creatd buffer.
+ */
+npumgr_status_e
+npumgr_buffer_destroy (npumgr_context ctx, npumgr_buffer *buf) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GError *error = NULL;
+ GVariant *variant;
+ GBytes *bytes;
+
+ 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",
+ "BufferDestroy");
+
+ bytes = g_bytes_new (buf, sizeof (*buf));
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_message_set_body (method_call, g_variant_new ("(tv)", ctx, variant));
+
+ method_reply = g_dbus_connection_send_message_with_reply_sync (
+ _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
+ &error);
+
+ g_bytes_unref (bytes);
+
+ 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 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) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GError *error = NULL;
+ GVariant *variant;
+ GBytes *bytes;
+ GUnixFDList *fd_list;
+
+ 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",
+ "BufferMap");
+
+ bytes = g_bytes_new (buf, sizeof (*buf));
+ variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
+ g_dbus_message_set_body (method_call, g_variant_new ("(tv)", ctx, variant));
+
+ method_reply = g_dbus_connection_send_message_with_reply_sync (
+ _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
+ &error);
+
+ g_bytes_unref (bytes);
+
+ 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), "(v)", &variant);
+ bytes = g_variant_get_data_as_bytes (variant);
+
+ if (g_bytes_get_size (bytes) != sizeof (*buf)) {
+ status = NPUMGR_STATUS_ERR_FAIL;
+ goto out_unref;
+ }
+
+ memcpy (buf, g_bytes_get_data (bytes, NULL), sizeof (*buf));
+
+ fd_list = g_dbus_message_get_unix_fd_list (method_reply);
+ buf->buf_fd = g_unix_fd_list_get (fd_list, 0, NULL);
+
+ *mapped_addr =
+ (uint8_t *) mmap (NULL, ALIGNED_SIZE (buf->buf_size),
+ PROT_READ | PROT_WRITE, MAP_SHARED, buf->buf_fd, 0);
+ if (*mapped_addr == MAP_FAILED)
+ status = NPUMGR_STATUS_ERR_FAIL;
+
+out_unref:
+ g_bytes_unref (bytes);
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @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) {
+ 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",
+ "QueryNetwork");
+ g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
+
+ 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), "(uu)", &data->n_input,
+ &data->n_output);
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @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) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GError *error = NULL;
+ GVariant *variant;
+ GBytes *bytes;
+
+ 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",
+ "QueryInput");
+ g_dbus_message_set_body (method_call,
+ g_variant_new ("(tti)", ctx, nw_handle, index));
+
+ 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), "(v)", &variant);
+ bytes = g_variant_get_data_as_bytes (variant);
+
+ if (g_bytes_get_size (bytes) != sizeof (*data)) {
+ status = NPUMGR_STATUS_ERR_FAIL;
+ goto out_unref;
+ }
+
+ memcpy (data, g_bytes_get_data (bytes, NULL), sizeof (*data));
+
+out_unref:
+ g_bytes_unref (bytes);
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @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) {
+ GDBusMessage *method_call;
+ GDBusMessage *method_reply;
+ npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
+ GError *error = NULL;
+ GVariant *variant;
+ GBytes *bytes;
+
+ 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",
+ "QueryOutput");
+ g_dbus_message_set_body (method_call,
+ g_variant_new ("(tti)", ctx, nw_handle, index));
+
+ 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), "(v)", &variant);
+ bytes = g_variant_get_data_as_bytes (variant);
+
+ if (g_bytes_get_size (bytes) != sizeof (*data)) {
+ status = NPUMGR_STATUS_ERR_FAIL;
+ goto out_unref;
+ }
+
+ memcpy (data, g_bytes_get_data (bytes, NULL), sizeof (*data));
+
+out_unref:
+ g_bytes_unref (bytes);
+
+out:
+ g_object_unref (method_call);
+ g_object_unref (method_reply);
+
+ return status;
+}
+
+/**
+ * @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) {
+ 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",
+ "ExecuteTrigger");
+ g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
+
+ 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 explicitly wait for HW to finish executing the submitted commands.
+ */
+npumgr_status_e
+npumgr_execute_wait (npumgr_context ctx, npumgr_network nw_handle) {
+ 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",
+ "ExecuteWait");
+ g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
+
+ 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 running the network.
+ */
+npumgr_status_e
+npumgr_execute_run (npumgr_context ctx, npumgr_network nw_handle) {
+ 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",
+ "ExecuteRun");
+ g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
+
+ 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 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_SYSTEM, "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_mutex_lock (&_mutex);
+ _running = TRUE;
+ g_cond_broadcast (&_cond);
+ g_mutex_unlock (&_mutex);
+
+ 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;
+ _running = FALSE;
+ _thread = g_thread_new (NULL, npumgr_thread, NULL);
+}
+
+/**
+ * @brief Destructor of npumgr APi library
+ */
+void
+fini_npumgr_api (void) {
+ if (_thread) {
+ gint64 end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
+
+ g_mutex_lock (&_mutex);
+ if (_running == FALSE)
+ g_cond_wait_until (&_cond, &_mutex, end_time);
+ g_main_loop_quit (_loop);
+ g_mutex_unlock (&_mutex);
+
+ g_thread_join (_thread);
+ }
+}
--- /dev/null
+/**
+* @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_FILE_TVN, /**< Trinity Vision NPU */
+
+ 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_BUF_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__ */
--- /dev/null
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr_device.cc
+ * @date 03 May 2021
+ * @brief a parent class (dummy) of VD NPU Manager device.
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include "npumgr_device.h"
+
+G_DEFINE_TYPE (NpumgrDevice, npumgr_device, G_TYPE_OBJECT);
+
+static void
+npumgr_device_class_init (NpumgrDeviceClass *klass) {
+ /* NYI */
+}
+
+static void
+npumgr_device_init (NpumgrDevice *self) {
+ /* NYI */
+}
--- /dev/null
+#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
--- /dev/null
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr_triv2.cc
+ * @date 03 May 2021
+ * @brief TRIV2 device plugin of VD NPU Manager
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include "npumgr_triv2.h"
+
+/* npu-engine API */
+#include <libnpuhost.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <vector>
+
+extern "C" {
+NpumgrDevice *npumgr_device_triv2_new (void);
+}
+
+typedef struct {
+ GMutex mutex;
+ GCond cond;
+ gboolean done;
+} async_cb_priv;
+
+void
+async_cb (output_buffers *output, int req_id, void *data) {
+ async_cb_priv *priv = (async_cb_priv *) data;
+
+ g_mutex_lock (&priv->mutex);
+ /* as output is dmabuf, don't need to perform memcpy */
+ priv->done = TRUE;
+ g_cond_broadcast (&priv->cond);
+ g_mutex_unlock (&priv->mutex);
+}
+
+/**
+ * @brief Class for triv2 npumgr buffer
+ */
+class NpumgrBufferTriv2 {
+ public:
+ NpumgrBufferTriv2 (const generic_buffer &gbuf) {
+ handle_ = g_atomic_int_add (&g_buf_handle, 1);
+ memcpy (&gbuf_, &gbuf, sizeof (gbuf));
+ quant_type_ = NPUMGR_TENSOR_QNT_MAX;
+ }
+
+ int getDbufFD () const { return gbuf_.dmabuf; }
+ size_t getSize () const { return gbuf_.size; }
+ void *getData () const { return gbuf_.addr; }
+ npumgr_buffer_h getHandle () const { return handle_; }
+ generic_buffer *getGenericBuffer () { return &gbuf_; }
+
+ void setDataFmt (const npumgr_tensor_fmt_t &fmt) { data_fmt_ = fmt; }
+ void setDataType (const npumgr_tensor_data_t &type) { data_type_ = type; }
+ void setQuantType (const npumgr_tensor_qnt_t &type) { quant_type_ = type; }
+
+ const npumgr_tensor_fmt_t &getDataFmt () const { return data_fmt_; }
+ const npumgr_tensor_data_t &getDataType () const { return data_type_; }
+ const npumgr_tensor_qnt_t &getQuantType () const { return quant_type_; }
+
+ private:
+ static volatile guint g_buf_handle;
+
+ npumgr_buffer_h handle_;
+ generic_buffer gbuf_;
+
+ npumgr_tensor_fmt_t data_fmt_;
+ npumgr_tensor_data_t data_type_;
+ npumgr_tensor_qnt_t quant_type_;
+};
+
+static data_layout
+convert_layout (const npumgr_tensor_fmt_t &fmt) {
+ data_layout layout;
+
+ /* unknown, relying on the model */
+ layout = DATA_LAYOUT_MODEL;
+ switch (fmt) {
+ case NPUMGR_TENSOR_FMT_NCHW:
+ layout = DATA_LAYOUT_NCHW;
+ break;
+ case NPUMGR_TENSOR_FMT_NHWC:
+ layout = DATA_LAYOUT_NHWC;
+ break;
+ default:
+ break;
+ }
+
+ return layout;
+}
+
+static data_type
+convert_type (const npumgr_tensor_data_t &data,
+ const npumgr_tensor_qnt_t &qnt) {
+ data_type type;
+
+ /* unknown, relying on the model */
+ type = DATA_TYPE_MODEL;
+ switch (data) {
+ case NPUMGR_TENSOR_DATA_FLOAT32:
+ type = DATA_TYPE_FLOAT32;
+ break;
+ case NPUMGR_TENSOR_DATA_INT8:
+ type = DATA_TYPE_INT8;
+ break;
+ case NPUMGR_TENSOR_DATA_UINT8:
+ type = DATA_TYPE_UINT8;
+ break;
+ case NPUMGR_TENSOR_DATA_INT16:
+ type = DATA_TYPE_INT16;
+ break;
+ case NPUMGR_TENSOR_DATA_UINT16:
+ type = DATA_TYPE_UINT16;
+ break;
+ default:
+ break;
+ }
+
+ if (qnt == NPUMGR_TENSOR_QNT_AFFINE_ASYMM)
+ type = DATA_TYPE_QASYMM8;
+
+ return type;
+}
+
+static gsize
+calc_data_size (const npumgr_tensor_data_t type) {
+ switch (type) {
+ case NPUMGR_TENSOR_DATA_FLOAT32:
+ return 4;
+ case NPUMGR_TENSOR_DATA_FLOAT16:
+ return 2;
+ case NPUMGR_TENSOR_DATA_INT8:
+ return 1;
+ case NPUMGR_TENSOR_DATA_UINT8:
+ return 1;
+ case NPUMGR_TENSOR_DATA_INT16:
+ return 2;
+ case NPUMGR_TENSOR_DATA_UINT16:
+ return 2;
+ case NPUMGR_TENSOR_DATA_UINT24:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * @brief Class for triv2 npumgr network
+ */
+class NpumgrNetworkTriv2 {
+ public:
+ NpumgrNetworkTriv2 (npudev_h dev, const npumgr_network_defn &model_file)
+ : dev_ (dev),
+ model_id_ (0),
+ model_file_ (model_file),
+ in_buffer_type_ (NPUMGR_BUF_TYPE_MAX),
+ out_buffer_type_ (NPUMGR_BUF_TYPE_MAX),
+ in_tensor_names_ (NULL),
+ out_tensor_names_ (NULL),
+ async_ (FALSE) {
+ handle_ = g_atomic_int_add (&g_nw_handle, 1);
+ meta_ = (npubin_meta *) g_new0 (npubin_meta, 1);
+ model_file_ = model_file;
+ in_buffers_.num_buffers = 0;
+ out_buffers_.num_buffers = 0;
+
+ memset (&in_info_, '\x00', sizeof (in_info_));
+ memset (&out_info_, '\x00', sizeof (out_info_));
+
+ timeout_ = default_timeout;
+ g_mutex_init (&async_priv_.mutex);
+ g_cond_init (&async_priv_.cond);
+ async_priv_.done = FALSE;
+ }
+ ~NpumgrNetworkTriv2 () {
+ if (model_id_ > 0)
+ unregisterNPUmodel (dev_, model_id_);
+
+ close (model_file_.fd);
+ g_strfreev (in_tensor_names_);
+ g_strfreev (out_tensor_names_);
+ g_free (meta_);
+ }
+
+ /** @brief set input buffer type */
+ void setInBufferType (npumgr_buffer_t type) { in_buffer_type_ = type; }
+ /** @brief set input tensor names */
+ void setInTensorNames (gchar **in_tensor_names) {
+ in_tensor_names_ = g_strdupv (in_tensor_names);
+ }
+ gboolean loadModel () {
+ generic_buffer model = {0};
+
+ if (lseek (model_file_.fd, 0, SEEK_SET) < 0)
+ return FALSE;
+
+ if (read (model_file_.fd, (void *) meta_, NPUBIN_META_SIZE) !=
+ NPUBIN_META_SIZE)
+ return FALSE;
+
+ if (meta_->size <= NPUBIN_META_SIZE)
+ return FALSE;
+
+ model.type = BUFFER_FILE;
+ model.fd = model_file_.fd;
+ model.size = meta_->size;
+
+ if (registerNPUmodel (dev_, &model, &model_id_) != 0) {
+ return FALSE;
+ }
+
+ in_buffers_.num_buffers = getInTensorCnt ();
+ out_buffers_.num_buffers = getOutTensorCnt ();
+
+ in_info_.num_info = getInTensorCnt ();
+ out_info_.num_info = getOutTensorCnt ();
+
+ return TRUE;
+ }
+
+ /** @brief set output buffer type */
+ void setOutBufferType (npumgr_buffer_t type) { out_buffer_type_ = type; }
+ /** @brief set output tensor names */
+ void setOutTensorNames (gchar **out_tensor_names) {
+ out_tensor_names_ = g_strdupv (out_tensor_names);
+ }
+
+ /** @brief get input tensor name */
+ const gchar *getInTensorName (gint idx) { return in_tensor_names_[idx]; }
+ /** @brief get output tensor name */
+ const gchar *getOutTensorName (gint idx) { return out_tensor_names_[idx]; }
+
+ guint getInTensorCnt () { return meta_->input_seg_num; }
+ guint getOutTensorCnt () { return meta_->output_seg_num; }
+
+ /** @brief get network handle */
+ npumgr_network getHandle () { return handle_; }
+
+ guint getInTensorDim (guint i, guint j) {
+ return meta_->input_seg_dims[i][j];
+ }
+ guint getInTensorSize (guint i, npumgr_tensor_fmt_t fmt,
+ npumgr_tensor_data_t type) {
+ guint size;
+
+ if (fmt == NPUMGR_TENSOR_FMT_NHWC || fmt == NPUMGR_TENSOR_FMT_NCHW) {
+ size = calc_data_size (type);
+ for (int j = 0; j < MAX_RANK; j++) size *= meta_->input_seg_dims[i][j];
+ } else {
+ int status;
+
+ status = getNPUmodel_tensorSize (dev_, model_id_, true, i, &size);
+ if (status != 0)
+ return 0;
+ }
+ return size;
+ }
+ int32_t getInTensorQuantZero (guint i) { return meta_->input_seg_quant_z[i]; }
+ float getInTensorQuantScale (guint i) { return meta_->input_seg_quant_s[i]; }
+
+ guint getOutTensorDim (gint i, gint j) {
+ return meta_->output_seg_dims[i][j];
+ }
+ guint getOutTensorSize (guint i, npumgr_tensor_fmt_t fmt,
+ npumgr_tensor_data_t type) {
+ guint size;
+
+ if (fmt == NPUMGR_TENSOR_FMT_NHWC || fmt == NPUMGR_TENSOR_FMT_NCHW) {
+ size = calc_data_size (type);
+ for (int j = 0; j < MAX_RANK; j++) size *= meta_->output_seg_dims[i][j];
+ } else {
+ int status;
+
+ status = getNPUmodel_tensorSize (dev_, model_id_, false, i, &size);
+ if (status != 0)
+ return 0;
+ }
+ return size;
+ }
+ int32_t getOutTensorQuantZero (gint i) {
+ return meta_->output_seg_quant_z[i];
+ }
+ float getOutTensorQuantScale (gint i) { return meta_->output_seg_quant_s[i]; }
+
+ gboolean setInput (gint index, NpumgrBufferTriv2 *buffer) {
+ if (index >= in_buffers_.num_buffers)
+ return FALSE;
+
+ in_info_.info[index].layout = convert_layout (buffer->getDataFmt ());
+ in_info_.info[index].type =
+ convert_type (buffer->getDataType (), buffer->getQuantType ());
+
+ memcpy (&in_buffers_.bufs[index], buffer->getGenericBuffer (),
+ sizeof (generic_buffer));
+ return TRUE;
+ }
+
+ gboolean setOutput (gint index, NpumgrBufferTriv2 *buffer) {
+ if (index >= out_buffers_.num_buffers)
+ return FALSE;
+
+ out_info_.info[index].layout = convert_layout (buffer->getDataFmt ());
+ out_info_.info[index].type =
+ convert_type (buffer->getDataType (), buffer->getQuantType ());
+
+ memcpy (&out_buffers_.bufs[index], buffer->getGenericBuffer (),
+ sizeof (generic_buffer));
+ return TRUE;
+ }
+
+ void setAsync (gboolean async) { async_ = async; }
+ gboolean isAsync () const { return async_; }
+
+ gboolean prepare () {
+ return (setNPU_dataInfo (dev_, model_id_, &in_info_, &out_info_) == 0);
+ }
+
+ gboolean execute () {
+ int req_id;
+
+ if (isAsync ()) {
+ async_priv_.done = FALSE;
+ req_id =
+ runNPU_model (dev_, model_id_, NPU_INFER_NON_BLOCKING, &in_buffers_,
+ &out_buffers_, async_cb, &async_priv_);
+ } else {
+ req_id = runNPU_model (dev_, model_id_, NPU_INFER_BLOCKING, &in_buffers_,
+ &out_buffers_, NULL, NULL);
+ }
+
+ return (req_id > 0);
+ }
+
+ gboolean wait () {
+ gint64 end_time;
+ gboolean result = TRUE;
+
+ end_time = g_get_monotonic_time () + timeout_ * G_TIME_SPAN_MILLISECOND;
+
+ g_mutex_lock (&async_priv_.mutex);
+ while (async_priv_.done != TRUE) {
+ if (!g_cond_wait_until (&async_priv_.cond, &async_priv_.mutex,
+ end_time)) {
+ result = FALSE;
+ break;
+ }
+ }
+ g_mutex_unlock (&async_priv_.mutex);
+ return result;
+ }
+
+ private:
+ static volatile guint g_nw_handle;
+
+ npudev_h dev_;
+
+ npumgr_network handle_;
+ uint32_t model_id_;
+
+ npumgr_network_defn model_file_;
+ npubin_meta *meta_;
+
+ npumgr_buffer_t in_buffer_type_;
+ npumgr_buffer_t out_buffer_type_;
+
+ gchar **in_tensor_names_;
+ gchar **out_tensor_names_;
+
+ input_buffers in_buffers_;
+ output_buffers out_buffers_;
+
+ tensors_data_info in_info_;
+ tensors_data_info out_info_;
+
+ gint64 timeout_;
+ gboolean async_;
+ async_cb_priv async_priv_;
+};
+
+static void
+nw_destroy (gpointer data) {
+ NpumgrNetworkTriv2 *nw = static_cast<NpumgrNetworkTriv2 *> (data);
+
+ delete nw;
+}
+
+static void
+buf_destroy (gpointer data) {
+ NpumgrBufferTriv2 *buf = static_cast<NpumgrBufferTriv2 *> (data);
+
+ delete buf;
+}
+
+/**
+ * @brief Class for triv2 npumgr context
+ */
+class NpumgrContextTriv2 {
+ public:
+ NpumgrContextTriv2 (npudev_h dev, int priority)
+ : dev_ (dev), priority_ (priority) {
+ handle_ = g_atomic_int_add (&g_ctx_handle, 1);
+ nw_table_ =
+ g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, nw_destroy);
+ buf_table_ = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
+ buf_destroy);
+ }
+
+ ~NpumgrContextTriv2 () {
+ g_hash_table_destroy (nw_table_);
+ g_hash_table_destroy (buf_table_);
+ }
+
+ npudev_h getDevice () const { return dev_; }
+
+ gboolean appendNetwork (npumgr_network handle, NpumgrNetworkTriv2 *nw) {
+ return g_hash_table_insert (nw_table_, GSIZE_TO_POINTER (handle), nw);
+ }
+ gboolean removeNetwork (npumgr_network handle) {
+ return g_hash_table_remove (nw_table_, GSIZE_TO_POINTER (handle));
+ }
+ NpumgrNetworkTriv2 *findNetwork (npumgr_network handle) {
+ return (NpumgrNetworkTriv2 *) g_hash_table_lookup (
+ nw_table_, GSIZE_TO_POINTER (handle));
+ }
+
+ gboolean executeNetwork (npumgr_network handle, gboolean async = FALSE) {
+ NpumgrNetworkTriv2 *nw = findNetwork (handle);
+
+ g_return_val_if_fail (nw != NULL, FALSE);
+
+ nw->setAsync (async);
+ return nw->execute ();
+ }
+
+ /* only after calling async execution */
+ gboolean waitNetwork (npumgr_network handle) {
+ NpumgrNetworkTriv2 *nw = findNetwork (handle);
+
+ g_return_val_if_fail (nw != NULL, FALSE);
+ g_return_val_if_fail (nw->isAsync (), FALSE);
+
+ return nw->wait ();
+ }
+
+ NpumgrBufferTriv2 *findBuffer (npumgr_buffer_h handle) {
+ return (NpumgrBufferTriv2 *) g_hash_table_lookup (
+ buf_table_, GSIZE_TO_POINTER (handle));
+ }
+
+ gboolean allocBuffer (npumgr_query_tensor_attr *param, npumgr_buffer *buf) {
+ generic_buffer gbuf = {0};
+
+ gbuf.type = BUFFER_MAPPED;
+ gbuf.size = param->size;
+
+ if (allocNPU_genericBuffer (dev_, &gbuf) != 0)
+ return FALSE;
+
+ NpumgrBufferTriv2 *nbuf = new NpumgrBufferTriv2 (gbuf);
+ nbuf->setDataFmt (param->fmt);
+ nbuf->setDataType (param->type);
+ nbuf->setQuantType (param->quant_type);
+
+ if (!g_hash_table_insert (buf_table_, GSIZE_TO_POINTER (nbuf->getHandle ()),
+ nbuf)) {
+ cleanNPU_genericBuffer (dev_, &gbuf);
+ delete nbuf;
+ return FALSE;
+ }
+
+ buf->buf_handle = nbuf->getHandle ();
+ buf->buf_fd = nbuf->getDbufFD ();
+ buf->buf_size = nbuf->getSize ();
+ buf->buf_offset = 0;
+
+ return TRUE;
+ }
+
+ gboolean destroyBuffer (npumgr_buffer *buf) {
+ NpumgrBufferTriv2 *nbuf = findBuffer (buf->buf_handle);
+ g_return_val_if_fail (nbuf != NULL, FALSE);
+
+ generic_buffer *gbuf = nbuf->getGenericBuffer ();
+ g_return_val_if_fail (gbuf != NULL, FALSE);
+
+ if (cleanNPU_genericBuffer (dev_, gbuf) != 0)
+ return FALSE;
+
+ return g_hash_table_remove (buf_table_, GSIZE_TO_POINTER (buf->buf_handle));
+ }
+
+ gboolean mapBuffer (npumgr_buffer *buf, uint8_t **mapped_addr) {
+ /* NYI */
+ return TRUE;
+ }
+
+ npumgr_context getHandle () { return handle_; }
+
+ private:
+ static volatile guint g_ctx_handle;
+
+ npumgr_context handle_;
+ npudev_h dev_;
+ int priority_;
+
+ GHashTable *nw_table_;
+ GHashTable *buf_table_;
+};
+
+static void
+ctx_destroy (gpointer data) {
+ NpumgrContextTriv2 *ctx = static_cast<NpumgrContextTriv2 *> (data);
+
+ delete ctx;
+}
+
+volatile guint NpumgrContextTriv2::g_ctx_handle = 1;
+volatile guint NpumgrNetworkTriv2::g_nw_handle = 1;
+volatile guint NpumgrBufferTriv2::g_buf_handle = 1;
+
+/**
+ * @brief Private members in NpumgrDeviceTriv2
+ */
+struct _NpumgrDeviceTriv2Private {
+ npudev_h dev;
+ GMutex mutex;
+ GHashTable *ctx_table;
+};
+
+#define NPUMGR_DEVICE(obj) &((obj)->parent)
+#define NPUMGR_DEVICE_TRIV2_GET_PRIVATE(obj) \
+ ((NpumgrDeviceTriv2Private *) g_type_instance_get_private ( \
+ (GTypeInstance *) obj, NPUMGR_TYPE_DEVICE_TRIV2))
+
+G_DEFINE_TYPE_WITH_PRIVATE (NpumgrDeviceTriv2, npumgr_device_triv2,
+ NPUMGR_TYPE_DEVICE);
+
+/* GObject */
+static void triv2_finalize (GObject *object);
+/* NpumgrDevice */
+static npumgr_status_e triv2_device_get_capabilities (
+ NpumgrDevice *device, guint *caps, npumgr_device_type_t *ptype);
+static npumgr_status_e triv2_context_create (NpumgrDevice *device,
+ int device_id, int priority,
+ npumgr_context *out_ctx);
+static npumgr_status_e triv2_context_destroy (NpumgrDevice *device,
+ npumgr_context ctx);
+static npumgr_status_e triv2_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);
+static npumgr_status_e triv2_network_set_input (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle,
+ int index,
+ npumgr_buffer *input_buffer);
+static npumgr_status_e triv2_network_set_output (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle,
+ int index,
+ npumgr_buffer *output_buffer);
+static npumgr_status_e triv2_network_prepare (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle);
+static npumgr_status_e triv2_network_destroy (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle);
+static npumgr_status_e triv2_buffer_create (
+ NpumgrDevice *device, npumgr_context ctx,
+ npumgr_query_tensor_attr *create_param, npumgr_buffer *buf);
+static npumgr_status_e triv2_buffer_destroy (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_buffer *buf);
+static npumgr_status_e triv2_buffer_map (NpumgrDevice *device,
+ npumgr_context ctx, npumgr_buffer *buf,
+ uint8_t **mapped_addr);
+static npumgr_status_e triv2_buffer_unmap (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_buffer *buf);
+
+static npumgr_status_e triv2_query_network (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle,
+ npumgr_query_inout_num *data);
+static npumgr_status_e triv2_query_input (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle, int index,
+ npumgr_query_tensor_attr *data);
+static npumgr_status_e triv2_query_output (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle, int index,
+ npumgr_query_tensor_attr *data);
+static npumgr_status_e triv2_execute_trigger (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle);
+static npumgr_status_e triv2_execute_wait (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle);
+static npumgr_status_e triv2_execute_run (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle);
+
+static npumgr_status_e triv2_execute_realtime (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle,
+ uint32_t task_handle,
+ uint32_t subtask_id);
+static npumgr_status_e triv2_execute_wait_realtime (NpumgrDevice *device,
+ npumgr_context ctx,
+ npumgr_network nw_handle,
+ uint32_t *golden_val,
+ uint32_t **golden_addr);
+static npumgr_status_e triv2_execute_completed_realtime (
+ NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
+
+extern NpumgrDevice *
+npumgr_device_triv2_new (void) {
+ gpointer instance = g_object_new (NPUMGR_TYPE_DEVICE_TRIV2, NULL);
+
+ return NPUMGR_DEVICE ((NpumgrDeviceTriv2 *) instance);
+}
+
+static void
+npumgr_device_triv2_class_init (NpumgrDeviceTriv2Class *klass) {
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ NpumgrDeviceClass *npumgr_device_class = &(klass->parent_class);
+
+ /* GObject */
+ gobject_class->finalize = triv2_finalize;
+ /* NpumgrDevice */
+ npumgr_device_class->device_get_capabilities = triv2_device_get_capabilities;
+ npumgr_device_class->context_create = triv2_context_create;
+ npumgr_device_class->context_destroy = triv2_context_destroy;
+ npumgr_device_class->network_create = triv2_network_create;
+ npumgr_device_class->network_set_input = triv2_network_set_input;
+ npumgr_device_class->network_set_output = triv2_network_set_output;
+ npumgr_device_class->network_prepare = triv2_network_prepare;
+ npumgr_device_class->network_destroy = triv2_network_destroy;
+ npumgr_device_class->buffer_create = triv2_buffer_create;
+ npumgr_device_class->buffer_destroy = triv2_buffer_destroy;
+ npumgr_device_class->buffer_map = triv2_buffer_map;
+ npumgr_device_class->buffer_unmap = triv2_buffer_unmap;
+ npumgr_device_class->query_network = triv2_query_network;
+ npumgr_device_class->query_input = triv2_query_input;
+ npumgr_device_class->query_output = triv2_query_output;
+
+ npumgr_device_class->execute_trigger = triv2_execute_trigger;
+ npumgr_device_class->execute_wait = triv2_execute_wait;
+ npumgr_device_class->execute_run = triv2_execute_run;
+ npumgr_device_class->execute_realtime = triv2_execute_realtime;
+ npumgr_device_class->execute_wait_realtime = triv2_execute_wait_realtime;
+ npumgr_device_class->execute_completed_realtime =
+ triv2_execute_completed_realtime;
+
+ /* NYI */
+}
+
+static void
+npumgr_device_triv2_init (NpumgrDeviceTriv2 *self) {
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+ int status;
+
+ memset (priv, '\x00', sizeof (*priv));
+ g_mutex_init (&priv->mutex);
+ priv->ctx_table =
+ g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, ctx_destroy);
+
+ /** TODO: How npumgr supports multiple TRIV2 devices? */
+ status = getNPUdeviceByTypeAny (&priv->dev, NPUCOND_TRIV2_CONN_SOCIP, 2);
+ if (status != 0) {
+ g_critical ("Unable to find/open 2-TOPS TRIV2 device\n");
+ return;
+ }
+}
+
+static void
+triv2_finalize (GObject *object) {
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (object);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ g_mutex_clear (&priv->mutex);
+ g_hash_table_destroy (priv->ctx_table);
+
+ if (priv->dev)
+ putNPUdevice (priv->dev);
+}
+
+/* Filling the virtual function table of TRIV2 */
+static npumgr_status_e
+triv2_device_get_capabilities (NpumgrDevice *device, guint *caps,
+ npumgr_device_type_t *ptype) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (caps != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ptype != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ g_return_val_if_fail (priv->dev != NULL,
+ NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE);
+
+ *caps = NPUMGR_DEVICE_CAPABILITY_MMAP |
+ NPUMGR_DEVICE_CAPABILITY_MULTICONTEXT | NPUMGR_DEVICE_CAPABILITY_MMU |
+ NPUMGR_DEVICE_CAPABILITY_REALTIME;
+ *ptype = NPUMGR_DEVICE_TYPE_NPU;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static gboolean
+insert_context (NpumgrDeviceTriv2Private *priv, npumgr_context handle,
+ NpumgrContextTriv2 *context) {
+ gboolean result;
+
+ g_mutex_lock (&priv->mutex);
+ result =
+ g_hash_table_insert (priv->ctx_table, GSIZE_TO_POINTER (handle), context);
+ g_mutex_unlock (&priv->mutex);
+
+ return result;
+}
+
+static gboolean
+remove_context (NpumgrDeviceTriv2Private *priv, npumgr_context handle) {
+ gboolean result;
+
+ g_mutex_lock (&priv->mutex);
+ result = g_hash_table_remove (priv->ctx_table, GSIZE_TO_POINTER (handle));
+ g_mutex_unlock (&priv->mutex);
+
+ return result;
+}
+
+static NpumgrContextTriv2 *
+find_context (NpumgrDeviceTriv2Private *priv, npumgr_context handle) {
+ NpumgrContextTriv2 *context;
+
+ g_mutex_lock (&priv->mutex);
+ context = (NpumgrContextTriv2 *) g_hash_table_lookup (
+ priv->ctx_table, GSIZE_TO_POINTER (handle));
+ g_mutex_unlock (&priv->mutex);
+
+ return context;
+}
+
+static npumgr_status_e
+triv2_context_create (NpumgrDevice *device, int device_id, int priority,
+ npumgr_context *ctx_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ g_return_val_if_fail (priv->dev != NULL,
+ NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE);
+
+ NpumgrContextTriv2 *context = new NpumgrContextTriv2 (priv->dev, priority);
+ *ctx_handle = context->getHandle ();
+
+ if (!insert_context (priv, context->getHandle (), context))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_context_destroy (NpumgrDevice *device, npumgr_context ctx_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ if (!remove_context (priv, ctx_handle))
+ return NPUMGR_STATUS_ERR_CTX_INVALID;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_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) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (num_files == 1, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (input_files != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (in_tensor_cnt != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (input_tensor_names != NULL,
+ NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (out_tensor_cnt != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (output_tensor_names != NULL,
+ NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (out_nw != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+ NpumgrContextTriv2 *context = find_context (priv, ctx);
+
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network =
+ new NpumgrNetworkTriv2 (context->getDevice (), input_files[0]);
+ if (!network->loadModel ())
+ goto err;
+ if (network->getInTensorCnt () != in_tensor_cnt)
+ goto err;
+ if (network->getOutTensorCnt () != out_tensor_cnt)
+ goto err;
+
+ network->setInTensorNames (input_tensor_names);
+ network->setOutTensorNames (output_tensor_names);
+ network->setInBufferType (in_buffer_type);
+ network->setOutBufferType (out_buffer_type);
+
+ if (context->appendNetwork (network->getHandle (), network)) {
+ *out_nw = network->getHandle ();
+ return NPUMGR_STATUS_SUCCESS;
+ }
+
+err:
+ delete network;
+ return NPUMGR_STATUS_ERR_FAIL;
+}
+
+static npumgr_status_e
+triv2_network_set_input (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle, int index,
+ npumgr_buffer *buf) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
+ g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
+ g_return_val_if_fail (network->getInTensorCnt () > index,
+ NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrBufferTriv2 *buffer = context->findBuffer (buf->buf_handle);
+ g_return_val_if_fail (buffer != NULL, NPUMGR_STATUS_ERR_FAIL);
+
+ if (!network->setInput (index, buffer))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_network_set_output (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle, int index,
+ npumgr_buffer *buf) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
+ g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
+ g_return_val_if_fail (network->getOutTensorCnt () > index,
+ NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrBufferTriv2 *buffer = context->findBuffer (buf->buf_handle);
+ g_return_val_if_fail (buffer != NULL, NPUMGR_STATUS_ERR_FAIL);
+
+ if (!network->setOutput (index, buffer))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_network_prepare (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
+ g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
+
+ if (!network->prepare ())
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_network_destroy (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->removeNetwork (nw_handle))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_buffer_create (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_query_tensor_attr *create_param,
+ npumgr_buffer *buf) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (create_param != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->allocBuffer (create_param, buf))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_buffer_destroy (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_buffer *buf) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->destroyBuffer (buf))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_buffer_map (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_buffer *buf, uint8_t **mapped_addr) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (mapped_addr != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->mapBuffer (buf, mapped_addr))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_buffer_unmap (NpumgrDevice *device, npumgr_context ctx,
+ npumgr_buffer *buf) {
+ /* NYI */
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_query_network (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle,
+ npumgr_query_inout_num *inout_num) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (inout_num != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
+ g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
+
+ inout_num->n_input = network->getInTensorCnt ();
+ inout_num->n_output = network->getOutTensorCnt ();
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_query_input (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle, int index,
+ npumgr_query_tensor_attr *attr) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (index >= 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (attr != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
+ g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
+
+ attr->n_dims = MAX_RANK;
+ for (guint rank = 0; rank < MAX_RANK; rank++)
+ attr->dims[rank] = network->getInTensorDim (index, rank);
+ g_snprintf (attr->name, NPUMGR_MAX_NAME_LEN, "%s",
+ network->getInTensorName (index));
+
+ /* FIXME: their exact meaning and usage? */
+ for (guint rank = 0; rank < MAX_RANK; rank++) attr->strides[rank] = 1;
+ attr->plane = 3;
+
+ attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
+ attr->type = NPUMGR_TENSOR_DATA_UINT8;
+ attr->size = network->getInTensorSize (index, attr->fmt, attr->type);
+
+ attr->quant_type = NPUMGR_TENSOR_QNT_AFFINE_ASYMM;
+ attr->quant_data.affine.scale = network->getInTensorQuantScale (index);
+ attr->quant_data.affine.zeroPoint = network->getInTensorQuantZero (index);
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_query_output (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle, int index,
+ npumgr_query_tensor_attr *attr) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (index >= 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (attr != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
+ g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
+
+ attr->n_dims = MAX_RANK;
+ for (guint rank = 0; rank < MAX_RANK; rank++)
+ attr->dims[rank] = network->getOutTensorDim (index, rank);
+ g_snprintf (attr->name, NPUMGR_MAX_NAME_LEN, "%s",
+ network->getOutTensorName (index));
+
+ /* FIXME: their exact meaning and usage? */
+ for (guint rank = 0; rank < MAX_RANK; rank++) attr->strides[rank] = 1;
+ attr->plane = 3;
+
+ attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
+ attr->type = NPUMGR_TENSOR_DATA_UINT8;
+ attr->size = network->getOutTensorSize (index, attr->fmt, attr->type);
+
+ attr->quant_type = NPUMGR_TENSOR_QNT_AFFINE_ASYMM;
+ attr->quant_data.affine.scale = network->getOutTensorQuantScale (index);
+ attr->quant_data.affine.zeroPoint = network->getOutTensorQuantZero (index);
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_execute_trigger (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->executeNetwork (nw_handle, TRUE))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_execute_wait (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->waitNetwork (nw_handle))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_execute_run (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle) {
+ g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+ g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
+
+ NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
+ NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
+ NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
+
+ g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
+
+ if (!context->executeNetwork (nw_handle))
+ return NPUMGR_STATUS_ERR_FAIL;
+
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_execute_realtime (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle, uint32_t task_handle,
+ uint32_t subtask_id) {
+ /* NYI */
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_execute_wait_realtime (NpumgrDevice *device, npumgr_context ctx_handle,
+ npumgr_network nw_handle, uint32_t *golden_val,
+ uint32_t **golden_addr) {
+ /* NYI */
+ return NPUMGR_STATUS_SUCCESS;
+}
+
+static npumgr_status_e
+triv2_execute_completed_realtime (NpumgrDevice *device,
+ npumgr_context ctx_handle,
+ npumgr_network nw_handle) {
+ /* NYI */
+ return NPUMGR_STATUS_SUCCESS;
+}
--- /dev/null
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file npumgr_triv2.h
+ * @date 03 May 2021
+ * @brief Internal header of TRIV2 device plugin
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#ifndef __NPUMGR_TRIV2_H__
+#define __NPUMGR_TRIV2_H__
+
+/* npumgr device API */
+#include <npumgr_device.h>
+
+G_BEGIN_DECLS
+
+#define NPUMGR_TYPE_DEVICE_TRIV2 (npumgr_device_triv2_get_type ())
+#define NPUMGR_DEVICE_TRIV2(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), NPUMGR_TYPE_DEVICE_TRIV2, \
+ NpumgrDeviceTriv2))
+
+typedef struct _NpumgrDeviceTriv2 NpumgrDeviceTriv2;
+typedef struct _NpumgrDeviceTriv2Class NpumgrDeviceTriv2Class;
+typedef struct _NpumgrDeviceTriv2Private NpumgrDeviceTriv2Private;
+
+/**
+ * @brief npumgr device class for TRIV2.
+ *
+ * NpumgrDeviceTriv2 inherits NpumgrDevice.
+ */
+struct _NpumgrDeviceTriv2 {
+ NpumgrDevice parent; /**< parent class object */
+};
+
+/**
+ * @brief NpumgrDeviceTriv2Class data structure.
+ *
+ * NpumgrDeviceTriv2Class inherits NpumgrDeviceClass.
+ */
+struct _NpumgrDeviceTriv2Class {
+ NpumgrDeviceClass parent_class; /**< inherits class object */
+};
+
+G_END_DECLS
+
+#endif
--- /dev/null
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+ This is a sample D-Bus configuration to test VD NPUMGR dummy module.
+ Please locate this file to your D-Bus system bus policy directory.
+ (e.g., /usr/share/dbus-1/system.d/sr.odl.NPUManager.conf)
+
+ Example command line for testing:
+ $ /usr/lib64/npu-engine/bin/apptests/npumgr/dummy_npumgr
+ $ /usr/lib64/npu-engine/bin/apptests/npumgr/apptest_npumgr \
+ /usr/share/npu-engine/testdata/TRIV235_2TOPS/MOBILENET_V1
+-->
+
+<busconfig>
+ <policy user="root">
+ <allow own="sr.odl.NPUManager.API"/>
+ </policy>
+ <policy context="default">
+ <allow send_path="/sr/org/NPUManager/APIObject"/>
+ <allow send_destination="sr.odl.NPUManager.API"/>
+ <allow receive_sender="sr.odl.NPUManager.API"/>
+ </policy>
+</busconfig>
--- /dev/null
+glib_dep = dependency('glib-2.0', required: false)
+if glib_dep.found()
+ npumgr_common_inc = include_directories('common')
+ npumgr_dep = disabler()
+
+ # dummy npu manager
+ subdir('dummy')
+ if npumgr_dep.found()
+ subdir('tests')
+ endif
+endif
--- /dev/null
+# npu manager test program
+executable ('apptest_npumgr',
+ 'npumgr_test.cc',
+ include_directories : [npumgr_common_inc],
+ dependencies : [glib_dep, ne_test_utils_common_dep, npumgr_dep],
+ install : true,
+ install_rpath : ne_libdir,
+ install_dir : join_paths(ne_bindir, 'plugins', 'npumgr')
+)
--- /dev/null
+/**
+ * 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 <fcntl.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <ne_test_utils_common.h>
+
+#include <npumgr_api.h>
+#include <npumgr_common.h>
+
+using namespace std;
+
+static int
+start_npumgr_test (int fd, const string &dir) {
+ npumgr_devices_id list;
+ npumgr_status_e status;
+
+ npumgr_context context;
+ npumgr_network network;
+
+ npumgr_buffer *input_bufs = NULL;
+ npumgr_buffer *output_bufs = NULL;
+ npumgr_query_inout_num inout_num = {0};
+
+ npumgr_network_defn input_files[] = {{NPUMGR_NETWORK_FILE_TVN, fd}};
+ const char *input_tensor_names[] = {"input"};
+ const char *output_tensor_names[] = {"output"};
+ npumgr_query_tensor_attr attr;
+
+ status = npumgr_device_get_available_list (&list);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to get available device list, " << status << "\n";
+ return status;
+ }
+
+ /* TODO: find the first NPU device */
+ bool found = false;
+ uint32_t id;
+
+ for (int i = 0; i < list.n_devices; i++) {
+ if (list.types[i] == NPUMGR_DEVICE_TYPE_NPU) {
+ found = true;
+ id = list.id[i];
+ break;
+ }
+ }
+
+ if (!found) {
+ cerr << "No available device\n";
+ return NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE;
+ }
+
+ status = npumgr_context_create (id, NPUMGR_FLAG_PRIORITY_DEFAULT, &context);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to create a npumgr context, " << status << "\n";
+ return NPUMGR_STATUS_ERR_FAIL;
+ }
+
+ status = npumgr_network_create (
+ context, 1, input_files, NPUMGR_BUF_TYPE_DRIVER, 1, input_tensor_names,
+ NPUMGR_BUF_TYPE_DRIVER, 1, output_tensor_names, &network);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to create a npumgr network, " << status << "\n";
+ goto destroy_ctx;
+ }
+
+ status = npumgr_query_network (context, network, &inout_num);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to query network info, " << status << "\n";
+ goto destroy_nw;
+ }
+
+ input_bufs = g_new0 (npumgr_buffer, inout_num.n_input);
+ output_bufs = g_new0 (npumgr_buffer, inout_num.n_output);
+
+ for (int i = 0; i < inout_num.n_input; i++) {
+ string file_path = dir + "/input_fmap_" + to_string (i) + ".bin";
+ FILE *f = fopen (file_path.c_str (), "rb");
+ void *data = NULL;
+
+ if (f == NULL) {
+ cerr << "Unable to find input file, " << file_path << "\n";
+ fclose (f);
+ goto destroy_all;
+ }
+
+ status = npumgr_query_input (context, network, i, &attr);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to query input info, " << status << "\n";
+ fclose (f);
+ goto destroy_all;
+ }
+
+ /** TODO: currently, support NHWC format only */
+ if (attr.fmt != NPUMGR_TENSOR_FMT_NHWC) {
+ cerr << "Other format is not supported yet, " << attr.fmt << "\n";
+ fclose (f);
+ goto destroy_all;
+ }
+
+ status = npumgr_buffer_create (context, &attr, &input_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to create input buffer, " << status << "\n";
+ fclose (f);
+ goto destroy_all;
+ }
+
+ status = npumgr_buffer_map (context, &input_bufs[i], (uint8_t **) &data);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to map input buffer, " << status << "\n";
+ fclose (f);
+ goto destroy_all;
+ }
+
+ size_t read_bytes = fread (data, 1, input_bufs[i].buf_size, f);
+ if (read_bytes != input_bufs[i].buf_size) {
+ cerr << "Unable to read input data, " << read_bytes << " vs. "
+ << input_bufs[i].buf_size << "\n";
+ fclose (f);
+ goto destroy_all;
+ }
+ fclose (f);
+
+ /** TODO: How unmap works? */
+#if 0
+ status = npumgr_buffer_unmap (context, &input_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to unmap buffer, " << status << "\n";
+ goto destroy_all;
+ }
+#else
+ munmap (data, ALIGNED_SIZE (input_bufs[i].buf_size));
+#endif
+
+ status = npumgr_network_set_input (context, network, i, &input_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to set input, " << status << "\n";
+ goto destroy_all;
+ }
+ }
+
+ for (int i = 0; i < inout_num.n_output; i++) {
+ status = npumgr_query_output (context, network, i, &attr);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to query output info, " << status << "\n";
+ goto destroy_all;
+ }
+
+ /** TODO: currently, support NHWC format only */
+ if (attr.fmt != NPUMGR_TENSOR_FMT_NHWC) {
+ cerr << "Other format is not supported yet, " << attr.fmt << "\n";
+ goto destroy_all;
+ }
+
+ status = npumgr_buffer_create (context, &attr, &output_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to create output buffer, " << status << "\n";
+ goto destroy_all;
+ }
+
+ status = npumgr_network_set_output (context, network, i, &output_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to set output, " << status << "\n";
+ goto destroy_all;
+ }
+ }
+
+ status = npumgr_network_prepare (context, network);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ goto destroy_all;
+ }
+
+ status = npumgr_execute_run (context, network);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to execute the network, " << status << "\n";
+ goto destroy_all;
+ }
+
+ for (int i = 0; i < inout_num.n_output; i++) {
+ string file_path = string (dir) + "/output_fmap_" + to_string (i) + ".bin";
+ void *data = NULL;
+
+ status = npumgr_buffer_map (context, &output_bufs[i], (uint8_t **) &data);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to map output buffer, " << status << "\n";
+ goto destroy_all;
+ }
+
+ if (compare_data (file_path.c_str (), (const char *) data,
+ output_bufs[i].buf_size) != 0) {
+ cerr << "Failed to get valid output data\n";
+ goto destroy_all;
+ }
+
+ /** TODO: How unmap works? */
+#if 0
+ status = npumgr_buffer_unmap (context, &output_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ cerr << "Unable to unmap output buffer, " << status << "\n";
+ goto destroy_all;
+ }
+#else
+ munmap (data, ALIGNED_SIZE (output_bufs[i].buf_size));
+#endif
+ }
+
+destroy_all:
+ if (input_bufs) {
+ for (int i = 0; i < inout_num.n_input; i++) {
+ if (input_bufs[i].buf_handle == 0)
+ continue;
+
+ status = npumgr_buffer_destroy (context, &input_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS)
+ cerr << "Unable to destroy the buffer, " << status << "\n";
+ }
+ }
+
+ if (output_bufs) {
+ for (int i = 0; i < inout_num.n_output; i++) {
+ if (output_bufs[i].buf_handle == 0)
+ continue;
+
+ status = npumgr_buffer_destroy (context, &output_bufs[i]);
+ if (status != NPUMGR_STATUS_SUCCESS)
+ cerr << "Unable to destroy the buffer, " << status << "\n";
+ }
+ }
+
+destroy_nw:
+ status = npumgr_network_destroy (context, network);
+ if (status != NPUMGR_STATUS_SUCCESS)
+ cerr << "Unable to destroy the npumgr network, " << status << "\n";
+
+destroy_ctx:
+ status = npumgr_context_destroy (context);
+ if (status != NPUMGR_STATUS_SUCCESS)
+ cerr << "Unable to destroy the npumgr context, " << status << "\n";
+
+ return status;
+}
+
+int
+main (int argc, char **argv) {
+ int fd, ret = -EINVAL;
+
+ if (argc != 2) {
+ cerr << "Please provide model datapath (i.e., including .tvn and .bin)\n";
+ cerr << "[APPTEST] " << argv[0] << ": SKIPPED\n";
+ return 0;
+ }
+
+ string dir (argv[1]);
+ string model_path = dir + "/model.tvn";
+
+ if (!g_file_test (dir.c_str (), G_FILE_TEST_IS_DIR)) {
+ cerr << "Invalid model datapath: " << dir << "\n";
+ goto out;
+ }
+
+ fd = open (model_path.c_str (), O_RDONLY);
+ if (fd < 0) {
+ cerr << "Unable to open file " << dir << "\n";
+ goto out;
+ }
+
+ ret = start_npumgr_test (fd, dir);
+ close (fd);
+
+out:
+ if (ret == 0)
+ cerr << "[APPTEST] " << argv[0] << ": PASSED\n";
+ else
+ cerr << "[APPTEST] " << argv[0] << ": FAILED (" << ret << ")\n";
+
+ return ret;
+}
install_rpath : ne_libdir,
install_dir : join_paths(ne_bindir, 'apptests')
)
-
-# npumgr is available on tizen env.
-if target_platform == 'tizen'
- subdir('npumgr')
-endif
+++ /dev/null
-# Note that VD NPU Manager is a gdbus-based thread application
-gmodule_dep = dependency('gmodule-2.0', required: false)
-giounix_dep = dependency('gio-unix-2.0', required: false)
-if gmodule_dep.found() and giounix_dep.found()
- npumgr_deps = [
- glib_dep,
- gmodule_dep,
- giounix_dep
- ]
-
- if target_platform == 'tizen'
- npumgr_deps += dependency('dlog')
- endif
-
- 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
- )
- npumgr_dep = declare_dependency (link_with : npumgr_lib,
- include_directories : include_directories('.')
- )
-
- npumgr_triv2_lib = shared_library ('npumgr_triv2',
- ['npumgr_triv2.cc', 'npumgr_device.cc'],
- include_directories : [ne_common_inc, ne_host_inc],
- dependencies: npumgr_deps,
- link_with : ne_library_shared,
- build_rpath : ne_libdir,
- install : true,
- install_rpath : ne_libdir,
- install_dir : ne_libdir
- )
-
- executable ('dummy_npumgr',
- ['npumgr.cc', 'npumgr_device.cc'],
- dependencies: npumgr_deps,
- install : true,
- install_rpath : ne_libdir,
- install_dir : join_paths(ne_bindir, 'apptests', 'npumgr')
- )
-
- install_data ('sr.odl.NPUManager.conf',
- install_dir: join_paths(get_option('datadir'), 'dbus-1', 'system.d')
- )
-endif
+++ /dev/null
-/**
- * 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 <vector>
-#include <string>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <gmodule.h>
-#include <gio/gio.h>
-#include <gio/gunixfdlist.h>
-
-#include <npumgr_api.h>
-#include <npumgr_device.h>
-
-#define NPUMGR_DAEMON_NAME "npumgr-dummy"
-#define NPUMGR_DEVICE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), NPUMGR_TYPE_DEVICE, NpumgrDeviceClass))
-
-#ifdef __TIZEN__
-#include <dlog.h>
-#define TAG_NAME NPUMGR_DAEMON_NAME
-#define logi(...) dlog_print (DLOG_INFO, TAG_NAME, __VA_ARGS__)
-#define logw(...) dlog_print (DLOG_WARN, TAG_NAME, __VA_ARGS__)
-#define loge(...) dlog_print (DLOG_ERROR, TAG_NAME, __VA_ARGS__)
-#else
-#include <syslog.h>
-#define logi(...) syslog (LOG_INFO, __VA_ARGS__)
-#define logw(...) syslog (LOG_WARNING, __VA_ARGS__)
-#define loge(...) syslog (LOG_ERR, __VA_ARGS__)
-#endif
-
-/**
- * @brief Internal data structure for NPU Manager Context
- */
-typedef struct {
- NpumgrDevice *device;
- npumgr_context handle;
-} NpumgrContext;
-
-G_LOCK_DEFINE_STATIC (mutex);
-static GHashTable *ctx_table;
-
-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='DeviceGetAvailableList'>"
- " <arg type='u' name='num_devices' direction='out'/>"
- " <arg type='ai' name='device_type' direction='out'/>"
- " <arg type='au' name='device_id' direction='out'/>"
- " </method>"
- " <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>"
- " <method name='NetworkCreate'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='i' name='num_files' direction='in'/>"
- " <arg type='at' name='input_files' direction='in'/>"
- " <arg type='i' name='in_buffer_type' direction='in'/>"
- " <arg type='i' name='in_tensor_cnt' direction='in'/>"
- " <arg type='v' name='in_tensor_names' direction='in'/>"
- " <arg type='i' name='out_buffer_type' direction='in'/>"
- " <arg type='i' name='out_tensor_cnt' direction='in'/>"
- " <arg type='v' name='out_tensor_names' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='out'/>"
- " </method>"
- " <method name='NetworkSetInput'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " <arg type='i' name='index' direction='in'/>"
- " <arg type='v' name='buffer' direction='in'/>"
- " </method>"
- " <method name='NetworkSetOutput'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " <arg type='i' name='index' direction='in'/>"
- " <arg type='v' name='buffer' direction='in'/>"
- " </method>"
- " <method name='NetworkPrepare'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " </method>"
- " <method name='NetworkDestroy'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " </method>"
- " <method name='BufferCreate'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='v' name='param' direction='in'/>"
- " <arg type='v' name='buffer' direction='out'/>"
- " </method>"
- " <method name='BufferMap'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='v' name='buffer' direction='in'/>"
- " <arg type='v' name='buffer' direction='out'/>"
- " </method>"
- " <method name='BufferDestroy'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='v' name='buffer' direction='in'/>"
- " </method>"
- " <method name='QueryNetwork'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " <arg type='u' name='n_input' direction='out'/>"
- " <arg type='u' name='n_output' direction='out'/>"
- " </method>"
- " <method name='QueryInput'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " <arg type='i' name='index' direction='in'/>"
- " <arg type='v' name='data' direction='out'/>"
- " </method>"
- " <method name='QueryOutput'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " <arg type='i' name='index' direction='in'/>"
- " <arg type='v' name='data' direction='out'/>"
- " </method>"
- " <method name='ExecuteTrigger'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " </method>"
- " <method name='ExecuteWait'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " </method>"
- " <method name='ExecuteRun'>"
- " <arg type='t' name='ctx_handle' direction='in'/>"
- " <arg type='t' name='nw_handle' direction='in'/>"
- " </method>"
- " </interface>"
- " </node>";
-
-/**
- * @brief Name of supported plugins
- */
-static const char *supported_plugins[] = {
- "triv2",
-};
-
-/**
- * @brief Internal structure to hold plugin data
- */
-typedef struct {
- const char *name;
- GModule *module;
- NpumgrDevice *device;
- uint32_t id;
- uint32_t caps;
- npumgr_device_type_t ptype;
-} plugin_pdata;
-
-/**
- * @brief Registered plugins
- */
-static GSList *registered_plugins;
-
-static void
-append_device (gpointer data, gpointer user_data) {
- plugin_pdata *pdata = (plugin_pdata *) data;
- npumgr_devices_id *devices = (npumgr_devices_id *) user_data;
- NpumgrDevice *device = pdata->device;
-
- NPUMGR_DEVICE_GET_CLASS (device)->device_get_capabilities (
- device, &pdata->caps, &pdata->ptype);
-
- devices->types[devices->n_devices] = pdata->ptype;
- devices->id[devices->n_devices] = pdata->id;
- devices->n_devices++;
-}
-
-/**
- * @brief Insert npumgr context created
- */
-static gboolean
-insert_context (npumgr_context handle, NpumgrContext *context) {
- gboolean result;
-
- G_LOCK (mutex);
- result = g_hash_table_insert (ctx_table, GSIZE_TO_POINTER (handle), context);
- G_UNLOCK (mutex);
-
- return result;
-}
-
-/**
- * @brief Remove the npumgr context
- */
-static gboolean
-remove_context (npumgr_context handle) {
- gboolean result;
-
- G_LOCK (mutex);
- result = g_hash_table_remove (ctx_table, GSIZE_TO_POINTER (handle));
- G_UNLOCK (mutex);
-
- return result;
-}
-
-/**
- * @brief Find npumgr context created
- */
-static NpumgrContext *
-find_context (npumgr_context handle) {
- NpumgrContext *context;
-
- G_LOCK (mutex);
- context = (NpumgrContext *) g_hash_table_lookup (ctx_table,
- GSIZE_TO_POINTER (handle));
- G_UNLOCK (mutex);
-
- return context;
-}
-
-/**
- * @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, "DeviceGetAvailableList") == 0) {
- GVariantBuilder builder, builder_arr;
- npumgr_devices_id devices = {.n_devices = 0};
-
- g_slist_foreach (registered_plugins, append_device, &devices);
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(uaiau)"));
- g_variant_builder_add (&builder, "u", devices.n_devices);
-
- g_variant_builder_init (&builder_arr, G_VARIANT_TYPE ("ai"));
- for (int i = 0; i < devices.n_devices; i++)
- g_variant_builder_add (&builder_arr, "i", ((int *) devices.types)[i]);
- g_variant_builder_add_value (&builder,
- g_variant_builder_end (&builder_arr));
-
- g_variant_builder_init (&builder_arr, G_VARIANT_TYPE ("au"));
- for (int i = 0; i < devices.n_devices; i++)
- g_variant_builder_add (&builder_arr, "u", ((int *) devices.id)[i]);
- g_variant_builder_add_value (&builder,
- g_variant_builder_end (&builder_arr));
-
- g_dbus_method_invocation_return_value (invocation,
- g_variant_builder_end (&builder));
- } else 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) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments detected");
- return;
- }
-
- plugin_pdata *pdata =
- (plugin_pdata *) g_slist_nth_data (registered_plugins, device_id);
- if (pdata == NULL) {
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Invalid device id");
- return;
- }
-
- NpumgrDevice *device = pdata->device;
- npumgr_context handle;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->context_create (
- device, device_id, priority, &handle);
- if (status == NPUMGR_STATUS_SUCCESS) {
- NpumgrContext *ctx;
-
- ctx = g_new0 (NpumgrContext, 1);
- ctx->handle = handle;
- ctx->device = device;
-
- if (insert_context (handle, ctx)) {
- g_dbus_method_invocation_return_value (invocation,
- g_variant_new ("(t)", handle));
- } else {
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
- "Unable to add context: same context handle detected");
- NPUMGR_DEVICE_GET_CLASS (device)->context_destroy (device, handle);
- g_free (ctx);
- }
- } else {
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
- "Unable to add context: internal errors");
- }
- } else if (g_strcmp0 (method_name, "ContextDestroy") == 0) {
- npumgr_context handle = 0;
-
- g_variant_get (parameters, "(t)", &handle);
- if (handle > 0) {
- if (remove_context (handle))
- g_dbus_method_invocation_return_value (invocation, NULL);
- else
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- } 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, "NetworkCreate") == 0) {
- npumgr_context ctx_handle = 0;
- int num_files;
- GVariantIter *input_files_iter;
- npumgr_buffer_t in_buffer_type, out_buffer_type;
- int in_tensor_cnt, out_tensor_cnt;
- GVariant *in_tensor_names_var;
- GVariant *out_tensor_names_var;
-
- g_variant_get (parameters, "(tiatiiviiv)", &ctx_handle, &num_files,
- &input_files_iter, &in_buffer_type, &in_tensor_cnt,
- &in_tensor_names_var, &out_buffer_type, &out_tensor_cnt,
- &out_tensor_names_var);
-
- if (ctx_handle > 0 && num_files > 0 && in_tensor_cnt < NPUMGR_MAX_DIMS &&
- out_tensor_cnt < NPUMGR_MAX_DIMS) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context == NULL) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to find context");
- return;
- }
- NpumgrDevice *device = context->device;
- GDBusMessage *message = g_dbus_method_invocation_get_message (invocation);
- GUnixFDList *fd_list = g_dbus_message_get_unix_fd_list (message);
-
- std::vector<npumgr_network_defn> input_files_vec;
- npumgr_network_defn input_file;
- while (g_variant_iter_loop (input_files_iter, "t", &input_file)) {
- input_file.fd = g_unix_fd_list_get (fd_list, 0, NULL);
- input_files_vec.push_back (input_file);
- }
- g_variant_iter_free (input_files_iter);
-
- gchar **in_tensor_names = g_variant_dup_strv (in_tensor_names_var, NULL);
- gchar **out_tensor_names =
- g_variant_dup_strv (out_tensor_names_var, NULL);
-
- npumgr_network nw_handle;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->network_create (
- device, ctx_handle, num_files, input_files_vec.data (),
- in_buffer_type, in_tensor_cnt, in_tensor_names, out_buffer_type,
- out_tensor_cnt, out_tensor_names, &nw_handle);
-
- g_strfreev (in_tensor_names);
- g_strfreev (out_tensor_names);
- g_variant_unref (in_tensor_names_var);
- g_variant_unref (out_tensor_names_var);
-
- if (status == NPUMGR_STATUS_SUCCESS) {
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(t)", nw_handle));
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to add network");
- }
- } 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, "NetworkSetInput") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
- GVariant *variant = NULL;
- int index = -1;
-
- g_variant_get (parameters, "(ttiv)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle, &index, &variant);
- if (ctx_handle > 0 && nw_handle > 0 && index >= 0 && variant != NULL) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
- npumgr_buffer buffer;
- GBytes *bytes;
-
- bytes = g_variant_get_data_as_bytes (variant);
- if (g_bytes_get_size (bytes) != sizeof (buffer)) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments detected");
- g_bytes_unref (bytes);
- return;
- }
-
- memcpy (&buffer, g_bytes_get_data (bytes, NULL), sizeof (buffer));
- g_bytes_unref (bytes);
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->network_set_input (
- device, ctx_handle, nw_handle, index, &buffer);
- if (status == NPUMGR_STATUS_SUCCESS)
- g_dbus_method_invocation_return_value (invocation, NULL);
- else
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to set the input");
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "NetworkSetOutput") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
- GVariant *variant = NULL;
- int index = -1;
-
- g_variant_get (parameters, "(ttiv)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle, &index, &variant);
- if (ctx_handle > 0 && nw_handle > 0 && index >= 0 && variant != NULL) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
- npumgr_buffer buffer;
- GBytes *bytes;
-
- bytes = g_variant_get_data_as_bytes (variant);
- if (g_bytes_get_size (bytes) != sizeof (buffer)) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments detected");
- g_bytes_unref (bytes);
- return;
- }
-
- memcpy (&buffer, g_bytes_get_data (bytes, NULL), sizeof (buffer));
- g_bytes_unref (bytes);
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->network_set_output (
- device, ctx_handle, nw_handle, index, &buffer);
- if (status == NPUMGR_STATUS_SUCCESS)
- g_dbus_method_invocation_return_value (invocation, NULL);
- else
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to set the output");
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "NetworkPrepare") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
-
- g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle);
- if (ctx_handle > 0 && nw_handle > 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->network_prepare (
- device, ctx_handle, nw_handle);
- if (status == NPUMGR_STATUS_SUCCESS)
- g_dbus_method_invocation_return_value (invocation, NULL);
- else
- g_dbus_method_invocation_return_error (
- invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to prepare network execution");
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "NetworkDestroy") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
-
- g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle);
- if (ctx_handle > 0 && nw_handle > 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->network_destroy (
- device, ctx_handle, nw_handle);
- if (status == NPUMGR_STATUS_SUCCESS)
- g_dbus_method_invocation_return_value (invocation, NULL);
- else
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the network");
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "QueryNetwork") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
-
- g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle);
- if (ctx_handle > 0 && nw_handle > 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- npumgr_query_inout_num data;
- status = NPUMGR_DEVICE_GET_CLASS (device)->query_network (
- device, ctx_handle, nw_handle, &data);
- if (status == NPUMGR_STATUS_SUCCESS) {
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(uu)", data.n_input, data.n_output));
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the network");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "QueryInput") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
- int index = -1;
-
- g_variant_get (parameters, "(tti)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle, &index);
- if (ctx_handle > 0 && nw_handle > 0 && index >= 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- npumgr_query_tensor_attr data;
- status = NPUMGR_DEVICE_GET_CLASS (device)->query_input (
- device, ctx_handle, nw_handle, index, &data);
- if (status == NPUMGR_STATUS_SUCCESS) {
- GBytes *bytes = g_bytes_new (&data, sizeof (data));
- GVariant *variant =
- g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(v)", variant));
- g_bytes_unref (bytes);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to find input attr");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "QueryOutput") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
- int index = -1;
-
- g_variant_get (parameters, "(tti)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle, &index);
- if (ctx_handle > 0 && nw_handle > 0 && index >= 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- npumgr_query_tensor_attr data;
- status = NPUMGR_DEVICE_GET_CLASS (device)->query_output (
- device, ctx_handle, nw_handle, index, &data);
- if (status == NPUMGR_STATUS_SUCCESS) {
- GBytes *bytes = g_bytes_new (&data, sizeof (data));
- GVariant *variant =
- g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(v)", variant));
- g_bytes_unref (bytes);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to find output attr");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "BufferCreate") == 0) {
- npumgr_context ctx_handle = 0;
- GVariant *variant = NULL;
-
- g_variant_get (parameters, "(tv)", (guint64 *) &ctx_handle, &variant);
- if (ctx_handle > 0 && variant != NULL) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_query_tensor_attr param;
- npumgr_buffer buf;
- npumgr_status_e status;
-
- GBytes *bytes = g_variant_get_data_as_bytes (variant);
- if (g_bytes_get_size (bytes) != sizeof (param)) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments detected");
- g_bytes_unref (bytes);
- return;
- }
-
- memcpy (¶m, g_bytes_get_data (bytes, NULL), sizeof (param));
- g_bytes_unref (bytes);
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->buffer_create (
- device, ctx_handle, ¶m, &buf);
- if (status == NPUMGR_STATUS_SUCCESS) {
- bytes = g_bytes_new (&buf, sizeof (buf));
- variant =
- g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_method_invocation_return_value (
- invocation, g_variant_new ("(v)", variant));
- g_bytes_unref (bytes);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to create buffer");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "BufferMap") == 0) {
- npumgr_context ctx_handle = 0;
- GVariant *variant = NULL;
-
- g_variant_get (parameters, "(tv)", (guint64 *) &ctx_handle, &variant);
- if (ctx_handle > 0 && variant != NULL) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_buffer buf;
- uint8_t *addr;
- npumgr_status_e status;
-
- GBytes *bytes = g_variant_get_data_as_bytes (variant);
- if (g_bytes_get_size (bytes) != sizeof (buf)) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments detected");
- g_bytes_unref (bytes);
- return;
- }
-
- memcpy (&buf, g_bytes_get_data (bytes, NULL), sizeof (buf));
- g_bytes_unref (bytes);
-
- /* TODO: how to deliver this addr to client? */
- status = NPUMGR_DEVICE_GET_CLASS (device)->buffer_map (
- device, ctx_handle, &buf, &addr);
- if (status == NPUMGR_STATUS_SUCCESS) {
- GUnixFDList *fd_list = g_unix_fd_list_new ();
- g_unix_fd_list_append (fd_list, buf.buf_fd, NULL);
-
- bytes = g_bytes_new (&buf, sizeof (buf));
- variant =
- g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_method_invocation_return_value_with_unix_fd_list (
- invocation, g_variant_new ("(v)", variant), fd_list);
- g_bytes_unref (bytes);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to map buffer");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "BufferDestroy") == 0) {
- npumgr_context ctx_handle = 0;
- GVariant *variant = NULL;
-
- g_variant_get (parameters, "(tv)", (guint64 *) &ctx_handle, &variant);
- if (ctx_handle > 0 && variant != NULL) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_buffer buf;
- npumgr_status_e status;
-
- GBytes *bytes = g_variant_get_data_as_bytes (variant);
- if (g_bytes_get_size (bytes) != sizeof (buf)) {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Invalid arguments detected");
- g_bytes_unref (bytes);
- return;
- }
-
- memcpy (&buf, g_bytes_get_data (bytes, NULL), sizeof (buf));
- g_bytes_unref (bytes);
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->buffer_destroy (
- device, ctx_handle, &buf);
- if (status == NPUMGR_STATUS_SUCCESS) {
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to destroy buffer");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "ExecuteTrigger") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
-
- g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle);
- if (ctx_handle > 0 && nw_handle > 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->execute_trigger (
- device, ctx_handle, nw_handle);
- if (status == NPUMGR_STATUS_SUCCESS) {
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to execute network");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "ExecuteWait") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
-
- g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle);
- if (ctx_handle > 0 && nw_handle > 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->execute_wait (
- device, ctx_handle, nw_handle);
- if (status == NPUMGR_STATUS_SUCCESS) {
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to finish execution");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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, "ExecuteRun") == 0) {
- npumgr_context ctx_handle = 0;
- npumgr_network nw_handle = 0;
-
- g_variant_get (parameters, "(tt)", (guint64 *) &ctx_handle,
- (guint64 *) &nw_handle);
- if (ctx_handle > 0 && nw_handle > 0) {
- NpumgrContext *context = find_context (ctx_handle);
- if (context != NULL) {
- NpumgrDevice *device = context->device;
- npumgr_status_e status;
-
- status = NPUMGR_DEVICE_GET_CLASS (device)->execute_run (
- device, ctx_handle, nw_handle);
- if (status == NPUMGR_STATUS_SUCCESS) {
- g_dbus_method_invocation_return_value (invocation, NULL);
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Unable to execute network");
- }
- } else {
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_UNKNOWN_OBJECT,
- "Unable to find the context");
- }
- } 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)
- loge ("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) {
- loge ("Unable to acquire name %s", name);
- exit (EXIT_FAILURE);
-}
-
-/**
- * @brief Destroy callback for freeing context instance
- */
-static void
-ctx_destroy (gpointer data) {
- NpumgrContext *ctx = static_cast<NpumgrContext *> (data);
- NpumgrDevice *device;
-
- g_return_if_fail (ctx != NULL);
-
- device = ctx->device;
- NPUMGR_DEVICE_GET_CLASS (device)->context_destroy (device, ctx->handle);
-
- g_free (ctx);
-}
-
-static void
-plugin_pdata_free (gpointer *data) {
- plugin_pdata *pdata = (plugin_pdata *) data;
-
- g_module_close (pdata->module);
- g_object_unref (pdata->device);
- g_free (pdata);
-}
-
-/**
- * @brief Initialize plugins
- */
-static void
-init_plugins (void) {
- typedef NpumgrDevice *(*NewFunc) (void);
- GModule *module;
- NewFunc func;
-
- registered_plugins = NULL;
-
- for (auto &name : supported_plugins) {
- gchar *module_name = g_strdup_printf ("libnpumgr_%s", name);
- module = g_module_open (module_name, G_MODULE_BIND_LAZY);
- if (!module) {
- logw ("Unable to open plugin %s", module_name);
- g_free (module_name);
- continue;
- }
- g_free (module_name);
-
- gchar *module_symbol = g_strdup_printf ("npumgr_device_%s_new", name);
- if (!g_module_symbol (module, module_symbol, (gpointer *) &func)) {
- logw ("Unable to find symbol %s", module_symbol);
- g_free (module_symbol);
- continue;
- }
- g_free (module_symbol);
-
- plugin_pdata *pdata = g_new0 (plugin_pdata, 1);
- registered_plugins = g_slist_append (registered_plugins, pdata);
-
- pdata->name = name;
- pdata->module = module;
- pdata->device = func ();
- pdata->id = g_slist_index (registered_plugins, pdata);
- }
-}
-
-/**
- * @brief Main routine for gdbus-based npumgr daemon
- */
-static int
-start_npumgr (void) {
- 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) {
- loge ("Failed to build the introspection data structure");
- return -1;
- }
-
- init_plugins ();
-
- ctx_table =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, ctx_destroy);
- owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, "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);
-
- g_hash_table_destroy (ctx_table);
- g_slist_free_full (registered_plugins, (GDestroyNotify) plugin_pdata_free);
-
- logi ("Stopping %s", NPUMGR_DAEMON_NAME);
- return 0;
-}
-
-/**
- * @brief Daemonize the program
- */
-int
-main (int argc, char *argv[]) {
- pid_t pid, sid;
-
- pid = fork ();
- if (pid > 0)
- exit (EXIT_SUCCESS);
- else if (pid < 0)
- exit (EXIT_FAILURE);
-
- umask (0);
-
-#ifndef __TIZEN__
- openlog (NPUMGR_DAEMON_NAME, LOG_NOWAIT | LOG_PID, LOG_USER);
-#endif
-
- sid = setsid ();
- if (sid < 0) {
- loge ("Unable to generate session ID for child process");
- exit (EXIT_FAILURE);
- }
-
- if ((chdir ("/")) < 0) {
- loge ("Unable to change the working directory");
- exit (EXIT_FAILURE);
- }
-
- close (STDIN_FILENO);
- close (STDOUT_FILENO);
- close (STDERR_FILENO);
-
- logi ("Starting %s", NPUMGR_DAEMON_NAME);
-
- return start_npumgr ();
-}
+++ /dev/null
-/**
- * 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 "../npumgr_common.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <gio/gio.h>
-#include <gio/gunixfdlist.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;
-static gboolean _running;
-
-/**
- * @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) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GError *error = NULL;
-
- g_return_val_if_fail (pdev != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- 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",
- "DeviceGetAvailableList");
- g_dbus_message_set_body (method_call, NULL);
-
- 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;
- }
-
- {
- GVariantIter *iter_type;
- GVariantIter *iter_id;
- uint32_t idx;
-
- g_variant_get (g_dbus_message_get_body (method_reply), "(uaiau)",
- &pdev->n_devices, &iter_type, &iter_id);
-
- if (pdev->n_devices > NPUMGR_MAX_DEVICES) {
- g_critical ("Too many devices: %u", pdev->n_devices);
- status = NPUMGR_STATUS_ERR_FAIL;
- goto out_iter;
- }
-
- idx = 0;
- while (idx < NPUMGR_MAX_DEVICES &&
- g_variant_iter_loop (iter_type, "i", &pdev->types[idx++]))
- ;
-
- idx = 0;
- while (idx < NPUMGR_MAX_DEVICES &&
- g_variant_iter_loop (iter_id, "u", &pdev->id[idx++]))
- ;
-
- out_iter:
- g_variant_iter_free (iter_type);
- g_variant_iter_free (iter_id);
- }
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @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 *in_tensor_names,
- npumgr_buffer_t out_buffer_type, int out_tensor_cnt,
- const char *const *out_tensor_names,
- npumgr_network *out_nw_handle) {
- 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",
- "NetworkCreate");
-
- GVariantBuilder builder, builder_arr;
- GUnixFDList *fd_list;
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(tiatiiviiv)"));
- g_variant_builder_init (&builder_arr, G_VARIANT_TYPE ("at"));
-
- fd_list = g_unix_fd_list_new ();
-
- /* build message body */
- g_variant_builder_add (&builder, "t", ctx);
- g_variant_builder_add (&builder, "i", num_files);
- for (int i = 0; i < num_files; i++) {
- g_unix_fd_list_append (fd_list, input_files[i].fd, NULL);
- g_variant_builder_add (&builder_arr, "t", ((uint64_t *) input_files)[i]);
- }
- g_dbus_message_set_unix_fd_list (method_call, fd_list);
-
- g_variant_builder_add_value (&builder, g_variant_builder_end (&builder_arr));
- g_variant_builder_add (&builder, "i", in_buffer_type);
- g_variant_builder_add (&builder, "i", in_tensor_cnt);
- g_variant_builder_add (&builder, "v",
- g_variant_new_strv (in_tensor_names, in_tensor_cnt));
- g_variant_builder_add (&builder, "i", out_buffer_type);
- g_variant_builder_add (&builder, "i", out_tensor_cnt);
- g_variant_builder_add (&builder, "v",
- g_variant_new_strv (out_tensor_names, out_tensor_cnt));
-
- g_dbus_message_set_body (method_call, g_variant_builder_end (&builder));
- 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_nw_handle);
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @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) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GBytes *bytes;
- GVariant *variant;
- 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",
- "NetworkSetInput");
-
- bytes = g_bytes_new (input_buffer, sizeof (*input_buffer));
- variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_message_set_body (
- method_call, g_variant_new ("(ttiv)", ctx, nw_handle, index, variant));
-
- 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 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) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GBytes *bytes;
- GVariant *variant;
- 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",
- "NetworkSetOutput");
-
- bytes = g_bytes_new (output_buffer, sizeof (*output_buffer));
- variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_message_set_body (
- method_call, g_variant_new ("(ttiv)", ctx, nw_handle, index, variant));
-
- 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 preparing network and making it ready to run on hardware.
- */
-npumgr_status_e
-npumgr_network_prepare (npumgr_context ctx, npumgr_network nw_handle) {
- 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",
- "NetworkPrepare");
- g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
-
- 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 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) {
- 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",
- "NetworkDestroy");
- g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
-
- 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 buffer creation.
- */
-npumgr_status_e
-npumgr_buffer_create (npumgr_context ctx,
- npumgr_query_tensor_attr *create_param,
- npumgr_buffer *buf) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GError *error = NULL;
- GVariant *variant;
- GBytes *bytes;
-
- 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",
- "BufferCreate");
-
- bytes = g_bytes_new (create_param, sizeof (*create_param));
- variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_message_set_body (method_call, g_variant_new ("(tv)", ctx, variant));
-
- method_reply = g_dbus_connection_send_message_with_reply_sync (
- _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
- &error);
-
- g_bytes_unref (bytes);
-
- 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), "(v)", &variant);
- bytes = g_variant_get_data_as_bytes (variant);
-
- if (g_bytes_get_size (bytes) != sizeof (*buf)) {
- status = NPUMGR_STATUS_ERR_FAIL;
- goto out_unref;
- }
-
- memcpy (buf, g_bytes_get_data (bytes, NULL), sizeof (*buf));
-
-out_unref:
- g_bytes_unref (bytes);
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @brief This API helps in destroying the creatd buffer.
- */
-npumgr_status_e
-npumgr_buffer_destroy (npumgr_context ctx, npumgr_buffer *buf) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GError *error = NULL;
- GVariant *variant;
- GBytes *bytes;
-
- 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",
- "BufferDestroy");
-
- bytes = g_bytes_new (buf, sizeof (*buf));
- variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_message_set_body (method_call, g_variant_new ("(tv)", ctx, variant));
-
- method_reply = g_dbus_connection_send_message_with_reply_sync (
- _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
- &error);
-
- g_bytes_unref (bytes);
-
- 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 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) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GError *error = NULL;
- GVariant *variant;
- GBytes *bytes;
- GUnixFDList *fd_list;
-
- 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",
- "BufferMap");
-
- bytes = g_bytes_new (buf, sizeof (*buf));
- variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_dbus_message_set_body (method_call, g_variant_new ("(tv)", ctx, variant));
-
- method_reply = g_dbus_connection_send_message_with_reply_sync (
- _connection, method_call, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL,
- &error);
-
- g_bytes_unref (bytes);
-
- 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), "(v)", &variant);
- bytes = g_variant_get_data_as_bytes (variant);
-
- if (g_bytes_get_size (bytes) != sizeof (*buf)) {
- status = NPUMGR_STATUS_ERR_FAIL;
- goto out_unref;
- }
-
- memcpy (buf, g_bytes_get_data (bytes, NULL), sizeof (*buf));
-
- fd_list = g_dbus_message_get_unix_fd_list (method_reply);
- buf->buf_fd = g_unix_fd_list_get (fd_list, 0, NULL);
-
- *mapped_addr =
- (uint8_t *) mmap (NULL, ALIGNED_SIZE (buf->buf_size),
- PROT_READ | PROT_WRITE, MAP_SHARED, buf->buf_fd, 0);
- if (*mapped_addr == MAP_FAILED)
- status = NPUMGR_STATUS_ERR_FAIL;
-
-out_unref:
- g_bytes_unref (bytes);
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @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) {
- 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",
- "QueryNetwork");
- g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
-
- 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), "(uu)", &data->n_input,
- &data->n_output);
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @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) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GError *error = NULL;
- GVariant *variant;
- GBytes *bytes;
-
- 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",
- "QueryInput");
- g_dbus_message_set_body (method_call,
- g_variant_new ("(tti)", ctx, nw_handle, index));
-
- 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), "(v)", &variant);
- bytes = g_variant_get_data_as_bytes (variant);
-
- if (g_bytes_get_size (bytes) != sizeof (*data)) {
- status = NPUMGR_STATUS_ERR_FAIL;
- goto out_unref;
- }
-
- memcpy (data, g_bytes_get_data (bytes, NULL), sizeof (*data));
-
-out_unref:
- g_bytes_unref (bytes);
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @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) {
- GDBusMessage *method_call;
- GDBusMessage *method_reply;
- npumgr_status_e status = NPUMGR_STATUS_SUCCESS;
- GError *error = NULL;
- GVariant *variant;
- GBytes *bytes;
-
- 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",
- "QueryOutput");
- g_dbus_message_set_body (method_call,
- g_variant_new ("(tti)", ctx, nw_handle, index));
-
- 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), "(v)", &variant);
- bytes = g_variant_get_data_as_bytes (variant);
-
- if (g_bytes_get_size (bytes) != sizeof (*data)) {
- status = NPUMGR_STATUS_ERR_FAIL;
- goto out_unref;
- }
-
- memcpy (data, g_bytes_get_data (bytes, NULL), sizeof (*data));
-
-out_unref:
- g_bytes_unref (bytes);
-
-out:
- g_object_unref (method_call);
- g_object_unref (method_reply);
-
- return status;
-}
-
-/**
- * @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) {
- 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",
- "ExecuteTrigger");
- g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
-
- 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 explicitly wait for HW to finish executing the submitted commands.
- */
-npumgr_status_e
-npumgr_execute_wait (npumgr_context ctx, npumgr_network nw_handle) {
- 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",
- "ExecuteWait");
- g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
-
- 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 running the network.
- */
-npumgr_status_e
-npumgr_execute_run (npumgr_context ctx, npumgr_network nw_handle) {
- 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",
- "ExecuteRun");
- g_dbus_message_set_body (method_call, g_variant_new ("(tt)", ctx, nw_handle));
-
- 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 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_SYSTEM, "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_mutex_lock (&_mutex);
- _running = TRUE;
- g_cond_broadcast (&_cond);
- g_mutex_unlock (&_mutex);
-
- 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;
- _running = FALSE;
- _thread = g_thread_new (NULL, npumgr_thread, NULL);
-}
-
-/**
- * @brief Destructor of npumgr APi library
- */
-void
-fini_npumgr_api (void) {
- if (_thread) {
- gint64 end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
-
- g_mutex_lock (&_mutex);
- if (_running == FALSE)
- g_cond_wait_until (&_cond, &_mutex, end_time);
- g_main_loop_quit (_loop);
- g_mutex_unlock (&_mutex);
-
- g_thread_join (_thread);
- }
-}
+++ /dev/null
-/**
-* @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_FILE_TVN, /**< Trinity Vision NPU */
-
- 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_BUF_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__ */
+++ /dev/null
-/**
- * Proprietary
- * Copyright (C) 2021 Samsung Electronics
- * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
- */
-/**
- * @file npumgr_device.cc
- * @date 03 May 2021
- * @brief a parent class (dummy) of VD NPU Manager device.
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include "npumgr_device.h"
-
-G_DEFINE_TYPE (NpumgrDevice, npumgr_device, G_TYPE_OBJECT);
-
-static void
-npumgr_device_class_init (NpumgrDeviceClass *klass) {
- /* NYI */
-}
-
-static void
-npumgr_device_init (NpumgrDevice *self) {
- /* NYI */
-}
+++ /dev/null
-#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
+++ /dev/null
-/**
- * Proprietary
- * Copyright (C) 2021 Samsung Electronics
- * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
- */
-/**
- * @file npumgr_triv2.cc
- * @date 03 May 2021
- * @brief TRIV2 device plugin of VD NPU Manager
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include "npumgr_triv2.h"
-
-/* npu-engine API */
-#include <libnpuhost.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <vector>
-
-extern "C" {
-NpumgrDevice *npumgr_device_triv2_new (void);
-}
-
-typedef struct {
- GMutex mutex;
- GCond cond;
- gboolean done;
-} async_cb_priv;
-
-void
-async_cb (output_buffers *output, int req_id, void *data) {
- async_cb_priv *priv = (async_cb_priv *) data;
-
- g_mutex_lock (&priv->mutex);
- /* as output is dmabuf, don't need to perform memcpy */
- priv->done = TRUE;
- g_cond_broadcast (&priv->cond);
- g_mutex_unlock (&priv->mutex);
-}
-
-/**
- * @brief Class for triv2 npumgr buffer
- */
-class NpumgrBufferTriv2 {
- public:
- NpumgrBufferTriv2 (const generic_buffer &gbuf) {
- handle_ = g_atomic_int_add (&g_buf_handle, 1);
- memcpy (&gbuf_, &gbuf, sizeof (gbuf));
- quant_type_ = NPUMGR_TENSOR_QNT_MAX;
- }
-
- int getDbufFD () const { return gbuf_.dmabuf; }
- size_t getSize () const { return gbuf_.size; }
- void *getData () const { return gbuf_.addr; }
- npumgr_buffer_h getHandle () const { return handle_; }
- generic_buffer *getGenericBuffer () { return &gbuf_; }
-
- void setDataFmt (const npumgr_tensor_fmt_t &fmt) { data_fmt_ = fmt; }
- void setDataType (const npumgr_tensor_data_t &type) { data_type_ = type; }
- void setQuantType (const npumgr_tensor_qnt_t &type) { quant_type_ = type; }
-
- const npumgr_tensor_fmt_t &getDataFmt () const { return data_fmt_; }
- const npumgr_tensor_data_t &getDataType () const { return data_type_; }
- const npumgr_tensor_qnt_t &getQuantType () const { return quant_type_; }
-
- private:
- static volatile guint g_buf_handle;
-
- npumgr_buffer_h handle_;
- generic_buffer gbuf_;
-
- npumgr_tensor_fmt_t data_fmt_;
- npumgr_tensor_data_t data_type_;
- npumgr_tensor_qnt_t quant_type_;
-};
-
-static data_layout
-convert_layout (const npumgr_tensor_fmt_t &fmt) {
- data_layout layout;
-
- /* unknown, relying on the model */
- layout = DATA_LAYOUT_MODEL;
- switch (fmt) {
- case NPUMGR_TENSOR_FMT_NCHW:
- layout = DATA_LAYOUT_NCHW;
- break;
- case NPUMGR_TENSOR_FMT_NHWC:
- layout = DATA_LAYOUT_NHWC;
- break;
- default:
- break;
- }
-
- return layout;
-}
-
-static data_type
-convert_type (const npumgr_tensor_data_t &data,
- const npumgr_tensor_qnt_t &qnt) {
- data_type type;
-
- /* unknown, relying on the model */
- type = DATA_TYPE_MODEL;
- switch (data) {
- case NPUMGR_TENSOR_DATA_FLOAT32:
- type = DATA_TYPE_FLOAT32;
- break;
- case NPUMGR_TENSOR_DATA_INT8:
- type = DATA_TYPE_INT8;
- break;
- case NPUMGR_TENSOR_DATA_UINT8:
- type = DATA_TYPE_UINT8;
- break;
- case NPUMGR_TENSOR_DATA_INT16:
- type = DATA_TYPE_INT16;
- break;
- case NPUMGR_TENSOR_DATA_UINT16:
- type = DATA_TYPE_UINT16;
- break;
- default:
- break;
- }
-
- if (qnt == NPUMGR_TENSOR_QNT_AFFINE_ASYMM)
- type = DATA_TYPE_QASYMM8;
-
- return type;
-}
-
-static gsize
-calc_data_size (const npumgr_tensor_data_t type) {
- switch (type) {
- case NPUMGR_TENSOR_DATA_FLOAT32:
- return 4;
- case NPUMGR_TENSOR_DATA_FLOAT16:
- return 2;
- case NPUMGR_TENSOR_DATA_INT8:
- return 1;
- case NPUMGR_TENSOR_DATA_UINT8:
- return 1;
- case NPUMGR_TENSOR_DATA_INT16:
- return 2;
- case NPUMGR_TENSOR_DATA_UINT16:
- return 2;
- case NPUMGR_TENSOR_DATA_UINT24:
- return 3;
- default:
- return 0;
- }
-}
-
-/**
- * @brief Class for triv2 npumgr network
- */
-class NpumgrNetworkTriv2 {
- public:
- NpumgrNetworkTriv2 (npudev_h dev, const npumgr_network_defn &model_file)
- : dev_ (dev),
- model_id_ (0),
- model_file_ (model_file),
- in_buffer_type_ (NPUMGR_BUF_TYPE_MAX),
- out_buffer_type_ (NPUMGR_BUF_TYPE_MAX),
- in_tensor_names_ (NULL),
- out_tensor_names_ (NULL),
- async_ (FALSE) {
- handle_ = g_atomic_int_add (&g_nw_handle, 1);
- meta_ = (npubin_meta *) g_new0 (npubin_meta, 1);
- model_file_ = model_file;
- in_buffers_.num_buffers = 0;
- out_buffers_.num_buffers = 0;
-
- memset (&in_info_, '\x00', sizeof (in_info_));
- memset (&out_info_, '\x00', sizeof (out_info_));
-
- timeout_ = default_timeout;
- g_mutex_init (&async_priv_.mutex);
- g_cond_init (&async_priv_.cond);
- async_priv_.done = FALSE;
- }
- ~NpumgrNetworkTriv2 () {
- if (model_id_ > 0)
- unregisterNPUmodel (dev_, model_id_);
-
- close (model_file_.fd);
- g_strfreev (in_tensor_names_);
- g_strfreev (out_tensor_names_);
- g_free (meta_);
- }
-
- /** @brief set input buffer type */
- void setInBufferType (npumgr_buffer_t type) { in_buffer_type_ = type; }
- /** @brief set input tensor names */
- void setInTensorNames (gchar **in_tensor_names) {
- in_tensor_names_ = g_strdupv (in_tensor_names);
- }
- gboolean loadModel () {
- generic_buffer model = {0};
-
- if (lseek (model_file_.fd, 0, SEEK_SET) < 0)
- return FALSE;
-
- if (read (model_file_.fd, (void *) meta_, NPUBIN_META_SIZE) !=
- NPUBIN_META_SIZE)
- return FALSE;
-
- if (meta_->size <= NPUBIN_META_SIZE)
- return FALSE;
-
- model.type = BUFFER_FILE;
- model.fd = model_file_.fd;
- model.size = meta_->size;
-
- if (registerNPUmodel (dev_, &model, &model_id_) != 0) {
- return FALSE;
- }
-
- in_buffers_.num_buffers = getInTensorCnt ();
- out_buffers_.num_buffers = getOutTensorCnt ();
-
- in_info_.num_info = getInTensorCnt ();
- out_info_.num_info = getOutTensorCnt ();
-
- return TRUE;
- }
-
- /** @brief set output buffer type */
- void setOutBufferType (npumgr_buffer_t type) { out_buffer_type_ = type; }
- /** @brief set output tensor names */
- void setOutTensorNames (gchar **out_tensor_names) {
- out_tensor_names_ = g_strdupv (out_tensor_names);
- }
-
- /** @brief get input tensor name */
- const gchar *getInTensorName (gint idx) { return in_tensor_names_[idx]; }
- /** @brief get output tensor name */
- const gchar *getOutTensorName (gint idx) { return out_tensor_names_[idx]; }
-
- guint getInTensorCnt () { return meta_->input_seg_num; }
- guint getOutTensorCnt () { return meta_->output_seg_num; }
-
- /** @brief get network handle */
- npumgr_network getHandle () { return handle_; }
-
- guint getInTensorDim (guint i, guint j) {
- return meta_->input_seg_dims[i][j];
- }
- guint getInTensorSize (guint i, npumgr_tensor_fmt_t fmt,
- npumgr_tensor_data_t type) {
- guint size;
-
- if (fmt == NPUMGR_TENSOR_FMT_NHWC || fmt == NPUMGR_TENSOR_FMT_NCHW) {
- size = calc_data_size (type);
- for (int j = 0; j < MAX_RANK; j++) size *= meta_->input_seg_dims[i][j];
- } else {
- int status;
-
- status = getNPUmodel_tensorSize (dev_, model_id_, true, i, &size);
- if (status != 0)
- return 0;
- }
- return size;
- }
- int32_t getInTensorQuantZero (guint i) { return meta_->input_seg_quant_z[i]; }
- float getInTensorQuantScale (guint i) { return meta_->input_seg_quant_s[i]; }
-
- guint getOutTensorDim (gint i, gint j) {
- return meta_->output_seg_dims[i][j];
- }
- guint getOutTensorSize (guint i, npumgr_tensor_fmt_t fmt,
- npumgr_tensor_data_t type) {
- guint size;
-
- if (fmt == NPUMGR_TENSOR_FMT_NHWC || fmt == NPUMGR_TENSOR_FMT_NCHW) {
- size = calc_data_size (type);
- for (int j = 0; j < MAX_RANK; j++) size *= meta_->output_seg_dims[i][j];
- } else {
- int status;
-
- status = getNPUmodel_tensorSize (dev_, model_id_, false, i, &size);
- if (status != 0)
- return 0;
- }
- return size;
- }
- int32_t getOutTensorQuantZero (gint i) {
- return meta_->output_seg_quant_z[i];
- }
- float getOutTensorQuantScale (gint i) { return meta_->output_seg_quant_s[i]; }
-
- gboolean setInput (gint index, NpumgrBufferTriv2 *buffer) {
- if (index >= in_buffers_.num_buffers)
- return FALSE;
-
- in_info_.info[index].layout = convert_layout (buffer->getDataFmt ());
- in_info_.info[index].type =
- convert_type (buffer->getDataType (), buffer->getQuantType ());
-
- memcpy (&in_buffers_.bufs[index], buffer->getGenericBuffer (),
- sizeof (generic_buffer));
- return TRUE;
- }
-
- gboolean setOutput (gint index, NpumgrBufferTriv2 *buffer) {
- if (index >= out_buffers_.num_buffers)
- return FALSE;
-
- out_info_.info[index].layout = convert_layout (buffer->getDataFmt ());
- out_info_.info[index].type =
- convert_type (buffer->getDataType (), buffer->getQuantType ());
-
- memcpy (&out_buffers_.bufs[index], buffer->getGenericBuffer (),
- sizeof (generic_buffer));
- return TRUE;
- }
-
- void setAsync (gboolean async) { async_ = async; }
- gboolean isAsync () const { return async_; }
-
- gboolean prepare () {
- return (setNPU_dataInfo (dev_, model_id_, &in_info_, &out_info_) == 0);
- }
-
- gboolean execute () {
- int req_id;
-
- if (isAsync ()) {
- async_priv_.done = FALSE;
- req_id =
- runNPU_model (dev_, model_id_, NPU_INFER_NON_BLOCKING, &in_buffers_,
- &out_buffers_, async_cb, &async_priv_);
- } else {
- req_id = runNPU_model (dev_, model_id_, NPU_INFER_BLOCKING, &in_buffers_,
- &out_buffers_, NULL, NULL);
- }
-
- return (req_id > 0);
- }
-
- gboolean wait () {
- gint64 end_time;
- gboolean result = TRUE;
-
- end_time = g_get_monotonic_time () + timeout_ * G_TIME_SPAN_MILLISECOND;
-
- g_mutex_lock (&async_priv_.mutex);
- while (async_priv_.done != TRUE) {
- if (!g_cond_wait_until (&async_priv_.cond, &async_priv_.mutex,
- end_time)) {
- result = FALSE;
- break;
- }
- }
- g_mutex_unlock (&async_priv_.mutex);
- return result;
- }
-
- private:
- static volatile guint g_nw_handle;
-
- npudev_h dev_;
-
- npumgr_network handle_;
- uint32_t model_id_;
-
- npumgr_network_defn model_file_;
- npubin_meta *meta_;
-
- npumgr_buffer_t in_buffer_type_;
- npumgr_buffer_t out_buffer_type_;
-
- gchar **in_tensor_names_;
- gchar **out_tensor_names_;
-
- input_buffers in_buffers_;
- output_buffers out_buffers_;
-
- tensors_data_info in_info_;
- tensors_data_info out_info_;
-
- gint64 timeout_;
- gboolean async_;
- async_cb_priv async_priv_;
-};
-
-static void
-nw_destroy (gpointer data) {
- NpumgrNetworkTriv2 *nw = static_cast<NpumgrNetworkTriv2 *> (data);
-
- delete nw;
-}
-
-static void
-buf_destroy (gpointer data) {
- NpumgrBufferTriv2 *buf = static_cast<NpumgrBufferTriv2 *> (data);
-
- delete buf;
-}
-
-/**
- * @brief Class for triv2 npumgr context
- */
-class NpumgrContextTriv2 {
- public:
- NpumgrContextTriv2 (npudev_h dev, int priority)
- : dev_ (dev), priority_ (priority) {
- handle_ = g_atomic_int_add (&g_ctx_handle, 1);
- nw_table_ =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, nw_destroy);
- buf_table_ = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
- buf_destroy);
- }
-
- ~NpumgrContextTriv2 () {
- g_hash_table_destroy (nw_table_);
- g_hash_table_destroy (buf_table_);
- }
-
- npudev_h getDevice () const { return dev_; }
-
- gboolean appendNetwork (npumgr_network handle, NpumgrNetworkTriv2 *nw) {
- return g_hash_table_insert (nw_table_, GSIZE_TO_POINTER (handle), nw);
- }
- gboolean removeNetwork (npumgr_network handle) {
- return g_hash_table_remove (nw_table_, GSIZE_TO_POINTER (handle));
- }
- NpumgrNetworkTriv2 *findNetwork (npumgr_network handle) {
- return (NpumgrNetworkTriv2 *) g_hash_table_lookup (
- nw_table_, GSIZE_TO_POINTER (handle));
- }
-
- gboolean executeNetwork (npumgr_network handle, gboolean async = FALSE) {
- NpumgrNetworkTriv2 *nw = findNetwork (handle);
-
- g_return_val_if_fail (nw != NULL, FALSE);
-
- nw->setAsync (async);
- return nw->execute ();
- }
-
- /* only after calling async execution */
- gboolean waitNetwork (npumgr_network handle) {
- NpumgrNetworkTriv2 *nw = findNetwork (handle);
-
- g_return_val_if_fail (nw != NULL, FALSE);
- g_return_val_if_fail (nw->isAsync (), FALSE);
-
- return nw->wait ();
- }
-
- NpumgrBufferTriv2 *findBuffer (npumgr_buffer_h handle) {
- return (NpumgrBufferTriv2 *) g_hash_table_lookup (
- buf_table_, GSIZE_TO_POINTER (handle));
- }
-
- gboolean allocBuffer (npumgr_query_tensor_attr *param, npumgr_buffer *buf) {
- generic_buffer gbuf = {0};
-
- gbuf.type = BUFFER_MAPPED;
- gbuf.size = param->size;
-
- if (allocNPU_genericBuffer (dev_, &gbuf) != 0)
- return FALSE;
-
- NpumgrBufferTriv2 *nbuf = new NpumgrBufferTriv2 (gbuf);
- nbuf->setDataFmt (param->fmt);
- nbuf->setDataType (param->type);
- nbuf->setQuantType (param->quant_type);
-
- if (!g_hash_table_insert (buf_table_, GSIZE_TO_POINTER (nbuf->getHandle ()),
- nbuf)) {
- cleanNPU_genericBuffer (dev_, &gbuf);
- delete nbuf;
- return FALSE;
- }
-
- buf->buf_handle = nbuf->getHandle ();
- buf->buf_fd = nbuf->getDbufFD ();
- buf->buf_size = nbuf->getSize ();
- buf->buf_offset = 0;
-
- return TRUE;
- }
-
- gboolean destroyBuffer (npumgr_buffer *buf) {
- NpumgrBufferTriv2 *nbuf = findBuffer (buf->buf_handle);
- g_return_val_if_fail (nbuf != NULL, FALSE);
-
- generic_buffer *gbuf = nbuf->getGenericBuffer ();
- g_return_val_if_fail (gbuf != NULL, FALSE);
-
- if (cleanNPU_genericBuffer (dev_, gbuf) != 0)
- return FALSE;
-
- return g_hash_table_remove (buf_table_, GSIZE_TO_POINTER (buf->buf_handle));
- }
-
- gboolean mapBuffer (npumgr_buffer *buf, uint8_t **mapped_addr) {
- /* NYI */
- return TRUE;
- }
-
- npumgr_context getHandle () { return handle_; }
-
- private:
- static volatile guint g_ctx_handle;
-
- npumgr_context handle_;
- npudev_h dev_;
- int priority_;
-
- GHashTable *nw_table_;
- GHashTable *buf_table_;
-};
-
-static void
-ctx_destroy (gpointer data) {
- NpumgrContextTriv2 *ctx = static_cast<NpumgrContextTriv2 *> (data);
-
- delete ctx;
-}
-
-volatile guint NpumgrContextTriv2::g_ctx_handle = 1;
-volatile guint NpumgrNetworkTriv2::g_nw_handle = 1;
-volatile guint NpumgrBufferTriv2::g_buf_handle = 1;
-
-/**
- * @brief Private members in NpumgrDeviceTriv2
- */
-struct _NpumgrDeviceTriv2Private {
- npudev_h dev;
- GMutex mutex;
- GHashTable *ctx_table;
-};
-
-#define NPUMGR_DEVICE(obj) &((obj)->parent)
-#define NPUMGR_DEVICE_TRIV2_GET_PRIVATE(obj) \
- ((NpumgrDeviceTriv2Private *) g_type_instance_get_private ( \
- (GTypeInstance *) obj, NPUMGR_TYPE_DEVICE_TRIV2))
-
-G_DEFINE_TYPE_WITH_PRIVATE (NpumgrDeviceTriv2, npumgr_device_triv2,
- NPUMGR_TYPE_DEVICE);
-
-/* GObject */
-static void triv2_finalize (GObject *object);
-/* NpumgrDevice */
-static npumgr_status_e triv2_device_get_capabilities (
- NpumgrDevice *device, guint *caps, npumgr_device_type_t *ptype);
-static npumgr_status_e triv2_context_create (NpumgrDevice *device,
- int device_id, int priority,
- npumgr_context *out_ctx);
-static npumgr_status_e triv2_context_destroy (NpumgrDevice *device,
- npumgr_context ctx);
-static npumgr_status_e triv2_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);
-static npumgr_status_e triv2_network_set_input (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle,
- int index,
- npumgr_buffer *input_buffer);
-static npumgr_status_e triv2_network_set_output (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle,
- int index,
- npumgr_buffer *output_buffer);
-static npumgr_status_e triv2_network_prepare (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle);
-static npumgr_status_e triv2_network_destroy (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle);
-static npumgr_status_e triv2_buffer_create (
- NpumgrDevice *device, npumgr_context ctx,
- npumgr_query_tensor_attr *create_param, npumgr_buffer *buf);
-static npumgr_status_e triv2_buffer_destroy (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_buffer *buf);
-static npumgr_status_e triv2_buffer_map (NpumgrDevice *device,
- npumgr_context ctx, npumgr_buffer *buf,
- uint8_t **mapped_addr);
-static npumgr_status_e triv2_buffer_unmap (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_buffer *buf);
-
-static npumgr_status_e triv2_query_network (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle,
- npumgr_query_inout_num *data);
-static npumgr_status_e triv2_query_input (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle, int index,
- npumgr_query_tensor_attr *data);
-static npumgr_status_e triv2_query_output (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle, int index,
- npumgr_query_tensor_attr *data);
-static npumgr_status_e triv2_execute_trigger (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle);
-static npumgr_status_e triv2_execute_wait (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle);
-static npumgr_status_e triv2_execute_run (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle);
-
-static npumgr_status_e triv2_execute_realtime (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle,
- uint32_t task_handle,
- uint32_t subtask_id);
-static npumgr_status_e triv2_execute_wait_realtime (NpumgrDevice *device,
- npumgr_context ctx,
- npumgr_network nw_handle,
- uint32_t *golden_val,
- uint32_t **golden_addr);
-static npumgr_status_e triv2_execute_completed_realtime (
- NpumgrDevice *device, npumgr_context ctx, npumgr_network nw_handle);
-
-extern NpumgrDevice *
-npumgr_device_triv2_new (void) {
- gpointer instance = g_object_new (NPUMGR_TYPE_DEVICE_TRIV2, NULL);
-
- return NPUMGR_DEVICE ((NpumgrDeviceTriv2 *) instance);
-}
-
-static void
-npumgr_device_triv2_class_init (NpumgrDeviceTriv2Class *klass) {
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- NpumgrDeviceClass *npumgr_device_class = &(klass->parent_class);
-
- /* GObject */
- gobject_class->finalize = triv2_finalize;
- /* NpumgrDevice */
- npumgr_device_class->device_get_capabilities = triv2_device_get_capabilities;
- npumgr_device_class->context_create = triv2_context_create;
- npumgr_device_class->context_destroy = triv2_context_destroy;
- npumgr_device_class->network_create = triv2_network_create;
- npumgr_device_class->network_set_input = triv2_network_set_input;
- npumgr_device_class->network_set_output = triv2_network_set_output;
- npumgr_device_class->network_prepare = triv2_network_prepare;
- npumgr_device_class->network_destroy = triv2_network_destroy;
- npumgr_device_class->buffer_create = triv2_buffer_create;
- npumgr_device_class->buffer_destroy = triv2_buffer_destroy;
- npumgr_device_class->buffer_map = triv2_buffer_map;
- npumgr_device_class->buffer_unmap = triv2_buffer_unmap;
- npumgr_device_class->query_network = triv2_query_network;
- npumgr_device_class->query_input = triv2_query_input;
- npumgr_device_class->query_output = triv2_query_output;
-
- npumgr_device_class->execute_trigger = triv2_execute_trigger;
- npumgr_device_class->execute_wait = triv2_execute_wait;
- npumgr_device_class->execute_run = triv2_execute_run;
- npumgr_device_class->execute_realtime = triv2_execute_realtime;
- npumgr_device_class->execute_wait_realtime = triv2_execute_wait_realtime;
- npumgr_device_class->execute_completed_realtime =
- triv2_execute_completed_realtime;
-
- /* NYI */
-}
-
-static void
-npumgr_device_triv2_init (NpumgrDeviceTriv2 *self) {
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- int status;
-
- memset (priv, '\x00', sizeof (*priv));
- g_mutex_init (&priv->mutex);
- priv->ctx_table =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, ctx_destroy);
-
- /** TODO: How npumgr supports multiple TRIV2 devices? */
- status = getNPUdeviceByTypeAny (&priv->dev, NPUCOND_TRIV2_CONN_SOCIP, 2);
- if (status != 0) {
- g_critical ("Unable to find/open 2-TOPS TRIV2 device\n");
- return;
- }
-}
-
-static void
-triv2_finalize (GObject *object) {
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (object);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- g_mutex_clear (&priv->mutex);
- g_hash_table_destroy (priv->ctx_table);
-
- if (priv->dev)
- putNPUdevice (priv->dev);
-}
-
-/* Filling the virtual function table of TRIV2 */
-static npumgr_status_e
-triv2_device_get_capabilities (NpumgrDevice *device, guint *caps,
- npumgr_device_type_t *ptype) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (caps != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ptype != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- g_return_val_if_fail (priv->dev != NULL,
- NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE);
-
- *caps = NPUMGR_DEVICE_CAPABILITY_MMAP |
- NPUMGR_DEVICE_CAPABILITY_MULTICONTEXT | NPUMGR_DEVICE_CAPABILITY_MMU |
- NPUMGR_DEVICE_CAPABILITY_REALTIME;
- *ptype = NPUMGR_DEVICE_TYPE_NPU;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static gboolean
-insert_context (NpumgrDeviceTriv2Private *priv, npumgr_context handle,
- NpumgrContextTriv2 *context) {
- gboolean result;
-
- g_mutex_lock (&priv->mutex);
- result =
- g_hash_table_insert (priv->ctx_table, GSIZE_TO_POINTER (handle), context);
- g_mutex_unlock (&priv->mutex);
-
- return result;
-}
-
-static gboolean
-remove_context (NpumgrDeviceTriv2Private *priv, npumgr_context handle) {
- gboolean result;
-
- g_mutex_lock (&priv->mutex);
- result = g_hash_table_remove (priv->ctx_table, GSIZE_TO_POINTER (handle));
- g_mutex_unlock (&priv->mutex);
-
- return result;
-}
-
-static NpumgrContextTriv2 *
-find_context (NpumgrDeviceTriv2Private *priv, npumgr_context handle) {
- NpumgrContextTriv2 *context;
-
- g_mutex_lock (&priv->mutex);
- context = (NpumgrContextTriv2 *) g_hash_table_lookup (
- priv->ctx_table, GSIZE_TO_POINTER (handle));
- g_mutex_unlock (&priv->mutex);
-
- return context;
-}
-
-static npumgr_status_e
-triv2_context_create (NpumgrDevice *device, int device_id, int priority,
- npumgr_context *ctx_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- g_return_val_if_fail (priv->dev != NULL,
- NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE);
-
- NpumgrContextTriv2 *context = new NpumgrContextTriv2 (priv->dev, priority);
- *ctx_handle = context->getHandle ();
-
- if (!insert_context (priv, context->getHandle (), context))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_context_destroy (NpumgrDevice *device, npumgr_context ctx_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- if (!remove_context (priv, ctx_handle))
- return NPUMGR_STATUS_ERR_CTX_INVALID;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_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) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (num_files == 1, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (input_files != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (in_tensor_cnt != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (input_tensor_names != NULL,
- NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (out_tensor_cnt != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (output_tensor_names != NULL,
- NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (out_nw != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- NpumgrContextTriv2 *context = find_context (priv, ctx);
-
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network =
- new NpumgrNetworkTriv2 (context->getDevice (), input_files[0]);
- if (!network->loadModel ())
- goto err;
- if (network->getInTensorCnt () != in_tensor_cnt)
- goto err;
- if (network->getOutTensorCnt () != out_tensor_cnt)
- goto err;
-
- network->setInTensorNames (input_tensor_names);
- network->setOutTensorNames (output_tensor_names);
- network->setInBufferType (in_buffer_type);
- network->setOutBufferType (out_buffer_type);
-
- if (context->appendNetwork (network->getHandle (), network)) {
- *out_nw = network->getHandle ();
- return NPUMGR_STATUS_SUCCESS;
- }
-
-err:
- delete network;
- return NPUMGR_STATUS_ERR_FAIL;
-}
-
-static npumgr_status_e
-triv2_network_set_input (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle, int index,
- npumgr_buffer *buf) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
- g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
- g_return_val_if_fail (network->getInTensorCnt () > index,
- NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrBufferTriv2 *buffer = context->findBuffer (buf->buf_handle);
- g_return_val_if_fail (buffer != NULL, NPUMGR_STATUS_ERR_FAIL);
-
- if (!network->setInput (index, buffer))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_network_set_output (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle, int index,
- npumgr_buffer *buf) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
- g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
- g_return_val_if_fail (network->getOutTensorCnt () > index,
- NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrBufferTriv2 *buffer = context->findBuffer (buf->buf_handle);
- g_return_val_if_fail (buffer != NULL, NPUMGR_STATUS_ERR_FAIL);
-
- if (!network->setOutput (index, buffer))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_network_prepare (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
- g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
-
- if (!network->prepare ())
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_network_destroy (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
-
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->removeNetwork (nw_handle))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_buffer_create (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_query_tensor_attr *create_param,
- npumgr_buffer *buf) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (create_param != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->allocBuffer (create_param, buf))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_buffer_destroy (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_buffer *buf) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->destroyBuffer (buf))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_buffer_map (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_buffer *buf, uint8_t **mapped_addr) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (buf != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (mapped_addr != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->mapBuffer (buf, mapped_addr))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_buffer_unmap (NpumgrDevice *device, npumgr_context ctx,
- npumgr_buffer *buf) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_query_network (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle,
- npumgr_query_inout_num *inout_num) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (inout_num != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
- g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
-
- inout_num->n_input = network->getInTensorCnt ();
- inout_num->n_output = network->getOutTensorCnt ();
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_query_input (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle, int index,
- npumgr_query_tensor_attr *attr) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (index >= 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (attr != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
- g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
-
- attr->n_dims = MAX_RANK;
- for (guint rank = 0; rank < MAX_RANK; rank++)
- attr->dims[rank] = network->getInTensorDim (index, rank);
- g_snprintf (attr->name, NPUMGR_MAX_NAME_LEN, "%s",
- network->getInTensorName (index));
-
- /* FIXME: their exact meaning and usage? */
- for (guint rank = 0; rank < MAX_RANK; rank++) attr->strides[rank] = 1;
- attr->plane = 3;
-
- attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
- attr->type = NPUMGR_TENSOR_DATA_UINT8;
- attr->size = network->getInTensorSize (index, attr->fmt, attr->type);
-
- attr->quant_type = NPUMGR_TENSOR_QNT_AFFINE_ASYMM;
- attr->quant_data.affine.scale = network->getInTensorQuantScale (index);
- attr->quant_data.affine.zeroPoint = network->getInTensorQuantZero (index);
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_query_output (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle, int index,
- npumgr_query_tensor_attr *attr) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (index >= 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (attr != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
-
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- NpumgrNetworkTriv2 *network = context->findNetwork (nw_handle);
- g_return_val_if_fail (network != NULL, NPUMGR_STATUS_ERR_MODEL_INVALID);
-
- attr->n_dims = MAX_RANK;
- for (guint rank = 0; rank < MAX_RANK; rank++)
- attr->dims[rank] = network->getOutTensorDim (index, rank);
- g_snprintf (attr->name, NPUMGR_MAX_NAME_LEN, "%s",
- network->getOutTensorName (index));
-
- /* FIXME: their exact meaning and usage? */
- for (guint rank = 0; rank < MAX_RANK; rank++) attr->strides[rank] = 1;
- attr->plane = 3;
-
- attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
- attr->type = NPUMGR_TENSOR_DATA_UINT8;
- attr->size = network->getOutTensorSize (index, attr->fmt, attr->type);
-
- attr->quant_type = NPUMGR_TENSOR_QNT_AFFINE_ASYMM;
- attr->quant_data.affine.scale = network->getOutTensorQuantScale (index);
- attr->quant_data.affine.zeroPoint = network->getOutTensorQuantZero (index);
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_execute_trigger (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
-
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->executeNetwork (nw_handle, TRUE))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_execute_wait (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
-
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->waitNetwork (nw_handle))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_execute_run (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle) {
- g_return_val_if_fail (device != NULL, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (ctx_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
- g_return_val_if_fail (nw_handle != 0, NPUMGR_STATUS_ERR_PARAM_INVALID);
-
- NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
- NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- NpumgrContextTriv2 *context = find_context (priv, ctx_handle);
-
- g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
-
- if (!context->executeNetwork (nw_handle))
- return NPUMGR_STATUS_ERR_FAIL;
-
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_execute_realtime (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle, uint32_t task_handle,
- uint32_t subtask_id) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_execute_wait_realtime (NpumgrDevice *device, npumgr_context ctx_handle,
- npumgr_network nw_handle, uint32_t *golden_val,
- uint32_t **golden_addr) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
-}
-
-static npumgr_status_e
-triv2_execute_completed_realtime (NpumgrDevice *device,
- npumgr_context ctx_handle,
- npumgr_network nw_handle) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
-}
+++ /dev/null
-/**
- * Proprietary
- * Copyright (C) 2021 Samsung Electronics
- * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
- */
-/**
- * @file npumgr_triv2.h
- * @date 03 May 2021
- * @brief Internal header of TRIV2 device plugin
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#ifndef __NPUMGR_TRIV2_H__
-#define __NPUMGR_TRIV2_H__
-
-/* npumgr device API */
-#include <npumgr_device.h>
-
-G_BEGIN_DECLS
-
-#define NPUMGR_TYPE_DEVICE_TRIV2 (npumgr_device_triv2_get_type ())
-#define NPUMGR_DEVICE_TRIV2(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), NPUMGR_TYPE_DEVICE_TRIV2, \
- NpumgrDeviceTriv2))
-
-typedef struct _NpumgrDeviceTriv2 NpumgrDeviceTriv2;
-typedef struct _NpumgrDeviceTriv2Class NpumgrDeviceTriv2Class;
-typedef struct _NpumgrDeviceTriv2Private NpumgrDeviceTriv2Private;
-
-/**
- * @brief npumgr device class for TRIV2.
- *
- * NpumgrDeviceTriv2 inherits NpumgrDevice.
- */
-struct _NpumgrDeviceTriv2 {
- NpumgrDevice parent; /**< parent class object */
-};
-
-/**
- * @brief NpumgrDeviceTriv2Class data structure.
- *
- * NpumgrDeviceTriv2Class inherits NpumgrDeviceClass.
- */
-struct _NpumgrDeviceTriv2Class {
- NpumgrDeviceClass parent_class; /**< inherits class object */
-};
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
-"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-
-<!--
- This is a sample D-Bus configuration to test VD NPUMGR dummy module.
- Please locate this file to your D-Bus system bus policy directory.
- (e.g., /usr/share/dbus-1/system.d/sr.odl.NPUManager.conf)
-
- Example command line for testing:
- $ /usr/lib64/npu-engine/bin/apptests/npumgr/dummy_npumgr
- $ /usr/lib64/npu-engine/bin/apptests/npumgr/apptest_npumgr \
- /usr/share/npu-engine/testdata/TRIV235_2TOPS/MOBILENET_V1
--->
-
-<busconfig>
- <policy user="root">
- <allow own="sr.odl.NPUManager.API"/>
- </policy>
- <policy context="default">
- <allow send_path="/sr/org/NPUManager/APIObject"/>
- <allow send_destination="sr.odl.NPUManager.API"/>
- <allow receive_sender="sr.odl.NPUManager.API"/>
- </policy>
-</busconfig>
+++ /dev/null
-glib_dep = dependency('glib-2.0', required: false)
-if glib_dep.found()
- if get_option('enable_vd_npumgr')
- # vd npu manager
- npumgr_dep = dependency('tizen-npumanager')
- else
- # dummy npu manager
- subdir('dummy')
- endif
-
- # npu manager test program
- executable ('apptest_npumgr',
- 'npumgr_test.cc',
- dependencies : [glib_dep, ne_test_utils_common_dep, npumgr_dep],
- install : true,
- install_rpath : ne_libdir,
- install_dir : join_paths(ne_bindir, 'apptests', 'npumgr')
- )
-endif
+++ /dev/null
-/**
- * Proprietary
- * Copyright (C) 2021 Samsung Electronics
- * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
- */
-/**
- * @file npumgr_common.h
- * @date 10 May 2021
- * @brief npumgr common header
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#ifndef __NPUMGR_COMMON_H__
-#define __NPUMGR_COMMON_H__
-
-#include <sys/mman.h>
-#include <sys/user.h> /* PAGE_SIZE */
-
-#ifndef PAGE_SHIFT
-#define PAGE_SHIFT (12)
-#endif
-#ifndef PAGE_SIZE
-
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
-#endif
-#ifndef PFN_UP
-
-#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
-#endif
-#define ALIGNED_SIZE(x) (PFN_UP (x) * PAGE_SIZE)
-
-#endif
+++ /dev/null
-/**
- * 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 <fcntl.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <ne_test_utils_common.h>
-
-#include <npumgr_api.h>
-#include "npumgr_common.h"
-
-using namespace std;
-
-static int
-start_npumgr_test (int fd, const string &dir) {
- npumgr_devices_id list;
- npumgr_status_e status;
-
- npumgr_context context;
- npumgr_network network;
-
- npumgr_buffer *input_bufs = NULL;
- npumgr_buffer *output_bufs = NULL;
- npumgr_query_inout_num inout_num = {0};
-
- npumgr_network_defn input_files[] = {{NPUMGR_NETWORK_FILE_TVN, fd}};
- const char *input_tensor_names[] = {"input"};
- const char *output_tensor_names[] = {"output"};
- npumgr_query_tensor_attr attr;
-
- status = npumgr_device_get_available_list (&list);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to get available device list, " << status << "\n";
- return status;
- }
-
- /* TODO: find the first NPU device */
- bool found = false;
- uint32_t id;
-
- for (int i = 0; i < list.n_devices; i++) {
- if (list.types[i] == NPUMGR_DEVICE_TYPE_NPU) {
- found = true;
- id = list.id[i];
- break;
- }
- }
-
- if (!found) {
- cerr << "No available device\n";
- return NPUMGR_STATUS_ERR_DEVICE_UNAVAILABLE;
- }
-
- status = npumgr_context_create (id, NPUMGR_FLAG_PRIORITY_DEFAULT, &context);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to create a npumgr context, " << status << "\n";
- return NPUMGR_STATUS_ERR_FAIL;
- }
-
- status = npumgr_network_create (
- context, 1, input_files, NPUMGR_BUF_TYPE_DRIVER, 1, input_tensor_names,
- NPUMGR_BUF_TYPE_DRIVER, 1, output_tensor_names, &network);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to create a npumgr network, " << status << "\n";
- goto destroy_ctx;
- }
-
- status = npumgr_query_network (context, network, &inout_num);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to query network info, " << status << "\n";
- goto destroy_nw;
- }
-
- input_bufs = g_new0 (npumgr_buffer, inout_num.n_input);
- output_bufs = g_new0 (npumgr_buffer, inout_num.n_output);
-
- for (int i = 0; i < inout_num.n_input; i++) {
- string file_path = dir + "/input_fmap_" + to_string (i) + ".bin";
- FILE *f = fopen (file_path.c_str (), "rb");
- void *data = NULL;
-
- if (f == NULL) {
- cerr << "Unable to find input file, " << file_path << "\n";
- fclose (f);
- goto destroy_all;
- }
-
- status = npumgr_query_input (context, network, i, &attr);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to query input info, " << status << "\n";
- fclose (f);
- goto destroy_all;
- }
-
- /** TODO: currently, support NHWC format only */
- if (attr.fmt != NPUMGR_TENSOR_FMT_NHWC) {
- cerr << "Other format is not supported yet, " << attr.fmt << "\n";
- fclose (f);
- goto destroy_all;
- }
-
- status = npumgr_buffer_create (context, &attr, &input_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to create input buffer, " << status << "\n";
- fclose (f);
- goto destroy_all;
- }
-
- status = npumgr_buffer_map (context, &input_bufs[i], (uint8_t **) &data);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to map input buffer, " << status << "\n";
- fclose (f);
- goto destroy_all;
- }
-
- size_t read_bytes = fread (data, 1, input_bufs[i].buf_size, f);
- if (read_bytes != input_bufs[i].buf_size) {
- cerr << "Unable to read input data, " << read_bytes << " vs. "
- << input_bufs[i].buf_size << "\n";
- fclose (f);
- goto destroy_all;
- }
- fclose (f);
-
- /** TODO: How unmap works? */
-#if 0
- status = npumgr_buffer_unmap (context, &input_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to unmap buffer, " << status << "\n";
- goto destroy_all;
- }
-#else
- munmap (data, ALIGNED_SIZE (input_bufs[i].buf_size));
-#endif
-
- status = npumgr_network_set_input (context, network, i, &input_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to set input, " << status << "\n";
- goto destroy_all;
- }
- }
-
- for (int i = 0; i < inout_num.n_output; i++) {
- status = npumgr_query_output (context, network, i, &attr);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to query output info, " << status << "\n";
- goto destroy_all;
- }
-
- /** TODO: currently, support NHWC format only */
- if (attr.fmt != NPUMGR_TENSOR_FMT_NHWC) {
- cerr << "Other format is not supported yet, " << attr.fmt << "\n";
- goto destroy_all;
- }
-
- status = npumgr_buffer_create (context, &attr, &output_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to create output buffer, " << status << "\n";
- goto destroy_all;
- }
-
- status = npumgr_network_set_output (context, network, i, &output_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to set output, " << status << "\n";
- goto destroy_all;
- }
- }
-
- status = npumgr_network_prepare (context, network);
- if (status != NPUMGR_STATUS_SUCCESS) {
- goto destroy_all;
- }
-
- status = npumgr_execute_run (context, network);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to execute the network, " << status << "\n";
- goto destroy_all;
- }
-
- for (int i = 0; i < inout_num.n_output; i++) {
- string file_path = string (dir) + "/output_fmap_" + to_string (i) + ".bin";
- void *data = NULL;
-
- status = npumgr_buffer_map (context, &output_bufs[i], (uint8_t **) &data);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to map output buffer, " << status << "\n";
- goto destroy_all;
- }
-
- if (compare_data (file_path.c_str (), (const char *) data,
- output_bufs[i].buf_size) != 0) {
- cerr << "Failed to get valid output data\n";
- goto destroy_all;
- }
-
- /** TODO: How unmap works? */
-#if 0
- status = npumgr_buffer_unmap (context, &output_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- cerr << "Unable to unmap output buffer, " << status << "\n";
- goto destroy_all;
- }
-#else
- munmap (data, ALIGNED_SIZE (output_bufs[i].buf_size));
-#endif
- }
-
-destroy_all:
- if (input_bufs) {
- for (int i = 0; i < inout_num.n_input; i++) {
- if (input_bufs[i].buf_handle == 0)
- continue;
-
- status = npumgr_buffer_destroy (context, &input_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS)
- cerr << "Unable to destroy the buffer, " << status << "\n";
- }
- }
-
- if (output_bufs) {
- for (int i = 0; i < inout_num.n_output; i++) {
- if (output_bufs[i].buf_handle == 0)
- continue;
-
- status = npumgr_buffer_destroy (context, &output_bufs[i]);
- if (status != NPUMGR_STATUS_SUCCESS)
- cerr << "Unable to destroy the buffer, " << status << "\n";
- }
- }
-
-destroy_nw:
- status = npumgr_network_destroy (context, network);
- if (status != NPUMGR_STATUS_SUCCESS)
- cerr << "Unable to destroy the npumgr network, " << status << "\n";
-
-destroy_ctx:
- status = npumgr_context_destroy (context);
- if (status != NPUMGR_STATUS_SUCCESS)
- cerr << "Unable to destroy the npumgr context, " << status << "\n";
-
- return status;
-}
-
-int
-main (int argc, char **argv) {
- int fd, ret = -EINVAL;
-
- if (argc != 2) {
- cerr << "Please provide model datapath (i.e., including .tvn and .bin)\n";
- cerr << "[APPTEST] " << argv[0] << ": SKIPPED\n";
- return 0;
- }
-
- string dir (argv[1]);
- string model_path = dir + "/model.tvn";
-
- if (!g_file_test (dir.c_str (), G_FILE_TEST_IS_DIR)) {
- cerr << "Invalid model datapath: " << dir << "\n";
- goto out;
- }
-
- fd = open (model_path.c_str (), O_RDONLY);
- if (fd < 0) {
- cerr << "Unable to open file " << dir << "\n";
- goto out;
- }
-
- ret = start_npumgr_test (fd, dir);
- close (fd);
-
-out:
- if (ret == 0)
- cerr << "[APPTEST] " << argv[0] << ": PASSED\n";
- else
- cerr << "[APPTEST] " << argv[0] << ": FAILED (" << ret << ")\n";
-
- return ret;
-}