glib_dep
]
-# TODO: enable for python
-
# Format for adding subplugin into extensions -
-# [name, extension abbreviation, dependencies, model file name/folder path/file path]
+# [name, extension abbreviation, dependencies, model file name/folder path/file path, test name]
extensions = []
-extensions += [['custom', 'custom', nnstreamer_unittest_deps, '../build/nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough.so']]
+extensions += [['custom', 'custom', nnstreamer_unittest_deps, '../build/nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough.so', 'custom']]
+extensions += [['custom', 'custom', nnstreamer_unittest_deps, '../build/nnstreamer_example/custom_example_passthrough/libnnstreamer_customfilter_passthrough_variable.so', 'custom-set']]
if get_option('enable-tensorflow-lite')
- extensions += [['tensorflow-lite', 'tflite', nnstreamer_filter_tflite_deps, 'mobilenet_v1_1.0_224_quant.tflite']]
+ extensions += [['tensorflow-lite', 'tflite', nnstreamer_filter_tflite_deps, 'mobilenet_v1_1.0_224_quant.tflite', 'tensorflow_lite']]
+ extensions += [['tensorflow-lite', 'tflite', nnstreamer_filter_tflite_deps, 'add.tflite', 'tensorflow_lite-set']]
endif
if get_option('enable-tensorflow')
- extensions += [['tensorflow', 'tf', nnstreamer_filter_tf_deps, 'mnist.pb']]
+ extensions += [['tensorflow', 'tf', nnstreamer_filter_tf_deps, 'mnist.pb', 'tensorflow']]
endif
if get_option('enable-nnfw-runtime')
- extensions += [['nnfw', 'nnfw', nnstreamer_filter_nnfw_deps, 'add.tflite']]
+ extensions += [['nnfw', 'nnfw', nnstreamer_filter_nnfw_deps, 'add.tflite', 'nnfw']]
endif
if get_option('enable-pytorch')
- extensions += [['pytorch', 'torch', nnstreamer_filter_torch_deps, 'pytorch_lenet5.pt']]
+ extensions += [['pytorch', 'torch', nnstreamer_filter_torch_deps, 'pytorch_lenet5.pt', 'pytorch']]
endif
if get_option('enable-caffe2')
- extensions += [['caffe2', 'caffe2', nnstreamer_filter_caffe2_deps, 'caffe2_init_net.pb,caffe2_predict_net.pb']]
+ extensions += [['caffe2', 'caffe2', nnstreamer_filter_caffe2_deps, 'caffe2_init_net.pb,caffe2_predict_net.pb', 'caffe2']]
endif
if have_python2
- extensions += [['python2', 'python2', nnstreamer_filter_python2_deps, 'passthrough.py']]
+ extensions += [['python2', 'python2', nnstreamer_filter_python2_deps, 'passthrough.py', 'python2-get']]
+ extensions += [['python2', 'python2', nnstreamer_filter_python2_deps, 'scaler.py', 'python2-set']]
endif
if have_python3
- extensions += [['python3', 'python3', nnstreamer_filter_python3_deps, 'passthrough.py']]
+ extensions += [['python3', 'python3', nnstreamer_filter_python3_deps, 'passthrough.py', 'python3-get']]
+ extensions += [['python3', 'python3', nnstreamer_filter_python3_deps, 'scaler.py', 'python3-set']]
endif
sed_command = find_program('sed', required: true)
ext_test_template = files (ext_test_template_prefix + 'template.cc.in')
foreach ext : extensions
- ext_test_path_each = ext_test_template_prefix + ext[0] + '.cc'
+ ext_test_path_each = ext_test_template_prefix + ext[4] + '.cc'
sed_ext_name_option = 's|@EXT_NAME@|' + ext[0] + '|'
sed_ext_abbrv_option = 's|@EXT_ABBRV@|' + ext[1] + '|'
)
exec = executable(
- ext_test_template_prefix + ext[0],
+ ext_test_template_prefix + ext[4],
ext_test_each,
dependencies: [tizen_apptest_deps, ext[2]],
install: get_option('install-test'),
install_dir: unittest_install_dir
)
- test(ext_test_template_prefix + ext[0], exec, args: ['--gst-plugin-path=../..'])
+ test(ext_test_template_prefix + ext[4], exec, args: ['--gst-plugin-path=../..'])
endforeach
ret = sp->open (&prop, &data);
EXPECT_EQ (ret, 0);
- /** python subplugin modifies methods based on model file */
- if (sp->getInputDimension && sp->getOutputDimension) {
- /** get input/output dimension unsuccessfully */
- ret = sp->getInputDimension (&prop, &data, NULL);
- EXPECT_NE (ret, 0);
-
- ret = sp->getOutputDimension (&prop, &data, NULL);
- EXPECT_NE (ret, 0);
- }
+ /** get input/output dimension unsuccessfully */
+ ret = sp->getInputDimension (&prop, &data, NULL);
+ EXPECT_NE (ret, 0);
+
+ ret = sp->getOutputDimension (&prop, &data, NULL);
+ EXPECT_NE (ret, 0);
sp->close (&prop, &data);
}
ret = sp->open (&prop, &data);
EXPECT_EQ (ret, 0);
- /** python subplugin modifies methods based on model file */
+ /** get input/output dimension successfully */
if (sp->getInputDimension && sp->getOutputDimension) {
- /** get input/output dimension successfully */
gst_tensors_info_init (&res);
ret = sp->getInputDimension (&prop, &data, &res);
gst_tensors_info_free (&res);
- EXPECT_EQ (ret, 0);
+ EXPECT_TRUE (ret == 0 || ret == -ENOENT);
gst_tensors_info_init (&res);
ret = sp->getOutputDimension (&prop, &data, &res);
gst_tensors_info_free (&res);
+ EXPECT_TRUE (ret == 0 || ret == -ENOENT);
+ }
+
+ sp->close (&prop, &data);
+
+ g_strfreev (model_files);
+}
+
+/**
+ * @brief Set input dimensions with @EXT_ABBRV@ subplugin
+ */
+TEST (nnstreamer_@EXT_ABBRV@_basic_functions, set_dimension_fail_n)
+{
+ int ret;
+ void *data = NULL;
+ GstTensorsInfo set;
+ gchar **model_files;
+
+ model_files = get_model_files ();
+ ASSERT_TRUE (model_files != nullptr);
+
+ GstTensorFilterProperties prop = {
+ .fwname = "@EXT_NAME@",
+ .fw_opened = 0,
+ .model_files = const_cast<const char **>(model_files),
+ .num_models = (int) g_strv_length (model_files),
+
+ };
+
+ const GstTensorFilterFramework *sp = nnstreamer_filter_find ("@EXT_NAME@");
+ EXPECT_NE (sp, (void *) NULL);
+
+ if (sp->setInputDimension) {
+ /** set input dimension without open */
+ ret = sp->setInputDimension (&prop, &data, &set, &set);
+ EXPECT_NE (ret, 0);
+
+ ret = sp->open (&prop, &data);
EXPECT_EQ (ret, 0);
+
+ gst_tensors_info_init (&set);
+
+ /** set input dimension unsuccessfully */
+ ret = sp->setInputDimension (&prop, &data, NULL, &set);
+ EXPECT_NE (ret, 0);
+ ret = sp->setInputDimension (&prop, &data, &set, NULL);
+ EXPECT_NE (ret, 0);
+
+ gst_tensors_info_free (&set);
+
+ sp->close (&prop, &data);
+ }
+
+ g_strfreev (model_files);
+
+}
+
+/**
+ * @brief Set input dimensions with @EXT_ABBRV@ subplugin
+ */
+TEST (nnstreamer_@EXT_ABBRV@_basic_functions, set_dimension)
+{
+ int ret;
+ void *data = NULL;
+ GstTensorsInfo set, get;
+ gchar **model_files;
+
+ model_files = get_model_files ();
+ ASSERT_TRUE (model_files != nullptr);
+
+ GstTensorFilterProperties prop = {
+ .fwname = "@EXT_NAME@",
+ .fw_opened = 0,
+ .model_files = const_cast<const char **>(model_files),
+ .num_models = (int) g_strv_length (model_files),
+
+ };
+
+ const GstTensorFilterFramework *sp = nnstreamer_filter_find ("@EXT_NAME@");
+ EXPECT_NE (sp, (void *) NULL);
+
+ ret = sp->open (&prop, &data);
+ EXPECT_EQ (ret, 0);
+
+ gst_tensors_info_init (&set);
+
+ /** Get the current input dimension, if allowed */
+ ret = -EINVAL;
+ if (sp->getInputDimension) {
+ ret = sp->getInputDimension (&prop, &data, &set);
+ EXPECT_TRUE (ret == 0 || ret == -ENOENT);
+ }
+
+ /** Set the dimension to be set in the framework */
+ if (ret == 0) {
+ /** if get input dimension was success */
+ set.info[0].dimension[0] *= 2;
+ set.info[0].dimension[2] *= 2;
+ } else {
+ set.num_tensors = 1;
+ set.info[0].type = _NNS_INT8;
+ set.info[0].dimension[0] = 10;
+ set.info[0].dimension[1] = 9;
+ set.info[0].dimension[2] = 8;
+ set.info[0].dimension[3] = 7;
+ }
+
+ if (sp->setInputDimension) {
+ /** set input dimension successfully */
+ ret = sp->setInputDimension (&prop, &data, &set, &set);
+ /**
+ * EPERM - changing the input dimension is not permitted for the loaded model
+ * ENOENT - setInputDimension operation is not supported by the framework
+ */
+ if (ret != -EPERM && ret != -ENOENT) {
+ EXPECT_EQ (ret, 0);
+ }
+
+ /** if set was successful and getInputDimension is supported, verify */
+ if (sp->getInputDimension && ret != -EPERM && ret != -ENOENT) {
+ /** use get dimension to verify the set values, if entry exists */
+ gst_tensors_info_init (&get);
+ ret = sp->getInputDimension (&prop, &data, &get);
+ EXPECT_TRUE (ret == 0 || ret == -ENOENT);
+
+ if (ret == 0) {
+ EXPECT_EQ (set.num_tensors, get.num_tensors);
+ EXPECT_EQ (set.info[0].type, get.info[0].type);
+ EXPECT_EQ (set.info[0].dimension[0], get.info[0].dimension[0]);
+ EXPECT_EQ (set.info[0].dimension[1], get.info[0].dimension[1]);
+ EXPECT_EQ (set.info[0].dimension[2], get.info[0].dimension[2]);
+ EXPECT_EQ (set.info[0].dimension[3], get.info[0].dimension[3]);
+ }
+ gst_tensors_info_free (&get);
+ }
}
sp->close (&prop, &data);
+ gst_tensors_info_free (&set);
g_strfreev (model_files);
}
TEST (nnstreamer_@EXT_ABBRV@_basic_functions, invoke)
{
int ret;
+ int ret_get_in, ret_get_out, ret_set_in;
void *data = NULL;
GstTensorMemory input[NNS_TENSOR_SIZE_LIMIT] = { 0, };
GstTensorMemory output[NNS_TENSOR_SIZE_LIMIT] = { 0, };
const GstTensorFilterFramework *sp = nnstreamer_filter_find ("@EXT_NAME@");
EXPECT_NE (sp, (void *) NULL);
+ EXPECT_TRUE ((sp->getInputDimension && sp->getOutputDimension) ||
+ (sp->setInputDimension));
+
ret = sp->open (&prop, &data);
EXPECT_EQ (ret, 0);
- ASSERT_TRUE ((sp->getInputDimension && sp->getOutputDimension) ||
- (sp->setInputDimension));
-
/** Decide the size for input and output */
gst_tensors_info_init (&input_info);
gst_tensors_info_init (&output_info);
+ /** if get dimension is supported, try it */
+ ret_get_in = ret_get_out = -EINVAL;
if (sp->getInputDimension && sp->getOutputDimension) {
- ret = sp->getInputDimension (&prop, &data, &input_info);
- EXPECT_EQ (ret, 0);
+ ret_get_in = sp->getInputDimension (&prop, &data, &input_info);
+ EXPECT_TRUE (ret_get_in == 0 || ret_get_in == -ENOENT);
+ ret_get_out = sp->getOutputDimension (&prop, &data, &output_info);
+ EXPECT_TRUE (ret_get_out == 0 || ret_get_out == -ENOENT);
+ }
- ret = sp->getOutputDimension (&prop, &data, &output_info);
- EXPECT_EQ (ret, 0);
- } else {
- input_info.num_tensors = output_info.num_tensors = 1;
- input_info.info[0].type = output_info.info[0].type = _NNS_FLOAT32;
- input_info.info[0].dimension[0] = output_info.info[0].dimension[0] = 10;
- input_info.info[0].dimension[1] = output_info.info[0].dimension[1] = 1;
- input_info.info[0].dimension[2] = output_info.info[0].dimension[2] = 1;
- input_info.info[0].dimension[3] = output_info.info[0].dimension[3] = 1;
+ /** if get dimension was not supported, use set dimension */
+ if (ret_get_in != 0 || ret_get_out != 0 ||
+ !gst_tensors_info_validate (&input_info) ||
+ !gst_tensors_info_validate (&output_info)) {
+ if (sp->setInputDimension) {
+ GstTensorsInfo res;
+
+ gst_tensors_info_init (&res);
+ res.num_tensors = 1;
+ res.info[0].type = _NNS_FLOAT32;
+ res.info[0].dimension[0] = 10;
+ res.info[0].dimension[1] = 1;
+ res.info[0].dimension[2] = 1;
+ res.info[0].dimension[3] = 1;
+
+ /** As get dimension failed, set dimension must pass */
+ ret_set_in = sp->setInputDimension (&prop, &data, &res, &res);
+ EXPECT_EQ (ret_set_in, 0);
+
+ input_info.num_tensors = output_info.num_tensors = 1;
+ input_info.info[0].type = output_info.info[0].type = _NNS_FLOAT32;
+ input_info.info[0].dimension[0] = output_info.info[0].dimension[0] = 10;
+ input_info.info[0].dimension[1] = output_info.info[0].dimension[1] = 1;
+ input_info.info[0].dimension[2] = output_info.info[0].dimension[2] = 1;
+ input_info.info[0].dimension[3] = output_info.info[0].dimension[3] = 1;
+ gst_tensors_info_free (&res);
+ }
}
for (i = 0; i < input_info.num_tensors; ++i) {
/** should never crash */
ret = sp->invoke_NN (&prop, &data, input, output);
- /** should be successful for single input/output case */
- if (sp->getInputDimension && sp->getOutputDimension &&
- input_info.num_tensors > 0 && output_info.num_tensors > 0) {
+ if (input_info.num_tensors != 0 && output_info.num_tensors != 0) {
+ /** should be successful for valid input/output case */
EXPECT_EQ (ret, 0);
}
}
/**
+ * @brief Reload model with @EXT_ABBRV@ subplugin
+ */
+TEST (nnstreamer_@EXT_ABBRV@_basic_functions, reload_model)
+{
+ int ret;
+ void *data = NULL;
+ gchar **model_files;
+ GstTensorMemory input, output;
+
+ model_files = get_model_files ();
+ ASSERT_TRUE (model_files != nullptr);
+
+ GstTensorFilterProperties prop = {
+ .fwname = "@EXT_NAME@",
+ .fw_opened = 0,
+ .model_files = const_cast<const char **>(model_files),
+ .num_models = (int) g_strv_length (model_files),
+ };
+
+ const GstTensorFilterFramework *sp = nnstreamer_filter_find ("@EXT_NAME@");
+ EXPECT_NE (sp, (void *) NULL);
+
+ if (sp->reloadModel) {
+ /** reload model without open */
+ ret = sp->reloadModel (&prop, &data);
+ EXPECT_NE (ret, 0);
+
+ ret = sp->open (&prop, &data);
+ EXPECT_EQ (ret, 0);
+
+ /** opening the same model again */
+ ret = sp->reloadModel (&prop, &data);
+ EXPECT_EQ (ret, 0);
+
+ output.type = input.type = _NNS_FLOAT32;
+ output.size = input.size = gst_tensor_get_element_size (input.type) * 10;
+ input.data = g_malloc(input.size);
+ output.data = g_malloc(output.size);
+
+ /** should not crash after reload */
+ ret = sp->invoke_NN (&prop, &data, &input, &output);
+
+ g_free (input.data);
+ g_free (output.data);
+
+ sp->close (&prop, &data);
+ }
+
+ g_strfreev (model_files);
+}
+
+/**
* @brief Main gtest
*/
int