This patch implements network execute APIs of VD NPUMGR.
Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
%build
meson --buildtype=plain --bindir=%{neexampledir} --prefix=%{_prefix} \
- --sysconfdir=%{_sysconfdir} --libdir=%{_libdir} --includedir=%{_includedir} \
+ --libdir=%{_libdir} --includedir=%{_includedir} \
+ --datadir=%{_datadir} --sysconfdir=%{_sysconfdir} \
-Denable_tizen=true -Denable_data_manip=true %{enable_npu_emul} \
build
ninja -C build %{?_smp_mflags}
%{neexampledir}/unittests/*
%{neexampledir}/apptests/*
%{_libdir}/libnpumgr*.so
+%{_datadir}/dbus-1/system.d/*
%package utils
Requires: npu-engine = %{version}-%{release}
executable ('apptest_npumgr',
'npumgr_test.cc',
- dependencies : glib_dep,
+ dependencies : [glib_dep, ne_test_utils_common_dep],
link_with : npumgr_lib,
install : true,
install_rpath : ne_libdir,
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
" <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>";
if (context == NULL) {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
- "Unable to add network");
+ "Unable to find context");
return;
}
NpumgrDevice *device = context->device;
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");
+ }
}
}
*/
npumgr_status_e
npumgr_execute_trigger (npumgr_context ctx, npumgr_network nw_handle) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
+ 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;
}
/**
*/
npumgr_status_e
npumgr_execute_wait (npumgr_context ctx, npumgr_network nw_handle) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
+ 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;
}
/**
*/
npumgr_status_e
npumgr_execute_run (npumgr_context ctx, npumgr_network nw_handle) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
+ 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;
}
/**
#include <unistd.h>
#include <glib.h>
+#include <ne_test_utils_common.h>
#include "npumgr_api.h"
+#include "npumgr_common.h"
-int
-main (int argc, char **argv) {
- npumgr_context context;
- npumgr_network network;
+using namespace std;
+
+static int
+start_npumgr_test (int fd, const string &dir) {
npumgr_devices_id list;
npumgr_status_e status;
- int fd, ret = -EINVAL;
- if (argc != 2) {
- std::cerr << "Please provide network file name (.tvn)\n";
- return ret;
- }
+ npumgr_context context;
+ npumgr_network network;
- if (!g_str_has_suffix (argv[1], ".tvn")) {
- std::cerr << "Invalid model path: " << argv[1] << "\n";
- return ret;
- }
+ 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) {
- std::cerr << "Unable to get available device list, " << status << "\n";
- return ret;
+ cerr << "Unable to get available device list, " << status << "\n";
+ return status;
}
/* TODO: find the first NPU device */
}
if (!found) {
- std::cerr << "No available device\n";
- return ret;
+ 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) {
- std::cerr << "Unable to create a npumgr context, " << status << "\n";
- return ret;
- }
-
- fd = open (argv[1], O_RDONLY);
- if (fd >= 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_inout_num inout_num;
- npumgr_query_tensor_attr *input_attr;
- npumgr_query_tensor_attr *output_attr;
-
- 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);
+ 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 TRIV2 (NHWC-based) format */
+ if (attr.fmt != NPUMGR_TENSOR_FMT_TRIV2) {
+ 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) {
- std::cerr << "Unable to create a npumgr network, " << status << "\n";
- goto out;
+ cerr << "Unable to create input buffer, " << status << "\n";
+ fclose (f);
+ goto destroy_all;
}
- status = npumgr_query_network (context, network, &inout_num);
+ status = npumgr_buffer_map (context, &input_bufs[i], (uint8_t **) &data);
if (status != NPUMGR_STATUS_SUCCESS) {
- std::cerr << "Unable to query network info, " << status << "\n";
- goto out;
+ cerr << "Unable to map input buffer, " << status << "\n";
+ fclose (f);
+ goto destroy_all;
}
- input_attr = g_new0 (npumgr_query_tensor_attr, inout_num.n_input);
- output_attr = g_new0 (npumgr_query_tensor_attr, inout_num.n_input);
+ 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);
- for (uint32_t i = 0; i < inout_num.n_input; i++) {
- status = npumgr_query_input (context, network, i, &input_attr[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- std::cerr << "Unable to query input info, " << status << "\n";
- g_free (input_attr);
- g_free (output_attr);
- goto out;
- }
+ /** 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
- for (uint32_t i = 0; i < inout_num.n_output; i++) {
- status = npumgr_query_output (context, network, i, &output_attr[i]);
- if (status != NPUMGR_STATUS_SUCCESS) {
- std::cerr << "Unable to query output info, " << status << "\n";
- g_free (input_attr);
- g_free (output_attr);
- goto out;
- }
+ 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;
}
+ }
- /* NYI: DO SOMETHING */
+ 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;
+ }
- g_free (input_attr);
- g_free (output_attr);
+ /** TODO: currently, support TRIV2 (NHWC-based) format */
+ if (attr.fmt != NPUMGR_TENSOR_FMT_TRIV2) {
+ cerr << "Other format is not supported yet, " << attr.fmt << "\n";
+ goto destroy_all;
+ }
- status = npumgr_network_destroy (context, network);
+ status = npumgr_buffer_create (context, &attr, &output_bufs[i]);
if (status != NPUMGR_STATUS_SUCCESS) {
- std::cerr << "Unable to destroy the npumgr network, " << status << "\n";
- goto out;
+ cerr << "Unable to create output buffer, " << status << "\n";
+ goto destroy_all;
}
- ret = 0;
- } else {
- std::cerr << "Unable to open file " << argv[1] << "\n";
+ 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;
+ }
}
-out:
- if (fd >= 0)
- close (fd);
+ status = npumgr_network_prepare (context, network);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ goto destroy_all;
+ }
- status = npumgr_context_destroy (context);
+ status = npumgr_execute_run (context, network);
if (status != NPUMGR_STATUS_SUCCESS) {
- std::cerr << "Unable to destroy the npumgr context, " << status << "\n";
- return ret;
+ 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;
}
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
*/
in_buffer_type_ (NPUMGR_BUF_TYPE_MAX),
out_buffer_type_ (NPUMGR_BUF_TYPE_MAX),
in_tensor_names_ (NULL),
- out_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;
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)
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;
tensors_data_info in_info_;
tensors_data_info out_info_;
+
+ gint64 timeout_;
+ gboolean async_;
+ async_cb_priv async_priv_;
};
static void
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));
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_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) {
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 */
}
status = getNPUdeviceByTypeAny (&priv->dev, NPUCOND_TRIV2_CONN_SOCIP, 2);
if (status != 0) {
g_critical ("Unable to find/open 2-TOPS TRIV2 device\n");
- priv->dev = NULL;
return;
}
- /* NYI */
}
static void
NpumgrContextTriv2 *context = new NpumgrContextTriv2 (priv->dev, priority);
*ctx_handle = context->getHandle ();
- if (insert_context (priv, context->getHandle (), context)) {
- return NPUMGR_STATUS_SUCCESS;
- } else {
+ if (!insert_context (priv, context->getHandle (), context))
return NPUMGR_STATUS_ERR_FAIL;
- }
+
+ return NPUMGR_STATUS_SUCCESS;
}
static npumgr_status_e
NpumgrDeviceTriv2 *self = NPUMGR_DEVICE_TRIV2 (device);
NpumgrDeviceTriv2Private *priv = NPUMGR_DEVICE_TRIV2_GET_PRIVATE (self);
- if (remove_context (priv, ctx_handle))
- return NPUMGR_STATUS_SUCCESS;
- else
+ if (!remove_context (priv, ctx_handle))
return NPUMGR_STATUS_ERR_CTX_INVALID;
+
+ return NPUMGR_STATUS_SUCCESS;
}
static npumgr_status_e
g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID);
- if (context->removeNetwork (nw_handle)) {
- return NPUMGR_STATUS_SUCCESS;
- } else {
+ if (!context->removeNetwork (nw_handle))
return NPUMGR_STATUS_ERR_FAIL;
- }
+
+ return NPUMGR_STATUS_SUCCESS;
}
static npumgr_status_e
attr->plane = 3;
attr->size = network->getInTensorSize (index);
- attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
+ attr->fmt = NPUMGR_TENSOR_FMT_TRIV2;
attr->type = NPUMGR_TENSOR_DATA_UINT8;
attr->quant_type = NPUMGR_TENSOR_QNT_AFFINE_ASYMM;
attr->plane = 3;
attr->size = network->getOutTensorSize (index);
- attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
+ attr->fmt = NPUMGR_TENSOR_FMT_TRIV2;
attr->type = NPUMGR_TENSOR_DATA_UINT8;
attr->quant_type = NPUMGR_TENSOR_QNT_AFFINE_ASYMM;
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
+<!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>