This validates integration mechanisms for nnfw-runtime of Tizen.
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
endforeach
nnfw_dep = dependency('nnfw', required: false)
- add_args = ''
- nnstreamer_filter_nnfw_deps = [glib_dep, gst_dep, nnstreamer_dep]
-
- if nnfw_dep.found()
- nnstreamer_filter_nnfw_deps += nnfw_dep
- else
+ if not nnfw_dep.found()
# Until nnfw supports pkg-config, we need to do this primitively.
- add_args = '-lnnfw-dev'
+ nnfw_dep = cc.find_library('nnfw-dev')
endif
+ nnstreamer_filter_nnfw_deps = [glib_dep, gst_dep, nnstreamer_dep, nnfw_dep]
- shared_library('nnstreamer_filter_nnfw',
+ nnfw_plugin_lib = shared_library('nnstreamer_filter_nnfw',
nnstreamer_filter_nnfw_sources,
dependencies: nnstreamer_filter_nnfw_deps,
- c_args : add_args,
install: true,
install_dir: filter_subplugin_install_dir
)
static_library('nnstreamer_filter_nnfw',
nnstreamer_filter_nnfw_sources,
dependencies: nnstreamer_filter_nnfw_deps,
- c_args : add_args,
install: false,
install_dir: filter_subplugin_install_dir
)
+
+ nnfw_plugin_dep = declare_dependency(link_with: nnfw_plugin_lib,
+ dependencies: nnstreamer_filter_nnfw_deps)
endif
if get_option('enable-tensorflow')
*
* @todo Check if nnfw supports dynamic input dimension. (if so, we need to supply setInputDim)
* @todo Decide whether to let nnfw allocate output buffers or we will feed output buffers to nnfw.
+ * @todo NYI: configuring backends
*
*/
+#include <string.h>
#include <glib.h>
#include <tensor_common.h>
#include <nnstreamer_plugin_api_filter.h>
void init_filter_nnfw (void) __attribute__ ((constructor));
void fini_filter_nnfw (void) __attribute__ ((destructor));
+typedef struct
+{
+ nnfw_tensorinfo i_in;
+ nnfw_tensorinfo i_out;
+ nnfw_session *session;
+ gchar *model_path;
+} nnfw_pdata;
+
+static void nnfw_close (const GstTensorFilterProperties * prop,
+ void **private_data);
+
/**
* @brief The standard tensor_filter callback
*/
-static int nnfw_open (const GstTensorFilterProperties * prop,
- void **private_data)
+static int
+nnfw_open (const GstTensorFilterProperties * prop, void **private_data)
{
+ NNFW_STATUS status;
+ int err = 0;
+ nnfw_pdata *pdata;
+
+ if (*private_data != NULL) {
+ pdata = *private_data;
+ if (strcmp (prop->model_file, pdata->model_path)) {
+ nnfw_close (prop, private_data); /* "reopen" */
+ } else {
+ return 1;
+ }
+ }
+
+ pdata = g_new0 (nnfw_pdata, 1);
+ if (pdata == NULL)
+ return -ENOMEM;
+
+ *private_data = (void *) pdata;
+
+ status = nnfw_create_session (&pdata->session);
+ if (status != NNFW_STATUS_NO_ERROR) {
+ err = -EINVAL;
+ g_printerr ("Cannot create nnfw-runtime session");
+ goto unalloc_exit;
+ }
+
+ status = nnfw_load_model_from_file (pdata->session, prop->model_file);
+ if (status != NNFW_STATUS_NO_ERROR) {
+ err = -EINVAL;
+ g_printerr ("Cannot load the model file: %s", prop->model_file);
+ goto session_exit;
+ }
+
+ status = nnfw_prepare (pdata->session);
+ if (status != NNFW_STATUS_NO_ERROR) {
+ err = -EINVAL;
+ g_printerr ("nnfw-runtime cannot prepare the session for %s",
+ prop->model_file);
+ goto session_exit;
+ }
+
+ pdata->model_path = g_strdup (prop->model_file);
return 0;
+
+session_exit:
+ status = nnfw_close_session(pdata->session);
+ if (status != NNFW_STATUS_NO_ERROR)
+ g_printerr ("Closing the session just opened by %s has failed", __func__);
+unalloc_exit:
+ g_free (pdata);
+ *private_data = NULL;
+ return err;
}
/**
* @brief The standard tensor_filter callback
+ * @todo Determine if we need to do "assert" for close-failure.
*/
-static void nnfw_close (const GstTensorFilterProperties * prop,
- void **private_data)
+static void
+nnfw_close (const GstTensorFilterProperties * prop, void **private_data)
{
+ nnfw_pdata *pdata;
+ pdata = *private_data;
+
+ if (pdata && pdata->session) {
+ NNFW_STATUS status = nnfw_close_session (pdata->session);
+
+ if (status != NNFW_STATUS_NO_ERROR) {
+ g_printerr ("cannot close nnfw-runtime session for %s",
+ pdata->model_path);
+ }
+ } else {
+ g_printerr ("nnfw_close called without proper nnfw_open");
+ if (pdata == NULL)
+ return;
+ }
+ pdata->session = NULL;
+
+ g_free (pdata->model_path);
+ pdata->model_path = NULL;
+
+ g_free (pdata);
+ *private_data = NULL;
}
/**
* @brief The standard tensor_filter callback
*/
-static int nnfw_getInputDim (const GstTensorFilterProperties * prop,
- void **private_data, GstTensorsInfo * info)
+static int
+nnfw_getInputDim (const GstTensorFilterProperties * prop,
+ void **private_data, GstTensorsInfo * info)
{
return 0;
}
/**
* @brief The standard tensor_filter callback
*/
-static int nnfw_getOutputDim (const GstTensorFilterProperties * prop,
- void **private_data, GstTensorsInfo * info)
+static int
+nnfw_getOutputDim (const GstTensorFilterProperties * prop,
+ void **private_data, GstTensorsInfo * info)
{
return 0;
}
/**
* @brief The standard tensor_filter callback
*/
-static int nnfw_invoke (const GstTensorFilterProperties * prop,
+static int
+nnfw_invoke (const GstTensorFilterProperties * prop,
void **private_data, const GstTensorMemory * input,
GstTensorMemory * output)
{
./tests/unittest_src_iio --gst-plugin-path=. --gtest_output="xml:unittest_src_iio.xml"
./tests/tizen_capi/unittest_tizen_capi --gst-plugin-path=. --gtest_output="xml:unittest_tizen_capi.xml"
./tests/tizen_capi/unittest_tizen_capi_single_new --gst-plugin-path=. --gtest_output="xml:unittest_tizen_capi_single_new.xml"
+%if 0%{?enable_nnfw_r}
+ ./tests/tizen_nnfw_runtime/unittest_nnfw_runtime_raw --gst-plugin-path=. --gtest_output="xml:unittest_nnfw_runtime_raw.xml"
+%endif
popd
pushd tests
ssat -n
subdir('tizen_capi')
endif
+if get_option('enable-nnfw-runtime')
+ subdir('tizen_nnfw_runtime')
+endif
+
# Install Unittest
if get_option('install-test')
install_data('gen24bBMP.py', install_dir: join_paths(unittest_install_dir,'tests'))
--- /dev/null
+unittest_nnfw_runtime_raw = executable('unittest_nnfw_runtime_raw',
+ 'unittest_tizen_nnfw_runtime_raw.cpp',
+ dependencies: [glib_dep, gst_dep, nnstreamer_dep, gtest_dep, nnfw_plugin_dep],
+ install: get_option('install-test'),
+ install_dir: unittest_install_dir,
+)
+
+test('unittest_nnfw_runtime_raw', unittest_nnfw_runtime_raw, args: ['--gst-plugin-path=../..'])
--- /dev/null
+/**
+ * @file unittest_tizen_capi.cpp
+ * @date 13 Mar 2019
+ * @brief Unit test for Tizen CAPI of NNStreamer. Basis of TCT in the future.
+ * @see https://github.com/nnsuite/nnstreamer
+ * @author MyungJoo Ham <myungjoo.ham@samsung.com>
+ * @bug No known bugs
+ */
+
+#include <gtest/gtest.h>
+#include <glib.h>
+#include <glib/gstdio.h> /* GStatBuf */
+#include <nnstreamer_plugin_api_filter.h>
+
+/**
+ * @brief Test nnfw subplugin existence.
+ */
+TEST (nnstreamer_nnfw_runtime_raw_functions, check_existence)
+{
+ const GstTensorFilterFramework *sp = nnstreamer_filter_find ("nnfw");
+ EXPECT_NE (sp, (void *) NULL);
+}
+
+/**
+ * @brief Test nnfw subplugin with failing open/flose (no model file)
+ */
+TEST (nnstreamer_nnfw_runtime_raw_functions, open_close_00_n)
+{
+ int ret;
+ GstTensorFilterProperties prop = {
+ .fwname = "nnfw",
+ .fw_opened = 0,
+ .model_file = "null.nnfw",
+ };
+ void *data;
+
+ const GstTensorFilterFramework *sp = nnstreamer_filter_find ("nnfw");
+ EXPECT_NE (sp, (void *) NULL);
+
+ ret = sp->open (&prop, &data);
+ EXPECT_NE (ret, 0);
+}
+
+/**
+ * @brief Main gtest
+ */
+int
+main (int argc, char **argv)
+{
+ int result;
+
+ testing::InitGoogleTest (&argc, argv);
+
+ result = RUN_ALL_TESTS ();
+
+ return result;
+}