executable ('apptest_npumgr',
'npumgr_test.cc',
+ dependencies : glib_dep,
link_with : npumgr_lib,
install : true,
install_rpath : ne_libdir,
#include <stdlib.h>
#include <unistd.h>
-#include <cstdint>
#include <vector>
#include <string>
" <arg type='t' name='ctx_handle' direction='in'/>"
" <arg type='t' name='nw_handle' 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>"
" </interface>"
" </node>";
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");
+ }
}
}
npumgr_status_e
npumgr_query_network (npumgr_context ctx, npumgr_network nw_handle,
npumgr_query_inout_num *data) {
- /* 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",
+ "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;
}
/**
npumgr_status_e
npumgr_query_input (npumgr_context ctx, npumgr_network nw_handle, int index,
npumgr_query_tensor_attr *data) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
+ 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;
}
/**
npumgr_status_e
npumgr_query_output (npumgr_context ctx, npumgr_network nw_handle, int index,
npumgr_query_tensor_attr *data) {
- /* NYI */
- return NPUMGR_STATUS_SUCCESS;
+ 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;
}
/**
#include <fcntl.h>
#include <unistd.h>
+#include <glib.h>
+
#include "npumgr_api.h"
int
main (int argc, char **argv) {
- npumgr_context ctx;
- npumgr_network nw_handle;
+ npumgr_context context;
+ npumgr_network network;
npumgr_devices_id list;
npumgr_status_e status;
int fd, ret = -EINVAL;
if (argc != 2) {
- std::cerr << "Please provide network file name\n";
+ std::cerr << "Please provide network file name (.tvn)\n";
+ return ret;
+ }
+
+ if (!g_str_has_suffix (argv[1], ".tvn")) {
+ std::cerr << "Invalid model path: " << argv[1] << "\n";
return ret;
}
return ret;
}
- status = npumgr_context_create (id, NPUMGR_FLAG_PRIORITY_DEFAULT, &ctx);
+ 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;
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 (
- ctx, 1, input_files, NPUMGR_BUF_TYPE_DRIVER, 1, input_tensor_names,
- NPUMGR_BUF_TYPE_DRIVER, 1, output_tensor_names, &nw_handle);
+ 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) {
std::cerr << "Unable to create a npumgr network, " << status << "\n";
goto out;
}
- status = npumgr_network_destroy (ctx, nw_handle);
+ status = npumgr_query_network (context, network, &inout_num);
+ if (status != NPUMGR_STATUS_SUCCESS) {
+ std::cerr << "Unable to query network info, " << status << "\n";
+ goto out;
+ }
+
+ input_attr = g_new0 (npumgr_query_tensor_attr, inout_num.n_input);
+ output_attr = g_new0 (npumgr_query_tensor_attr, inout_num.n_input);
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ /* NYI: DO SOMETHING */
+
+ g_free (input_attr);
+ g_free (output_attr);
+
+ status = npumgr_network_destroy (context, network);
if (status != NPUMGR_STATUS_SUCCESS) {
std::cerr << "Unable to destroy the npumgr network, " << status << "\n";
goto out;
if (fd >= 0)
close (fd);
- status = npumgr_context_destroy (ctx);
+ status = npumgr_context_destroy (context);
if (status != NPUMGR_STATUS_SUCCESS) {
std::cerr << "Unable to destroy the npumgr context, " << status << "\n";
return ret;
/* npu-engine API */
#include <libnpuhost.h>
-#include <vector>
#include <fcntl.h>
#include <unistd.h>
+#include <vector>
extern "C" {
NpumgrDevice *npumgr_device_triv2_new (void);
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));
+ }
npumgr_context getHandle () { return handle_; }
static void triv2_finalize (GObject *object);
/* NpumgrDevice */
static npumgr_status_e triv2_device_get_capabilities (
- NpumgrDevice *device, uint32_t *caps, npumgr_device_type_t *ptype);
+ 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_network_destroy (NpumgrDevice *device,
npumgr_context ctx,
npumgr_network nw_handle);
+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);
extern NpumgrDevice *
npumgr_device_triv2_new (void) {
npumgr_device_class->context_destroy = triv2_context_destroy;
npumgr_device_class->network_create = triv2_network_create;
npumgr_device_class->network_destroy = triv2_network_destroy;
+ npumgr_device_class->query_network = triv2_query_network;
+ npumgr_device_class->query_input = triv2_query_input;
+ npumgr_device_class->query_output = triv2_query_output;
/* NYI */
}
/* Filling the virtual function table of TRIV2 */
static npumgr_status_e
-triv2_device_get_capabilities (NpumgrDevice *device, uint32_t *caps,
+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);
return NPUMGR_STATUS_ERR_FAIL;
}
}
+
+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->size = network->getInTensorSize (index);
+ attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
+ attr->type = NPUMGR_TENSOR_DATA_UINT8;
+
+ 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->size = network->getOutTensorSize (index);
+ attr->fmt = NPUMGR_TENSOR_FMT_NHWC;
+ attr->type = NPUMGR_TENSOR_DATA_UINT8;
+
+ 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;
+}