This patch changes plugin test program paths.
Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
Requires: npu-engine = %{version}-%{release}
Summary: NPU Engine Example Package
%description utils
-This probides utility packages for NPU Engine, including metadata extraction of model files.
+This provides utility packages for NPU Engine, including metadata extraction of model files.
%files utils
%manifest npu-engine.manifest
%defattr(-,root,root,-)
%{neexampledir}/utils/*
+%if ( 0%{?npumgr_plugin} || 0%{?nns_plugin} )
+%package example-plugins
+Requires: npu-engine = %{version}-%{release}
+Summary: NPU Engine Example Package for Plugins
+%description example-plugins
+Example application package for NPU Engine plugins
+%files example-plugins
+%manifest npu-engine.manifest
+%defattr(-,root,root,-)
+%if 0%{?npumgr_plugin}
+%{neexampledir}/plugins/npumgr/*
+%endif
+%if 0%{?nns_plugin}
+%{neexampledir}/plugins/nnstreamer/*
+%endif
+%endif
+
%if 0%{?npumgr_plugin}
%package -n npumgr-srnpu
Summary: Tizen NPU Manager plugin for SR-NPU device family
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
Reference implementation of NNStreamer filter subplugin for SR-NPU (for now, TRIV2 only).
%files -n nnstreamer-srnpu
%manifest npu-engine.manifest
-# Uncomment below when test-cases are ready
-# %{neexampledir}/plugins/nnstreamer/*
%{_prefix}/lib/nnstreamer/filters/libnnstreamer_filter_srnpu.so
%endif
# dummy npu manager
subdir('dummy')
-subdir('tests')
+++ /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;
-}
-if ne_test_utils_gtest_dep.found()
- testenv = environment()
- testenv.set('LD_LIBRARY_PATH', ne_libdir)
-
- if get_option('enable_plugin_nns')
- plugintest_nnstreamer = executable('plugintest_nnstreamer',
- ['nnstreamer_test.cc'],
- dependencies: [ne_test_utils_gtest_dep, glib_dep, gst_dep],
- install : true,
- install_rpath : ne_libdir,
- install_dir : join_paths(ne_bindir, 'plugins')
- )
- test('plugintest_nnstreamer', plugintest_nnstreamer, env: testenv)
- endif
+if get_option('enable_plugin_nns')
+ subdir('nnstreamer')
+endif
+if get_option('enable_plugin_npumgr')
+ subdir('npumgr')
endif
--- /dev/null
+if ne_test_utils_gtest_dep.found()
+ testenv = environment()
+ testenv.set('LD_LIBRARY_PATH', ne_libdir)
+
+ if get_option('enable_plugin_nns')
+ plugintest_nnstreamer = executable('plugintest_nnstreamer',
+ ['nnstreamer_test.cc'],
+ dependencies: [ne_test_utils_gtest_dep, glib_dep, gst_dep],
+ install : true,
+ install_rpath : ne_libdir,
+ install_dir : join_paths(ne_bindir, 'plugins', 'nnstreamer')
+ )
+ test('plugintest_nnstreamer', plugintest_nnstreamer, env: testenv)
+ endif
+endif
--- /dev/null
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file nnstreamer_test.cc
+ * @date 07 July 2021
+ * @brief Test NNStreamer filter sub-plugin for TRIV2
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <ne_test_utils_gtest.h>
+
+#include <glib.h>
+#include <gst/gst.h>
+
+#define STATECHANGE_TIMEOUT 100000 /* 100s */
+
+typedef enum {
+ MODEL_CONV_2D_000 = 0,
+ MODEL_MOBILENET_V1,
+ MODEL_END
+} srnpu_model;
+
+static const gchar *model_names[MODEL_END] = {
+ [MODEL_CONV_2D_000] = "CONV_2D_000",
+ [MODEL_MOBILENET_V1] = "MOBILENET_V1",
+};
+
+static const gchar *input_dims[MODEL_END] = {
+ [MODEL_CONV_2D_000] = "64:1:1:1",
+ [MODEL_MOBILENET_V1] = "3:224:224:1",
+};
+
+static const gchar *output_dims[MODEL_END] = {
+ [MODEL_CONV_2D_000] = "64:1:1:1",
+ [MODEL_MOBILENET_V1] = "1000:1:1:1",
+};
+
+static int
+set_pipeline_state_sync (GstElement *pipeline, GstState state,
+ uint32_t timeout_ms) {
+ GstState cur_state = GST_STATE_VOID_PENDING;
+ GstStateChangeReturn ret;
+ gint counter = 0;
+
+ ret = gst_element_set_state (pipeline, state);
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ return -EPIPE;
+
+ do {
+ ret = gst_element_get_state (pipeline, &cur_state, NULL, 10 * GST_MSECOND);
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ return -EPIPE;
+ if (cur_state == state)
+ return 0;
+ g_usleep (10000); /* 10 ms */
+ } while ((timeout_ms / 20) > counter++);
+
+ return -ETIME;
+}
+
+static gchar *
+make_pipeline_srnpu (srnpu_model model) {
+ if (model < 0 || model >= MODEL_END)
+ return nullptr;
+
+ const gchar *input_dim = input_dims[model];
+ const gchar *output_dim = output_dims[model];
+ gchar *model_path = g_strdup_printf ("%s/testdata/TRIV235_2TOPS/%s",
+ NE_DATADIR, model_names[model]);
+ gchar *pipeline = g_strdup_printf (
+ "filesrc location=%s/input_fmap_0.bin blocksize=-1 ! "
+ "application/octet-stream "
+ "! tensor_converter input-dim=%s input-type=uint8 "
+ "! tensor_filter framework=srnpu accelerator=true:npu.sr "
+ "model=%s/model.tvn "
+ " input=%s inputtype=uint8 inputlayout=NHWC "
+ " output=%s outputtype=uint8 outputlayout=NHWC "
+ "! fakesink",
+ model_path, input_dim, model_path, input_dim, output_dim);
+
+ g_free (model_path);
+ return pipeline;
+}
+
+TEST (nnstreamer_test, launch_conv_2d) {
+ gchar *pipeline;
+ GstElement *gstpipe;
+ GError *err = NULL;
+
+ pipeline = make_pipeline_srnpu (MODEL_CONV_2D_000);
+ gstpipe = gst_parse_launch (pipeline, &err);
+ EXPECT_NE (gstpipe, nullptr);
+
+ EXPECT_EQ (
+ set_pipeline_state_sync (gstpipe, GST_STATE_PLAYING, STATECHANGE_TIMEOUT),
+ 0);
+ EXPECT_EQ (
+ set_pipeline_state_sync (gstpipe, GST_STATE_NULL, STATECHANGE_TIMEOUT),
+ 0);
+
+ gst_object_unref (gstpipe);
+ g_free (pipeline);
+}
+
+TEST (nnstreamer_test, launch_mobilenet_v1) {
+ gchar *pipeline;
+ GstElement *gstpipe;
+ GError *err = NULL;
+
+ pipeline = make_pipeline_srnpu (MODEL_MOBILENET_V1);
+ gstpipe = gst_parse_launch (pipeline, &err);
+ EXPECT_NE (gstpipe, nullptr);
+
+ EXPECT_EQ (
+ set_pipeline_state_sync (gstpipe, GST_STATE_PLAYING, STATECHANGE_TIMEOUT),
+ 0);
+ EXPECT_EQ (
+ set_pipeline_state_sync (gstpipe, GST_STATE_NULL, STATECHANGE_TIMEOUT),
+ 0);
+
+ gst_object_unref (gstpipe);
+ g_free (pipeline);
+}
+
+/** @brief plugintest main */
+int
+main (int argc, char **argv) {
+ gst_init (&argc, &argv);
+ return start_gtest (argc, argv);
+}
+++ /dev/null
-/**
- * Proprietary
- * Copyright (C) 2021 Samsung Electronics
- * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
- */
-/**
- * @file nnstreamer_test.cc
- * @date 07 July 2021
- * @brief Test NNStreamer filter sub-plugin for TRIV2
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include <ne_test_utils_gtest.h>
-
-#include <glib.h>
-#include <gst/gst.h>
-
-#define STATECHANGE_TIMEOUT 100000 /* 100s */
-
-typedef enum {
- MODEL_CONV_2D_000 = 0,
- MODEL_MOBILENET_V1,
- MODEL_END
-} srnpu_model;
-
-static const gchar *model_names[MODEL_END] = {
- [MODEL_CONV_2D_000] = "CONV_2D_000",
- [MODEL_MOBILENET_V1] = "MOBILENET_V1",
-};
-
-static const gchar *input_dims[MODEL_END] = {
- [MODEL_CONV_2D_000] = "64:1:1:1",
- [MODEL_MOBILENET_V1] = "3:224:224:1",
-};
-
-static const gchar *output_dims[MODEL_END] = {
- [MODEL_CONV_2D_000] = "64:1:1:1",
- [MODEL_MOBILENET_V1] = "1000:1:1:1",
-};
-
-static int
-set_pipeline_state_sync (GstElement *pipeline, GstState state,
- uint32_t timeout_ms) {
- GstState cur_state = GST_STATE_VOID_PENDING;
- GstStateChangeReturn ret;
- gint counter = 0;
-
- ret = gst_element_set_state (pipeline, state);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return -EPIPE;
-
- do {
- ret = gst_element_get_state (pipeline, &cur_state, NULL, 10 * GST_MSECOND);
- if (ret == GST_STATE_CHANGE_FAILURE)
- return -EPIPE;
- if (cur_state == state)
- return 0;
- g_usleep (10000); /* 10 ms */
- } while ((timeout_ms / 20) > counter++);
-
- return -ETIME;
-}
-
-static gchar *
-make_pipeline_srnpu (srnpu_model model) {
- if (model < 0 || model >= MODEL_END)
- return nullptr;
-
- const gchar *input_dim = input_dims[model];
- const gchar *output_dim = output_dims[model];
- gchar *model_path = g_strdup_printf ("%s/testdata/TRIV235_2TOPS/%s",
- NE_DATADIR, model_names[model]);
- gchar *pipeline = g_strdup_printf (
- "filesrc location=%s/input_fmap_0.bin blocksize=-1 ! "
- "application/octet-stream "
- "! tensor_converter input-dim=%s input-type=uint8 "
- "! tensor_filter framework=srnpu accelerator=true:npu.sr "
- "model=%s/model.tvn "
- " input=%s inputtype=uint8 inputlayout=NHWC "
- " output=%s outputtype=uint8 outputlayout=NHWC "
- "! fakesink",
- model_path, input_dim, model_path, input_dim, output_dim);
-
- g_free (model_path);
- return pipeline;
-}
-
-TEST (nnstreamer_test, launch_conv_2d) {
- gchar *pipeline;
- GstElement *gstpipe;
- GError *err = NULL;
-
- pipeline = make_pipeline_srnpu (MODEL_CONV_2D_000);
- gstpipe = gst_parse_launch (pipeline, &err);
- EXPECT_NE (gstpipe, nullptr);
-
- EXPECT_EQ (
- set_pipeline_state_sync (gstpipe, GST_STATE_PLAYING, STATECHANGE_TIMEOUT),
- 0);
- EXPECT_EQ (
- set_pipeline_state_sync (gstpipe, GST_STATE_NULL, STATECHANGE_TIMEOUT),
- 0);
-
- gst_object_unref (gstpipe);
- g_free (pipeline);
-}
-
-TEST (nnstreamer_test, launch_mobilenet_v1) {
- gchar *pipeline;
- GstElement *gstpipe;
- GError *err = NULL;
-
- pipeline = make_pipeline_srnpu (MODEL_MOBILENET_V1);
- gstpipe = gst_parse_launch (pipeline, &err);
- EXPECT_NE (gstpipe, nullptr);
-
- EXPECT_EQ (
- set_pipeline_state_sync (gstpipe, GST_STATE_PLAYING, STATECHANGE_TIMEOUT),
- 0);
- EXPECT_EQ (
- set_pipeline_state_sync (gstpipe, GST_STATE_NULL, STATECHANGE_TIMEOUT),
- 0);
-
- gst_object_unref (gstpipe);
- g_free (pipeline);
-}
-
-/** @brief plugintest main */
-int
-main (int argc, char **argv) {
- gst_init (&argc, &argv);
- return start_gtest (argc, argv);
-}
--- /dev/null
+testenv = environment()
+testenv.set('LD_LIBRARY_PATH', ne_libdir)
+
+# npu manager test program
+plugintest_npumgr = executable ('plugintest_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')
+)
+test('plugintest_npumgr', plugintest_npumgr, env: testenv)
--- /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;
+}