From 8ab640b5413922c72bd207703b32b3e0bc453a8d Mon Sep 17 00:00:00 2001 From: Dongju Chae Date: Tue, 25 May 2021 13:06:23 +0900 Subject: [PATCH] [VD/NPUMGR] Implement buffer-related APIs This patch implement buffer-related APIs and its backend modules. Signed-off-by: Dongju Chae --- src/core/ne-mem.cc | 6 +- tests/apptests/npumgr/npumgr.cc | 297 +++++++++++++++++++++++ tests/apptests/npumgr/npumgr_api.cc | 292 +++++++++++++++++++++- tests/apptests/npumgr/npumgr_api.h | 1 + tests/apptests/npumgr/npumgr_common.h | 33 +++ tests/apptests/npumgr/npumgr_triv2.cc | 444 +++++++++++++++++++++++++++++++++- 6 files changed, 1048 insertions(+), 25 deletions(-) create mode 100644 tests/apptests/npumgr/npumgr_common.h diff --git a/src/core/ne-mem.cc b/src/core/ne-mem.cc index 8a6f679..d8a106a 100644 --- a/src/core/ne-mem.cc +++ b/src/core/ne-mem.cc @@ -28,11 +28,11 @@ class MemDefault : public MemAllocator { /** For library users. its backing storage is always a device driver */ int allocMemory (size_t size, void **addr) { - int dmabuf = api_->alloc (size); + int dmabuf = api_->alloc (ALIGNED_SIZE (size)); if (dmabuf < 0) return dmabuf; - *addr = api_->mmap (dmabuf, size); + *addr = api_->mmap (dmabuf, ALIGNED_SIZE (size)); if (*addr == nullptr) { api_->dealloc (dmabuf); return -EINVAL; @@ -42,7 +42,7 @@ class MemDefault : public MemAllocator { } int deallocMemory (int dmabuf_fd, size_t size, void *addr) { - int status = api_->munmap (addr, size); + int status = api_->munmap (addr, ALIGNED_SIZE (size)); if (status != 0) return status; diff --git a/tests/apptests/npumgr/npumgr.cc b/tests/apptests/npumgr/npumgr.cc index 8f9f540..34c8d27 100644 --- a/tests/apptests/npumgr/npumgr.cc +++ b/tests/apptests/npumgr/npumgr.cc @@ -84,10 +84,40 @@ static const gchar introspection_xml[] = " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " " " " " @@ -350,6 +380,128 @@ handle_method_call (GDBusConnection *connection, const gchar *sender, 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; @@ -489,6 +641,151 @@ handle_method_call (GDBusConnection *connection, const gchar *sender, 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"); + } } } diff --git a/tests/apptests/npumgr/npumgr_api.cc b/tests/apptests/npumgr/npumgr_api.cc index 686916f..55d36dc 100644 --- a/tests/apptests/npumgr/npumgr_api.cc +++ b/tests/apptests/npumgr/npumgr_api.cc @@ -12,6 +12,7 @@ */ #include "npumgr_api.h" +#include "npumgr_common.h" #include #include @@ -306,8 +307,47 @@ npumgr_network_set_attribute (npumgr_context ctx, npumgr_network nw_handle, npumgr_status_e npumgr_network_set_input (npumgr_context ctx, npumgr_network nw_handle, int index, npumgr_buffer *input_buffer) { - /* NYI */ - return NPUMGR_STATUS_SUCCESS; + 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; } /** @@ -316,8 +356,47 @@ npumgr_network_set_input (npumgr_context ctx, npumgr_network nw_handle, npumgr_status_e npumgr_network_set_output (npumgr_context ctx, npumgr_network nw_handle, int index, npumgr_buffer *output_buffer) { - /* NYI */ - return NPUMGR_STATUS_SUCCESS; + 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; } /** @@ -325,8 +404,41 @@ npumgr_network_set_output (npumgr_context ctx, npumgr_network nw_handle, */ npumgr_status_e npumgr_network_prepare (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", + "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; } /** @@ -378,8 +490,61 @@ npumgr_status_e npumgr_buffer_create (npumgr_context ctx, npumgr_query_tensor_attr *create_param, npumgr_buffer *buf) { - /* NYI */ - return NPUMGR_STATUS_SUCCESS; + 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; } /** @@ -387,8 +552,48 @@ npumgr_buffer_create (npumgr_context ctx, */ npumgr_status_e npumgr_buffer_destroy (npumgr_context ctx, npumgr_buffer *buf) { - /* NYI */ - return NPUMGR_STATUS_SUCCESS; + 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; } /** @@ -397,8 +602,71 @@ npumgr_buffer_destroy (npumgr_context ctx, npumgr_buffer *buf) { npumgr_status_e npumgr_buffer_map (npumgr_context ctx, npumgr_buffer *buf, uint8_t **mapped_addr) { - /* NYI */ - return NPUMGR_STATUS_SUCCESS; + 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; } /** diff --git a/tests/apptests/npumgr/npumgr_api.h b/tests/apptests/npumgr/npumgr_api.h index c17dcf8..6fae8e7 100644 --- a/tests/apptests/npumgr/npumgr_api.h +++ b/tests/apptests/npumgr/npumgr_api.h @@ -165,6 +165,7 @@ typedef enum _npumgr_tensor_qnt_type { typedef enum _npumgr_tensor_fmt { NPUMGR_TENSOR_FMT_NCHW = 0, NPUMGR_TENSOR_FMT_NHWC, + NPUMGR_TENSOR_FMT_TRIV2, NPUMGR_TENSOR_FMT_MAX }npumgr_tensor_fmt_t; diff --git a/tests/apptests/npumgr/npumgr_common.h b/tests/apptests/npumgr/npumgr_common.h new file mode 100644 index 0000000..aa7708a --- /dev/null +++ b/tests/apptests/npumgr/npumgr_common.h @@ -0,0 +1,33 @@ +/** + * Proprietary + * Copyright (C) 2021 Samsung Electronics + * Copyright (C) 2021 Dongju Chae + */ +/** + * @file npumgr_common.h + * @date 10 May 2021 + * @brief npumgr common header + * @author Dongju Chae + * @bug No known bugs except for NYI items + */ + +#ifndef __NPUMGR_COMMON_H__ +#define __NPUMGR_COMMON_H__ + +#include +#include /* 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 diff --git a/tests/apptests/npumgr/npumgr_triv2.cc b/tests/apptests/npumgr/npumgr_triv2.cc index 62a18bd..d9a3ba3 100644 --- a/tests/apptests/npumgr/npumgr_triv2.cc +++ b/tests/apptests/npumgr/npumgr_triv2.cc @@ -25,12 +25,106 @@ NpumgrDevice *npumgr_device_triv2_new (void); } /** + * @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; + case NPUMGR_TENSOR_FMT_TRIV2: + layout = DATA_LAYOUT_TRIV2; + 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; +} + +/** * @brief Class for triv2 npumgr network */ class NpumgrNetworkTriv2 { public: - NpumgrNetworkTriv2 (const npumgr_network_defn &model_file) - : model_file_ (model_file), + 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), @@ -38,8 +132,16 @@ class NpumgrNetworkTriv2 { 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_)); } ~NpumgrNetworkTriv2 () { + if (model_id_ > 0) + unregisterNPUmodel (dev_, model_id_); + close (model_file_.fd); g_strfreev (in_tensor_names_); g_strfreev (out_tensor_names_); @@ -53,8 +155,31 @@ class NpumgrNetworkTriv2 { in_tensor_names_ = g_strdupv (in_tensor_names); } gboolean loadModel () { - return read (model_file_.fd, (void *) meta_, NPUBIN_META_SIZE) == - NPUBIN_META_SIZE; + generic_buffer model = {0}; + + lseek (model_file_.fd, 0, SEEK_SET); + 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 */ @@ -79,8 +204,13 @@ class NpumgrNetworkTriv2 { return meta_->input_seg_dims[i][j]; } guint getInTensorSize (guint i) { - guint size = 1; - for (guint j = 0; j < MAX_RANK; j++) size *= getInTensorDim (i, j); + guint size; + 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]; } @@ -90,8 +220,13 @@ class NpumgrNetworkTriv2 { return meta_->output_seg_dims[i][j]; } guint getOutTensorSize (guint i) { - guint size = 1; - for (guint j = 0; j < MAX_RANK; j++) size *= getOutTensorDim (i, j); + guint size; + int status; + + status = getNPUmodel_tensorSize (dev_, model_id_, false, i, &size); + if (status != 0) + return 0; + return size; } int32_t getOutTensorQuantZero (gint i) { @@ -99,10 +234,45 @@ class NpumgrNetworkTriv2 { } 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)); + in_buffers_.bufs[index].type = BUFFER_DMABUF; + 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)); + out_buffers_.bufs[index].type = BUFFER_DMABUF; + return TRUE; + } + + gboolean prepare () { + return (setNPU_dataInfo (dev_, model_id_, &in_info_, &out_info_) == 0); + } + 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_; @@ -112,6 +282,12 @@ class NpumgrNetworkTriv2 { 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_; }; static void @@ -121,6 +297,13 @@ nw_destroy (gpointer data) { delete nw; } +static void +buf_destroy (gpointer data) { + NpumgrBufferTriv2 *buf = static_cast (data); + + delete buf; +} + /** * @brief Class for triv2 npumgr context */ @@ -131,9 +314,16 @@ class NpumgrContextTriv2 { 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_); } + ~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); @@ -146,6 +336,58 @@ class NpumgrContextTriv2 { nw_table_, GSIZE_TO_POINTER (handle)); } + 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: @@ -156,6 +398,7 @@ class NpumgrContextTriv2 { int priority_; GHashTable *nw_table_; + GHashTable *buf_table_; }; static void @@ -167,6 +410,7 @@ ctx_destroy (gpointer data) { 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 @@ -201,9 +445,34 @@ static npumgr_status_e triv2_network_create ( 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, @@ -236,7 +505,14 @@ npumgr_device_triv2_class_init (NpumgrDeviceTriv2Class *klass) { 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; @@ -394,7 +670,8 @@ triv2_network_create (NpumgrDevice *device, npumgr_context ctx, int num_files, g_return_val_if_fail (context != NULL, NPUMGR_STATUS_ERR_CTX_INVALID); - NpumgrNetworkTriv2 *network = new NpumgrNetworkTriv2 (input_files[0]); + NpumgrNetworkTriv2 *network = + new NpumgrNetworkTriv2 (context->getDevice (), input_files[0]); if (!network->loadModel ()) goto err; if (network->getInTensorCnt () != in_tensor_cnt) @@ -418,6 +695,86 @@ err: } 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); @@ -438,6 +795,73 @@ triv2_network_destroy (NpumgrDevice *device, npumgr_context ctx_handle, } 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) { -- 2.7.4