[Test] add tests to increase ML_TENSOR_RANK_LIMIT
authorYelin Jeong <yelini.jeong@samsung.com>
Thu, 23 Mar 2023 04:56:33 +0000 (13:56 +0900)
committerSangjung Woo <again4you@gmail.com>
Thu, 6 Apr 2023 10:00:26 +0000 (19:00 +0900)
This patch adds some TCs for increased ML_TENSOR_RANK_LIMIT.

Signed-off-by: Yelin Jeong <yelini.jeong@samsung.com>
tests/capi/unittest_capi_datatype_consistency.cc
tests/capi/unittest_capi_inference.cc
tests/capi/unittest_capi_inference_single.cc
tests/test_models/models/add_extended.tflite [new file with mode: 0644]

index b0404fb..2376aa9 100644 (file)
@@ -25,9 +25,9 @@
  */
 TEST (nnstreamer_datatypes, test_all_1)
 {
-  EXPECT_EQ ((int) NNS_TENSOR_RANK_LIMIT, (int) ML_TENSOR_RANK_LIMIT);
+  EXPECT_EQ (8, (int) NNS_TENSOR_RANK_LIMIT);
+  EXPECT_EQ (16, (int) ML_TENSOR_RANK_LIMIT);
   EXPECT_EQ ((int) NNS_TENSOR_SIZE_LIMIT, (int) ML_TENSOR_SIZE_LIMIT);
-  EXPECT_EQ (sizeof (tensor_dim), sizeof (ml_tensor_dimension));
   EXPECT_EQ (sizeof (tensor_dim[0]), sizeof (ml_tensor_dimension[0]));
   EXPECT_EQ ((int) _NNS_INT32, (int) ML_TENSOR_TYPE_INT32);
   EXPECT_EQ ((int) _NNS_UINT32, (int) ML_TENSOR_TYPE_UINT32);
index 9541a95..30946a1 100644 (file)
@@ -2575,6 +2575,90 @@ TEST (nnstreamer_capi_util, tensors_info)
 }
 
 /**
+ * @brief Test NNStreamer Utility for checking extended tensors info handle
+ */
+TEST (nnstreamer_capi_util, tensors_info_extended)
+{
+  ml_tensors_info_h info;
+  ml_tensor_dimension in_dim, out_dim;
+  ml_tensor_type_e out_type;
+  gchar *out_name;
+  size_t data_size;
+  int status, i;
+
+  status = ml_tensors_info_create_extended (&info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    in_dim[i] = i % 4 + 1;
+  }
+
+  /* add tensor info */
+  status = ml_tensors_info_set_count (info, 2);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_set_tensor_type (info, 0, ML_TENSOR_TYPE_UINT8);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_set_tensor_dimension (info, 0, in_dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_set_tensor_type (info, 1, ML_TENSOR_TYPE_FLOAT64);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_set_tensor_dimension (info, 1, in_dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_set_tensor_name (info, 1, "tensor-name-test");
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  /* get tensor info */
+  status = ml_tensors_info_get_tensor_type (info, 0, &out_type);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_EQ (out_type, ML_TENSOR_TYPE_UINT8);
+
+  status = ml_tensors_info_get_tensor_dimension (info, 0, out_dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    EXPECT_EQ (out_dim[i], i % 4 + 1);
+  }
+
+  status = ml_tensors_info_get_tensor_name (info, 0, &out_name);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (out_name == NULL);
+
+  status = ml_tensors_info_get_tensor_type (info, 1, &out_type);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_EQ (out_type, ML_TENSOR_TYPE_FLOAT64);
+
+  status = ml_tensors_info_get_tensor_dimension (info, 1, out_dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    EXPECT_EQ (out_dim[i], i % 4 + 1);
+  }
+
+  status = ml_tensors_info_get_tensor_name (info, 1, &out_name);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (out_name && g_str_equal (out_name, "tensor-name-test"));
+  g_free (out_name);
+
+  /* get tensor size */
+  status = ml_tensors_info_get_tensor_size (info, 0, &data_size);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (data_size == (2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4));
+
+  status = ml_tensors_info_get_tensor_size (info, 1, &data_size);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (data_size == ((2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4)* 8));
+
+  status = ml_tensors_info_get_tensor_size (info, -1, &data_size);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_TRUE (data_size == (((2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4)) + ((2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4) * (2 * 3 * 4)* 8)));
+
+  status = ml_tensors_info_destroy (info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+}
+
+/**
  * @brief Test utility functions
  */
 TEST (nnstreamer_capi_util, compare_info)
@@ -2625,6 +2709,86 @@ TEST (nnstreamer_capi_util, compare_info)
 }
 
 /**
+ * @brief Test utility functions
+ */
+TEST (nnstreamer_capi_util, compare_info_extended)
+{
+  ml_tensors_info_h info1, info2;
+  ml_tensor_dimension dim;
+  int status, i;
+
+  status = ml_tensors_info_create_extended (&info1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_create_extended (&info2);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    dim[i] = i + 1;
+  }
+
+  ml_tensors_info_set_count (info1, 1);
+  ml_tensors_info_set_tensor_type (info1, 0, ML_TENSOR_TYPE_UINT8);
+  ml_tensors_info_set_tensor_dimension (info1, 0, dim);
+
+  ml_tensors_info_set_count (info2, 1);
+  ml_tensors_info_set_tensor_type (info2, 0, ML_TENSOR_TYPE_UINT8);
+  ml_tensors_info_set_tensor_dimension (info2, 0, dim);
+
+  /* compare info */
+  EXPECT_TRUE (ml_tensors_info_is_equal (info1, info2));
+
+  /* change type */
+  ml_tensors_info_set_tensor_type (info2, 0, ML_TENSOR_TYPE_UINT16);
+  EXPECT_FALSE (ml_tensors_info_is_equal (info1, info2));
+
+  /* validate info */
+  EXPECT_TRUE (ml_tensors_info_is_valid (info2));
+
+  /* validate invalid dimension */
+  dim[3] = 0;
+  ml_tensors_info_set_tensor_dimension (info2, 0, dim);
+  EXPECT_FALSE (ml_tensors_info_is_valid (info2));
+
+  status = ml_tensors_info_destroy (info1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_destroy (info2);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Test utility functions
+ */
+TEST (nnstreamer_capi_util, compare_info_extended_n)
+{
+  ml_tensors_info_h info1, info2;
+  ml_tensor_dimension dim;
+  int status, i;
+
+  status = ml_tensors_info_create_extended (&info1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_create (&info2);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    dim[i] = i + 1;
+  }
+
+  ml_tensors_info_set_count (info1, 1);
+  ml_tensors_info_set_tensor_type (info1, 0, ML_TENSOR_TYPE_UINT8);
+  ml_tensors_info_set_tensor_dimension (info1, 0, dim);
+
+  ml_tensors_info_set_count (info2, 1);
+  ml_tensors_info_set_tensor_type (info2, 0, ML_TENSOR_TYPE_UINT8);
+  ml_tensors_info_set_tensor_dimension (info2, 0, dim);
+
+  /* compare info */
+  EXPECT_FALSE (ml_tensors_info_is_equal (info1, info2));
+}
+
+/**
  * @brief Test utility functions (public)
  */
 TEST (nnstreamer_capi_util, info_create_1_n)
@@ -2656,6 +2820,15 @@ TEST (nnstreamer_capi_util, info_create_3_n)
 /**
  * @brief Test utility functions (public)
  */
+TEST (nnstreamer_capi_util, info_create_4_n)
+{
+  int status = ml_tensors_info_create_extended (nullptr);
+  ASSERT_EQ (status, ML_ERROR_INVALID_PARAMETER);
+}
+
+/**
+ * @brief Test utility functions (public)
+ */
 TEST (nnstreamer_capi_util, info_destroy_n)
 {
   int status = ml_tensors_info_destroy (nullptr);
@@ -2815,6 +2988,41 @@ TEST (nnstreamer_capi_util, info_comp_0)
 }
 
 /**
+ * @brief Test utility functions (internal)
+ */
+TEST (nnstreamer_capi_util, info_comp_1)
+{
+  ml_tensors_info_h info1, info2;
+  ml_tensor_dimension dim = { 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 };
+  int status;
+  bool equal;
+
+  status = ml_tensors_info_create (&info1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  ml_tensors_info_set_count (info1, 1);
+  ml_tensors_info_set_tensor_type (info1, 0, ML_TENSOR_TYPE_UINT8);
+  ml_tensors_info_set_tensor_dimension (info1, 0, dim);
+
+  status = ml_tensors_info_create_extended (&info2);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  ml_tensors_info_set_count (info2, 1);
+  ml_tensors_info_set_tensor_type (info2, 0, ML_TENSOR_TYPE_UINT8);
+  ml_tensors_info_set_tensor_dimension (info2, 0, dim);
+
+  status = _ml_tensors_info_compare (info1, info2, &equal);
+  ASSERT_EQ (status, ML_ERROR_NONE);
+  ASSERT_FALSE (equal);
+
+  status = ml_tensors_info_destroy (info1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_destroy (info2);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+}
+
+/**
  * @brief Test utility functions (public)
  */
 TEST (nnstreamer_capi_util, info_set_count_n)
@@ -3240,6 +3448,57 @@ TEST (nnstreamer_capi_util, info_clone)
 /**
  * @brief Test utility functions (public)
  */
+TEST (nnstreamer_capi_util, info_clone_extended)
+{
+  gint status, i;
+  guint count = 0;
+  ml_tensors_info_h in_info, out_info;
+  ml_tensor_dimension in_dim, out_dim;
+  ml_tensor_type_e type = ML_TENSOR_TYPE_UNKNOWN;
+
+  status = ml_tensors_info_create_extended (&in_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_create_extended (&out_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    in_dim[i] = i + 1;
+  }
+
+  status = ml_tensors_info_set_count (in_info, 1);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_set_tensor_type (in_info, 0, ML_TENSOR_TYPE_UINT8);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_set_tensor_dimension (in_info, 0, in_dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_clone (out_info, in_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_info_get_count (out_info, &count);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_EQ (count, 1U);
+
+  status = ml_tensors_info_get_tensor_type (out_info, 0, &type);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_EQ (type, ML_TENSOR_TYPE_UINT8);
+
+  status = ml_tensors_info_get_tensor_dimension (out_info, 0, out_dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  for (i = 0 ;i < ML_TENSOR_RANK_LIMIT ; i++) {
+    EXPECT_TRUE (in_dim[i] == out_dim[i]);
+  }
+
+  status = ml_tensors_info_destroy (in_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  status = ml_tensors_info_destroy (out_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Test utility functions (public)
+ */
 TEST (nnstreamer_capi_util, info_clone_01_n)
 {
   int status;
@@ -3665,6 +3924,46 @@ TEST (nnstreamer_capi_util, data_clone_03_n)
 }
 
 /**
+ * @brief Test utility functions - clone data.
+ */
+TEST (nnstreamer_capi_util, data_clone_04_p)
+{
+  int status, i;
+  ml_tensors_info_h info;
+  ml_tensors_data_h data;
+  ml_tensors_data_h data_out;
+  ml_tensor_dimension dim = { 5, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+  int raw_data[25];
+  int *result = nullptr;
+  size_t data_size, result_size;
+
+  for (i = 0; i < 25; i++)
+    raw_data[i] = i;
+
+  ml_tensors_info_create_extended (&info);
+  ml_tensors_info_set_count (info, 1);
+  ml_tensors_info_set_tensor_type (info, 0, ML_TENSOR_TYPE_INT32);
+  ml_tensors_info_set_tensor_dimension (info, 0, dim);
+  ml_tensors_info_get_tensor_size (info, 0, &data_size);
+
+  ml_tensors_data_create (info, &data);
+  ml_tensors_data_set_tensor_data (data, 0, (const void *) raw_data, data_size);
+
+  /* test code : clone data and compare raw value. */
+  status = ml_tensors_data_clone (data, &data_out);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  status = ml_tensors_data_get_tensor_data (data_out, 0, (void **) &result, &result_size);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  for (unsigned int i = 0; i < 25; i++)
+    EXPECT_EQ (result[i], raw_data[i]);
+
+  ml_tensors_info_destroy (info);
+  ml_tensors_data_destroy (data);
+  ml_tensors_data_destroy (data_out);
+}
+
+/**
  * @brief Test to replace string.
  */
 TEST (nnstreamer_capi_util, replaceStr01)
@@ -6575,6 +6874,47 @@ TEST (nnstreamer_capi_internal, copy_from_gst)
 /**
  * @brief Test for internal function '_ml_tensors_info_copy_from_gst'.
  */
+TEST (nnstreamer_capi_internal, copy_from_gst_extended)
+{
+  int status;
+  ml_tensors_info_h ml_info;
+  ml_tensor_dimension dim;
+  unsigned int count;
+  GstTensorsInfo gst_info;
+  guint i;
+
+  gst_tensors_info_init (&gst_info);
+  gst_info.num_tensors = 2;
+  gst_info.info[0].type = _NNS_UINT32;
+  gst_info.info[1].type = _NNS_UINT32;
+
+  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    gst_info.info[0].dimension[i] = i + 1;
+    gst_info.info[1].dimension[i] = i + 1;
+  }
+
+  status = ml_tensors_info_create_extended (&ml_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  _ml_tensors_info_copy_from_gst ((ml_tensors_info_s *)ml_info, &gst_info);
+  status = ml_tensors_info_get_count (ml_info, &count);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  EXPECT_EQ (count, 2U);
+  status = ml_tensors_info_get_tensor_dimension (ml_info, 0, dim);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    EXPECT_EQ (dim[i], i + 1);
+  }
+
+  status = ml_tensors_info_destroy (ml_info);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  gst_tensors_info_free (&gst_info);
+}
+
+/**
+ * @brief Test for internal function '_ml_tensors_info_copy_from_gst'.
+ */
 TEST (nnstreamer_capi_internal, copy_from_gst_01_n)
 {
   GstTensorsInfo gst_info;
index a52a84f..55dec81 100644 (file)
@@ -1673,6 +1673,157 @@ skip_test:
 }
 
 /**
+ * @brief Test NNStreamer single shot with extended tensors info
+ */
+TEST (nnstreamer_capi_singleshot, set_input_info_extended_success)
+{
+  ml_single_h single;
+  ml_tensors_info_h in_info, out_info;
+  ml_tensors_info_h in_res = nullptr, out_res = nullptr;
+  ml_tensors_data_h input, output;
+  ml_tensor_dimension in_dim = {4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+  ml_tensor_dimension out_dim = {4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+  ml_tensor_dimension res_dim;
+  ml_tensor_type_e type = ML_TENSOR_TYPE_UNKNOWN;
+  unsigned int count = 0;
+  int status, i, tensor_size = 4*4*4*4*4;
+  size_t data_size;
+  float *input0, *input1, *output0;
+
+  const gchar *root_path = g_getenv ("MLAPI_SOURCE_ROOT_PATH");
+  gchar *test_model;
+
+  /* supposed to run test in build directory */
+  if (root_path == NULL)
+    root_path = "..";
+
+  /** add_extended.tflite adds two input tensors and makes one output tensor */
+  test_model = g_build_filename (
+      root_path, "tests", "test_models", "models", "add_extended.tflite", NULL);
+  ASSERT_TRUE (g_file_test (test_model, G_FILE_TEST_EXISTS));
+
+  ml_tensors_info_create_extended (&in_info);
+  ml_tensors_info_create_extended (&out_info);
+
+  ml_tensors_info_set_count (in_info, 2);
+  ml_tensors_info_set_tensor_type (in_info, 0, ML_TENSOR_TYPE_FLOAT32);
+  ml_tensors_info_set_tensor_dimension (in_info, 0, in_dim);
+  ml_tensors_info_set_tensor_type (in_info, 1, ML_TENSOR_TYPE_FLOAT32);
+  ml_tensors_info_set_tensor_dimension (in_info, 1, in_dim);
+
+  ml_tensors_info_set_count (out_info, 1);
+  ml_tensors_info_set_tensor_type (out_info, 0, ML_TENSOR_TYPE_FLOAT32);
+  ml_tensors_info_set_tensor_dimension (out_info, 0, out_dim);
+
+  status = ml_single_open (&single, test_model, in_info, out_info,
+      ML_NNFW_TYPE_TENSORFLOW_LITE, ML_NNFW_HW_ANY);
+  if (is_enabled_tensorflow_lite) {
+    EXPECT_EQ (status, ML_ERROR_NONE);
+  } else {
+    EXPECT_NE (status, ML_ERROR_NONE);
+    goto skip_test;
+  }
+
+  status = ml_single_get_input_info (single, &in_res);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+  ml_tensors_info_get_tensor_dimension (in_res, 0, res_dim);
+  for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++)
+    EXPECT_EQ (in_dim[i], res_dim[i]);
+
+  status = ml_single_set_input_info (single, in_info);
+  EXPECT_TRUE (status == ML_ERROR_NOT_SUPPORTED || status == ML_ERROR_NONE);
+  if (status == ML_ERROR_NONE) {
+    /* input tensor in filter */
+    ml_tensors_info_destroy (in_res);
+    status = ml_single_get_input_info (single, &in_res);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+
+    status = ml_tensors_info_get_count (in_res, &count);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (count, 2U);
+
+    status = ml_tensors_info_get_tensor_type (in_res, 0, &type);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (type, ML_TENSOR_TYPE_FLOAT32);
+
+    ml_tensors_info_get_tensor_dimension (in_res, 0, res_dim);
+    for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++)
+      EXPECT_EQ (in_dim[i], res_dim[i]);
+
+    /* output tensor in filter */
+    status = ml_single_get_output_info (single, &out_res);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+
+    status = ml_tensors_info_get_count (out_res, &count);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (count, 1U);
+
+    status = ml_tensors_info_get_tensor_type (out_res, 0, &type);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (type, ML_TENSOR_TYPE_FLOAT32);
+
+    ml_tensors_info_get_tensor_dimension (out_res, 0, res_dim);
+    for (i = 0; i < ML_TENSOR_RANK_LIMIT; i++)
+      EXPECT_EQ (out_dim[i], res_dim[i]);
+
+    input = output = NULL;
+
+    /* generate dummy data */
+    status = ml_tensors_data_create (in_info, &input);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_TRUE (input != NULL);
+
+    status = ml_tensors_data_get_tensor_data (input, 0, (void **)&input0, &data_size);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (data_size, tensor_size * sizeof (float));
+    for (int idx = 0; idx < tensor_size; idx++)
+      input0[idx] = idx;
+
+    status = ml_tensors_data_get_tensor_data (input, 1, (void **)&input1, &data_size);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (data_size, tensor_size * sizeof (float));
+    for (int idx = 0; idx < tensor_size; idx++)
+      input1[idx] = idx+1;
+
+    status = ml_single_invoke (single, input, &output);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_TRUE (output != NULL);
+
+    status = ml_tensors_data_get_tensor_data (input, 0, (void **)&input0, &data_size);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (data_size, tensor_size * sizeof (float));
+    for (int idx = 0; idx < tensor_size; idx++)
+      EXPECT_EQ (input0[idx], idx);
+
+    status = ml_tensors_data_get_tensor_data (input, 1, (void **)&input1, &data_size);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (data_size, tensor_size * sizeof (float));
+    for (int idx = 0; idx < tensor_size; idx++)
+      EXPECT_EQ (input1[idx], idx+1);
+
+    status = ml_tensors_data_get_tensor_data (output, 0, (void **)&output0, &data_size);
+    EXPECT_EQ (status, ML_ERROR_NONE);
+    EXPECT_EQ (data_size, tensor_size * sizeof (float));
+    for (int idx = 0; idx < tensor_size; idx++)
+      EXPECT_EQ (output0[idx], input0[idx] + input1[idx]);
+
+    ml_tensors_data_destroy (output);
+    ml_tensors_data_destroy (input);
+  }
+
+  status = ml_single_close (single);
+  EXPECT_EQ (status, ML_ERROR_NONE);
+
+skip_test:
+  g_free (test_model);
+  ml_tensors_info_destroy (in_info);
+  ml_tensors_info_destroy (out_info);
+  ml_tensors_info_destroy (in_res);
+  ml_tensors_info_destroy (out_res);
+}
+
+/**
  * @brief Test NNStreamer single shot (tensorflow-lite)
  * @detail Update property 'layout' for input tensor
  */
diff --git a/tests/test_models/models/add_extended.tflite b/tests/test_models/models/add_extended.tflite
new file mode 100644 (file)
index 0000000..4fc02ce
Binary files /dev/null and b/tests/test_models/models/add_extended.tflite differ