Doxygen Book
tensor_filter_common.c
Go to the documentation of this file.
1 
26 #include <string.h>
27 
28 #include <hw_accel.h>
29 #include <ml_agent.h>
30 #include <nnstreamer_log.h>
31 #include <nnstreamer_util.h>
32 
33 #include "tensor_filter_common.h"
34 
35 #define silent_debug_info(i,msg) do { \
36  if (DBG) { \
37  guint info_idx; \
38  gchar *dim_str; \
39  ml_logd (msg " total %d", (i)->num_tensors); \
40  for (info_idx = 0; info_idx < (i)->num_tensors; info_idx++) { \
41  GstTensorInfo *nth = gst_tensors_info_get_nth_info (i, info_idx); \
42  if (nth) { \
43  dim_str = gst_tensor_get_dimension_string (nth->dimension); \
44  ml_logd ("[%d] type=%d dim=%s", info_idx, nth->type, dim_str); \
45  g_free (dim_str); \
46  } \
47  } \
48  } \
49 } while (0)
50 
54 #define REGEX_ACCL_ELEM_START "("
55 #define REGEX_ACCL_ELEM_PREFIX "(?<!!)"
56 #define REGEX_ACCL_ELEM_SUFFIX ""
57 #define REGEX_ACCL_ELEM_DELIMITER "|"
58 #define REGEX_ACCL_ELEM_END ")?"
59 
60 #define REGEX_ACCL_START "(^(true)[:]?([(]?("
61 #define REGEX_ACCL_PREFIX ""
62 #define REGEX_ACCL_SUFFIX ""
63 #define REGEX_ACCL_DELIMITER "|"
64 #define REGEX_ACCL_END ")*[)]?))"
65 
66 static const gchar *regex_accl_utils[] = {
72  NULL
73 };
74 
75 static const gchar *regex_accl_elem_utils[] = {
81  NULL
82 };
83 
87 #define g_free_const(x) g_free((void*)(long)(x))
88 #define g_strfreev_const(x) g_strfreev((void*)(long)(x))
89 
90 static GType accl_hw_get_type (void);
91 static GList *parse_accl_hw_all (const gchar * accelerators,
92  const gchar ** supported_accelerators);
94  GstTensorFilterProperties * prop, const GValue * value);
96  GstTensorFilterProperties * prop, const GValue * value);
97 
102 static GHashTable *shared_model_table = NULL;
103 
107 static void
109 {
110  int i;
111 
112  for (i = 0; i < NNS_TENSOR_SIZE_LIMIT; i++) {
113  layout[i] = _NNS_LAYOUT_ANY;
114  }
115 }
116 
120 static void
121 gst_tensors_rank_init (unsigned int ranks[])
122 {
123  int i;
124  for (i = 0; i < NNS_TENSOR_SIZE_LIMIT; ++i) {
125  ranks[i] = 0;
126  }
127 }
128 
133 static tensor_layout
134 gst_tensor_parse_layout_string (const gchar * layoutstr)
135 {
136  gchar *layout_string;
138 
139  if (layoutstr == NULL)
140  return layout;
141 
142  /* remove spaces */
143  layout_string = g_strdup (layoutstr);
144  g_strstrip (layout_string);
145 
146  /* empty string */
147  if (0 == strlen (layout_string))
148  goto done;
149 
150  if (g_ascii_strcasecmp (layoutstr, "NCHW") == 0) {
151  layout = _NNS_LAYOUT_NCHW;
152  } else if (g_ascii_strcasecmp (layoutstr, "NHWC") == 0) {
153  layout = _NNS_LAYOUT_NHWC;
154  } else if (g_ascii_strcasecmp (layoutstr, "ANY") == 0) {
155  layout = _NNS_LAYOUT_ANY;
156  } else {
157  nns_logw ("Invalid layout, defaulting to none layout.");
158  layout = _NNS_LAYOUT_NONE;
159  }
160 
161 done:
162  g_free (layout_string);
163  return layout;
164 }
165 
172 static guint
174  const gchar * layout_string)
175 {
176  guint num_layouts = 0;
177 
178  g_return_val_if_fail (layout != NULL, 0);
179 
180  if (layout_string) {
181  guint i;
182  gchar **str_layouts;
183 
184  str_layouts = g_strsplit_set (layout_string, ",.", -1);
185  num_layouts = g_strv_length (str_layouts);
186 
187  if (num_layouts > NNS_TENSOR_SIZE_LIMIT) {
188  nns_logw ("Invalid param, layouts (%d) max (%d)\n",
189  num_layouts, NNS_TENSOR_SIZE_LIMIT);
190 
191  num_layouts = NNS_TENSOR_SIZE_LIMIT;
192  }
193 
194  for (i = 0; i < num_layouts; i++) {
195  layout[i] = gst_tensor_parse_layout_string (str_layouts[i]);
196  }
197 
198  g_strfreev (str_layouts);
199  }
200 
201  return num_layouts;
202 }
203 
210 static gchar *
212  gboolean isInput)
213 {
214  gchar *rank_str = NULL;
215  guint i;
216  const guint *_ranks;
217  const GstTensorsInfo *_meta;
218 
219  g_return_val_if_fail (prop != NULL, NULL);
220 
221  if (isInput) {
222  _ranks = prop->input_ranks;
223  _meta = &prop->input_meta;
224  } else {
225  _ranks = prop->output_ranks;
226  _meta = &prop->output_meta;
227  }
228 
229  if (_meta->num_tensors > 0) {
230  GString *rank = g_string_new (NULL);
231 
232  for (i = 0; i < _meta->num_tensors; ++i) {
233  if (_ranks[i] != 0)
234  g_string_append_printf (rank, "%u", _ranks[i]);
235  else
236  g_string_append_printf (rank, "%u",
238  (GstTensorsInfo *) _meta, i)));
239 
240  if (i < _meta->num_tensors - 1)
241  g_string_append_printf (rank, ",");
242  }
243  rank_str = g_string_free (rank, FALSE);
244  } else {
245  rank_str = g_strdup ("");
246  }
247 
248  return rank_str;
249 }
250 
258 static gchar *
260  const gboolean isInput)
261 {
262  gchar *dim_str = NULL;
263  const GstTensorsInfo *tinfo;
264  const unsigned int *_rank;
265 
266  if (isInput) {
267  tinfo = &prop->input_meta;
268  _rank = prop->input_ranks;
269  } else {
270  tinfo = &prop->output_meta;
271  _rank = prop->output_ranks;
272  }
273 
274  if (tinfo->num_tensors > 0) {
275  guint i;
276  GString *dimensions = g_string_new (NULL);
277 
278  for (i = 0; i < tinfo->num_tensors; ++i) {
279  dim_str =
281  (GstTensorsInfo *) tinfo, i)->dimension, *(_rank + i));
282  g_string_append (dimensions, dim_str);
283 
284  if (i < tinfo->num_tensors - 1) {
285  g_string_append (dimensions, ",");
286  }
287  g_free (dim_str);
288  }
289  dim_str = g_string_free (dimensions, FALSE);
290  } else {
291  dim_str = g_strdup ("");
292  }
293 
294  return dim_str;
295 }
296 
303 static gchar *
305  const gboolean is_input)
306 {
307  gchar *type_str;
308  const GstTensorsInfo *info;
309 
310  info = (is_input) ? &prop->input_meta : &prop->output_meta;
311 
312  if (info->num_tensors > 0)
313  type_str = gst_tensors_info_get_types_string (info);
314  else
315  type_str = g_strdup ("");
316 
317  return type_str;
318 }
319 
326 static gchar *
328  const gboolean is_input)
329 {
330  gchar *name_str;
331  const GstTensorsInfo *info;
332 
333  info = (is_input) ? &prop->input_meta : &prop->output_meta;
334 
335  if (info->num_tensors > 0)
336  name_str = gst_tensors_info_get_names_string (info);
337  else
338  name_str = g_strdup ("");
339 
340  return name_str;
341 }
342 
348 static const gchar *
350 {
351  switch (layout) {
352  case _NNS_LAYOUT_NCHW:
353  return "NCHW";
354  case _NNS_LAYOUT_NHWC:
355  return "NHWC";
356  case _NNS_LAYOUT_NONE:
357  return "NONE";
358  case _NNS_LAYOUT_ANY:
359  return "ANY";
360  default:
361  return NULL;
362  }
363 }
364 
371 static gchar *
373  const gboolean is_input)
374 {
375  gchar *layout_str = NULL;
376  const GstTensorsInfo *info;
377  const tensors_layout *layout;
378 
379  if (is_input) {
380  info = &prop->input_meta;
381  layout = &prop->input_layout;
382  } else {
383  info = &prop->output_meta;
384  layout = &prop->output_layout;
385  }
386 
387  if (info->num_tensors > 0) {
388  guint i;
389  GString *layouts = g_string_new (NULL);
390 
391  for (i = 0; i < info->num_tensors; i++) {
392  g_string_append (layouts, gst_tensor_get_layout_string ((*layout)[i]));
393 
394  if (i < info->num_tensors - 1) {
395  g_string_append (layouts, ",");
396  }
397  }
398 
399  layout_str = g_string_free (layouts, FALSE);
400  } else {
401  layout_str = g_strdup ("");
402  }
403 
404  return layout_str;
405 }
406 
413 static gchar *
414 strcpy2 (gchar * dest, const gchar * src)
415 {
416  if (!dest || !src) {
417  ml_loge ("Failed to copy a string. The variables shouldn't be NULL.");
418  return NULL;
419  }
420  memcpy (dest, src, strlen (src));
421  return dest + strlen (src);
422 }
423 
430 static gchar *
431 create_regex (const gchar ** enum_list, const gchar ** regex_utils)
432 {
433  gchar regex[4096];
434  gchar *regex_ptr = regex;
435  const gchar **strings = enum_list;
436  const gchar *iterator = *strings;
437  const gchar *escape_separator = "\\.";
438  const gchar *escape_chars = ".";
439  gchar **regex_split;
440  gchar *regex_escaped;
441 
442  if (iterator == NULL)
443  return NULL;
444 
446  regex_ptr = strcpy2 (regex_ptr, regex_utils[0]);
447  regex_ptr = strcpy2 (regex_ptr, regex_utils[1]);
448  regex_ptr = strcpy2 (regex_ptr, iterator);
449  regex_ptr = strcpy2 (regex_ptr, regex_utils[2]);
450  for (iterator = strings[1]; iterator != NULL; iterator = *++strings) {
451  regex_ptr = strcpy2 (regex_ptr, regex_utils[3]);
452  regex_ptr = strcpy2 (regex_ptr, regex_utils[1]);
453  regex_ptr = strcpy2 (regex_ptr, iterator);
454  regex_ptr = strcpy2 (regex_ptr, regex_utils[2]);
455  }
456  regex_ptr = strcpy2 (regex_ptr, regex_utils[4]);
457  *regex_ptr = '\0';
458 
460  regex_split = g_strsplit_set (regex, escape_chars, -1);
461  regex_escaped = g_strjoinv (escape_separator, regex_split);
462  g_strfreev (regex_split);
463 
464  return regex_escaped;
465 }
466 
472 static inline gboolean
474 {
476  gboolean ret = TRUE;
477  int verify_model_path = 0, i;
478 
479  if (priv == NULL)
480  return FALSE;
481 
482  prop = &(priv->prop);
483 
484  if (g_strcmp0 (prop->fwname, "custom-easy") == 0)
485  return TRUE;
486 
487  if (GST_TF_FW_V0 (priv->fw)) {
489  } else if (GST_TF_FW_V1 (priv->fw)) {
491  }
492 
493  if ((prop->model_files != NULL) && (verify_model_path == TRUE)) {
494  for (i = 0; i < prop->num_models; i++) {
495  if (!g_file_test (prop->model_files[i], G_FILE_TEST_IS_REGULAR)) {
496  ml_loge ("Cannot find the model file [%d]: %s\n",
497  i, prop->model_files[i]);
498  ret = FALSE;
499  }
500  }
501  }
502 
503  return ret;
504 }
505 
509 static void
511 {
512  /* init null */
513  memset (prop, 0, sizeof (GstTensorFilterProperties));
514 
515  gst_tensors_info_init (&prop->input_meta);
516  gst_tensors_layout_init (prop->input_layout);
517  gst_tensors_rank_init (prop->input_ranks);
518 
519  gst_tensors_info_init (&prop->output_meta);
520  gst_tensors_layout_init (prop->output_layout);
521  gst_tensors_rank_init (prop->output_ranks);
522 }
523 
527 static void
529 {
530  info->name = NULL;
531  info->allow_in_place = 0;
532  info->allocate_in_invoke = 0;
533  info->run_without_model = 0;
534  info->verify_model_path = 0;
535  info->hw_list = NULL;
536  info->accl_auto = -1;
537  info->accl_default = -1;
538  info->statistics = NULL;
539 }
540 
544 static void
546 {
547  stat->total_invoke_num = 0;
548  stat->total_invoke_latency = 0;
549  stat->old_total_invoke_num = 0;
550  stat->old_total_invoke_latency = 0;
551  stat->latest_invoke_time = 0;
552  stat->recent_latencies = g_queue_new ();
553  stat->latency_ignore_count = 1;
554 }
555 
559 static gboolean
561 {
562  if (GST_TF_FW_V0 (tfsp)) {
563  if (!tfsp->name) {
564  /* invalid fw name */
565  return FALSE;
566  }
567 
568  if (!tfsp->invoke_NN) {
569  /* no invoke function */
570  return FALSE;
571  }
572 
573  if (!(tfsp->getInputDimension && tfsp->getOutputDimension) &&
574  !tfsp->setInputDimension) {
575  /* no method to get tensor info */
576  return FALSE;
577  }
578  } else if (GST_TF_FW_V1 (tfsp)) {
581 
582  if (!tfsp->invoke || !tfsp->getFrameworkInfo || !tfsp->getModelInfo ||
583  !tfsp->eventHandler) {
585  return FALSE;
586  }
587 
589  if (tfsp->getFrameworkInfo (tfsp, &prop, NULL, &info) != 0) {
590  /* unable to get framework info */
591  return FALSE;
592  }
593 
594  if (!info.name) {
595  /* invalid fw name */
596  return FALSE;
597  }
598  } else {
599  return FALSE;
600  }
601 
602  return TRUE;
603 }
604 
610 int
612 {
615  const char *name = NULL;
616 
617  g_return_val_if_fail (nnstreamer_filter_validate (tfsp), FALSE);
618 
619  if (GST_TF_FW_V0 (tfsp)) {
620  name = tfsp->name;
621  } else if (GST_TF_FW_V1 (tfsp)) {
623  if (0 != tfsp->getFrameworkInfo (tfsp, &prop, NULL, &info)) {
624  ml_loge ("getFrameworkInfo() failed.\n");
625  return FALSE;
626  }
627  name = info.name;
628  }
629 
630  return register_subplugin (NNS_SUBPLUGIN_FILTER, name, tfsp);
631 }
632 
637 void
638 nnstreamer_filter_exit (const char *name)
639 {
641 }
642 
646 void
647 nnstreamer_filter_set_custom_property_desc (const char *name, const char *prop,
648  ...)
649 {
650  va_list varargs;
651 
652  va_start (varargs, prop);
654  varargs);
655  va_end (varargs);
656 }
657 
663 static const GstTensorFilterFramework *
665 {
666  const GstTensorFilterFramework *fw = NULL;
667  gchar **subplugins;
668  guint i, len;
669 
670  if (names == NULL || names[0] == '\0')
671  return NULL;
672 
673  subplugins = g_strsplit_set (names, " ,;", -1);
674  len = g_strv_length (subplugins);
675 
676  for (i = 0; i < len; i++) {
677  if (strlen (g_strstrip (subplugins[i])) == 0)
678  continue;
679 
681  if (fw) {
682  nns_logi ("Found %s", subplugins[i]);
683  break;
684  }
685  }
686  g_strfreev (subplugins);
687 
688  return fw;
689 }
690 
697 nnstreamer_filter_find (const char *name)
698 {
699  const GstTensorFilterFramework *fw;
700  gchar *_str;
701 
702  g_return_val_if_fail (name != NULL, NULL);
703 
704  fw = get_subplugin (NNS_SUBPLUGIN_FILTER, name);
705 
706  if (fw == NULL) {
707  /* get sub-plugin priority from ini file and find sub-plugin */
708  _str = nnsconf_get_custom_value_string (name, "subplugin_priority");
710  g_free (_str);
711  }
712 
713  if (fw == NULL) {
714  /* Check the filter-alias from ini file */
715  _str = nnsconf_get_custom_value_string ("filter-aliases", name);
717  g_free (_str);
718  }
719  return fw;
720 }
721 
727 static void
729  const gchar * model_files)
730 {
731  if (prop == NULL)
732  return;
733 
734  g_strfreev_const (prop->model_files);
735 
736  if (model_files) {
737  gchar **models = g_strsplit_set (model_files, ",", -1);
738  guint i, num = g_strv_length (models);
739 
740  for (i = 0; i < num; i++)
741  g_strstrip (models[i]);
742 
743  prop->model_files = (const gchar **) models;
744  prop->num_models = num;
745  } else {
746  prop->model_files = NULL;
747  prop->num_models = 0;
748  }
749 }
750 
756 gboolean
758 {
759  int allocate_in_invoke = 0;
760 
761  if (priv->prop.invoke_dynamic)
762  return TRUE;
763 
764  if (GST_TF_FW_V0 (priv->fw)) {
765  allocate_in_invoke = priv->fw->allocate_in_invoke;
766  if (allocate_in_invoke == TRUE && priv->fw->allocateInInvoke) {
767  if (priv->fw->allocateInInvoke (&priv->privateData) == 0) {
768  allocate_in_invoke = TRUE;
769  } else {
770  allocate_in_invoke = FALSE;
771  }
772  }
773  } else if (GST_TF_FW_V1 (priv->fw)) {
774  allocate_in_invoke = priv->info.allocate_in_invoke;
775  }
776 
777  return allocate_in_invoke;
778 }
779 
785 void
787  void *data)
788 {
790 
791  if (GST_TF_FW_V0 (priv->fw) && priv->fw->destroyNotify) {
792  priv->fw->destroyNotify (&priv->privateData, data);
793  } else if (GST_TF_FW_V1 (priv->fw)) {
794  event_data.data = data;
795  if (priv->fw->eventHandler (priv->fw, &priv->prop, priv->privateData,
796  DESTROY_NOTIFY, &event_data) == -ENOENT) {
797  g_free (data);
798  }
799  } else {
800  g_free (data);
801  }
802 }
803 
810 gchar *
812  const GstTensorsInfo * info2)
813 {
814  gchar *result = NULL;
815  gchar *line, *tmp, *left, *right;
816  guint i;
817 
818  g_return_val_if_fail (info1 != NULL && info2 != NULL, NULL);
819 
820  for (i = 0; i < NNS_TENSOR_SIZE_LIMIT; i++) {
821  if (info1->num_tensors <= i && info2->num_tensors <= i)
822  break;
823 
824  if (info1->num_tensors > i) {
825  GstTensorInfo *info1_i =
828  left =
829  g_strdup_printf ("%s [%s]",
830  gst_tensor_get_type_string (info1_i->type), tmp);
831  g_free (tmp);
832  } else {
833  left = g_strdup ("None");
834  }
835 
836  if (info2->num_tensors > i) {
837  GstTensorInfo *info2_i =
840  right =
841  g_strdup_printf ("%s [%s]",
842  gst_tensor_get_type_string (info2_i->type), tmp);
843  g_free (tmp);
844  } else {
845  right = g_strdup ("None");
846  }
847 
848  line = g_strdup_printf ("%2d : %s | %s %s\n", i, left, right,
849  g_str_equal (left, right) ? "" : "Not equal");
850 
851  g_free (left);
852  g_free (right);
853 
854  if (result) {
855  tmp = g_strdup_printf ("%s%s", result, line);
856  g_free (result);
857  g_free (line);
858 
859  result = tmp;
860  } else {
861  result = line;
862  }
863  }
864 
865  return result;
866 }
867 
873 void
875  const GstTensorsInfo * info2)
876 {
877  gchar *result = gst_tensorsinfo_compare_to_string (info1, info2);
878  nns_logi ("%s\n", (result == NULL) ?
879  "cannot compare NULL metadata(GstTensorsInfo) with others" : result);
880  g_free (result);
881 }
882 
887 void
888 gst_tensor_filter_install_properties (GObjectClass * gobject_class)
889 {
890  gchar **subplugins = NULL;
891  gchar *strbuf;
892  static gchar *strprint = NULL;
893 
894  g_object_class_install_property (gobject_class, PROP_SILENT,
895  g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
896  FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
897 
899  strbuf = g_strjoinv (", ", subplugins);
900  g_free (strprint);
901  strprint = g_strdup_printf
902  ("Neural network framework. Custom property depends on the specified framework. Use 'auto' to let tensor_filter determine the framework. For more detail, please refer to the documentation or nnstreamer-check utility. Available frameworks (filter subplugins) are: {%s}.",
903  strbuf);
904 
905  g_object_class_install_property (gobject_class, PROP_FRAMEWORK,
906  g_param_spec_string ("framework", "Framework", strprint, "auto",
907  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
908 
909  g_free (strbuf);
910  g_strfreev (subplugins);
911 
912  g_object_class_install_property (gobject_class, PROP_MODEL,
913  g_param_spec_string ("model", "Model filepath",
914  "File path to the model file. Separated with ',' in case of multiple model files(like caffe2)",
915  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
916  g_object_class_install_property (gobject_class, PROP_INPUT,
917  g_param_spec_string ("input", "Input dimension",
918  "Input tensor dimension from inner array (Max rank #NNS_TENSOR_RANK_LIMIT)",
919  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
920  g_object_class_install_property (gobject_class, PROP_INPUTNAME,
921  g_param_spec_string ("inputname", "Name of Input Tensor",
922  "The Name of Input Tensor", "",
923  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
924  g_object_class_install_property (gobject_class, PROP_INPUTTYPE,
925  g_param_spec_string ("inputtype", "Input tensor element type",
926  "Type of each element of the input tensor ?", "",
927  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
928  g_object_class_install_property (gobject_class, PROP_INPUTLAYOUT,
929  g_param_spec_string ("inputlayout", "Input Data Layout",
930  "Set channel first (NCHW) or channel last layout (NHWC) or None for input data. "
931  "Layout of the data can be any or NHWC or NCHW or none for now. ",
932  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
933  g_object_class_install_property (gobject_class, PROP_INPUTRANKS,
934  g_param_spec_string ("inputranks", "Rank of Input Tensor",
935  "The Rank of the Input Tensor, which is separated with ',' in case of multiple Tensors",
936  "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
937  g_object_class_install_property (gobject_class, PROP_OUTPUTNAME,
938  g_param_spec_string ("outputname", "Name of Output Tensor",
939  "The Name of Output Tensor", "",
940  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
941  g_object_class_install_property (gobject_class, PROP_OUTPUT,
942  g_param_spec_string ("output", "Output dimension",
943  "Output tensor dimension from inner array (Max rank #NNS_TENSOR_RANK_LIMIT)",
944  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
945  g_object_class_install_property (gobject_class, PROP_OUTPUTTYPE,
946  g_param_spec_string ("outputtype", "Output tensor element type",
947  "Type of each element of the output tensor ?", "",
948  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
949  g_object_class_install_property (gobject_class, PROP_OUTPUTLAYOUT,
950  g_param_spec_string ("outputlayout", "Output Data Layout",
951  "Set channel first (NCHW) or channel last layout (NHWC) or None for output data. "
952  "Layout of the data can be any or NHWC or NCHW or none for now. ",
953  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
954  g_object_class_install_property (gobject_class, PROP_OUTPUTRANKS,
955  g_param_spec_string ("outputranks", "Rank of Out Tensor",
956  "The Rank of the Out Tensor, which is separated with ',' in case of multiple Tensors",
957  "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
958  g_object_class_install_property (gobject_class, PROP_CUSTOM,
959  g_param_spec_string ("custom", "Custom properties for subplugins",
960  "Custom properties for subplugins ?", "",
961  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
962  g_object_class_install_property (gobject_class, PROP_SUBPLUGINS,
963  g_param_spec_string ("sub-plugins", "Sub-plugins",
964  "Registrable sub-plugins list", "",
965  G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
966  g_object_class_install_property (gobject_class, PROP_ACCELERATOR,
967  g_param_spec_string ("accelerator", "ACCELERATOR",
968  "Set accelerator for the subplugin with format "
969  "(true/false):(comma separated ACCELERATOR(s)). "
970  "true/false determines if accelerator is to be used. "
971  "list of accelerators determines the backend (ignored with false). "
972  "Example, if GPU, NPU can be used but not CPU - true:npu,gpu,!cpu. "
973  "The full list of accelerators can be found in nnstreamer_plugin_api_filter.h. "
974  "Note that only a few subplugins support this property.",
975  "", G_PARAM_READWRITE));
976  g_object_class_install_property (gobject_class, PROP_IS_UPDATABLE,
977  g_param_spec_boolean ("is-updatable", "Updatable model",
978  "Indicate whether a given model to this tensor filter is "
979  "updatable in runtime. (e.g., with on-device training)",
980  FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
981  g_object_class_install_property (gobject_class, PROP_LATENCY,
982  g_param_spec_int ("latency", "The average latency",
983  "Turn on performance profiling for the average latency "
984  "over the recent 10 inferences in microseconds. "
985  "Currently, this accepts either 0 (OFF) or 1 (ON).",
986  0 , 1 , 0 ,
987  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
988  g_object_class_install_property (gobject_class, PROP_THROUGHPUT,
989  g_param_spec_int ("throughput", "The average throughput (FPS)",
990  "Turn on performance profiling for the average throughput "
991  "in the number of outputs per seconds (i.e., FPS), multiplied by 1000 "
992  "to represent a floating point using an integer. "
993  "Currently, this accepts either 0 (OFF) or 1 (ON).",
994  0 , 1 , 0 ,
995  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
996  g_object_class_install_property (gobject_class, PROP_INPUTCOMBINATION,
997  g_param_spec_string ("input-combination", "input tensor(s) to invoke",
998  "Select the input tensor(s) to invoke the models", "",
999  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1000  g_object_class_install_property (gobject_class, PROP_OUTPUTCOMBINATION,
1001  g_param_spec_string ("output-combination", "output tensor(s) combination",
1002  "Select the output tensor(s) from the input tensor(s) and/or model output",
1003  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1004  g_object_class_install_property (gobject_class, PROP_SHARED_TENSOR_FILTER_KEY,
1005  g_param_spec_string ("shared-tensor-filter-key",
1006  "The key(name) of shared model representation",
1007  "Multiple element instances of tensor-filter in a pipeline may share "
1008  "a single resource instance if they share the same framework (subplugin) "
1009  "and neural network model. Designate \"shared-tensor-filter-key\" "
1010  "to declare and share such instances. "
1011  "If it is NULL, it means the model representations is not shared.",
1012  NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1013  g_object_class_install_property (gobject_class, PROP_LATENCY_REPORT,
1014  g_param_spec_boolean ("latency-report", "Latency report",
1015  "Report to the pipeline the estimated tensor-filter element latency.",
1016  FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1017  g_object_class_install_property (gobject_class, PROP_INVOKE_DYNAMIC,
1018  g_param_spec_boolean ("invoke-dynamic", "Enable dynamic invoke",
1019  "Flexible tensors whose memory size changes can be used as"
1020  "input and output of the tensor filter. "
1021  "With this option, the output caps is always in the format of flexible tensors.",
1022  FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1023  g_object_class_install_property (gobject_class, PROP_CONFIG,
1024  g_param_spec_string ("config-file", "Configuration-file",
1025  "Path to configuration file which contains plugins properties", "",
1026  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1027  g_object_class_install_property (gobject_class, PROP_SUSPEND,
1028  g_param_spec_uint ("suspend",
1029  "Timeout for unloading the framework",
1030  "Unload the framework if there is no new data within the timeout (ms). "
1031  "When the data arrives, load the framework and run the timer again. "
1032  "The state of the pipeline does not change. "
1033  "Default 0 means no suspend.", 0, G_MAXUINT32, 0,
1034  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1035 }
1036 
1040 void
1042 {
1043  /* init null */
1044  memset (priv, 0, sizeof (GstTensorFilterPrivate));
1045 
1046  /* init NNFW properties */
1050 
1051  /* set default framework 'auto' */
1052  priv->prop.fwname = g_strdup ("auto");
1053 
1054  /* init internal properties */
1055  priv->silent = TRUE;
1056  priv->prop.invoke_dynamic = FALSE;
1059 }
1060 
1064 void
1066 {
1068 
1069  prop = &priv->prop;
1070 
1071  g_free_const (prop->fwname);
1072  g_free_const (prop->accl_str);
1073  g_free (prop->hw_list);
1074  g_free (prop->shared_tensor_filter_key);
1075 
1076  g_free_const (prop->custom_properties);
1077  g_strfreev_const (prop->model_files);
1078 
1079  gst_tensors_info_free (&prop->input_meta);
1080  gst_tensors_info_free (&prop->output_meta);
1081 
1084  g_free (priv->config_path);
1085 
1086  g_list_free (priv->combi.in_combi);
1087  g_list_free (priv->combi.out_combi_i);
1088  g_list_free (priv->combi.out_combi_o);
1089 
1090  if (priv->stat.recent_latencies != NULL) {
1091  GQueue *queue = priv->stat.recent_latencies;
1092  gint64 *latency;
1093  while ((latency = g_queue_pop_tail (queue)) != NULL)
1094  g_free (latency);
1095  g_queue_free (queue);
1096  }
1097 
1098  G_LOCK (shared_model_table);
1099  if (shared_model_table) {
1101  GList *value = g_hash_table_get_values (shared_model_table);
1102 
1103  while (value) {
1104  rep = (GstTensorFilterSharedModelRepresentation *) value->data;
1105  g_list_free (rep->referred_list);
1106  value = g_list_next (value);
1107  }
1108 
1109  g_hash_table_destroy (shared_model_table);
1110  shared_model_table = NULL;
1111  }
1112  G_UNLOCK (shared_model_table);
1113 }
1114 
1122 static void
1124  GstTensorFilterProperties * prop, const char *accelerators)
1125 {
1126  gint status, idx;
1128  const gchar **accl_support;
1129  GList *match_accl, *iter;
1130 
1131  prop->num_hw = 0;
1132  g_free (prop->hw_list);
1133  prop->hw_list = NULL;
1134 
1136  if (!priv->fw || !GST_TF_FW_V1 (priv->fw))
1137  return;
1138 
1140  status = priv->fw->getFrameworkInfo (priv->fw, prop, NULL, &info);
1141  if (status != 0 || info.hw_list == NULL || info.num_hw <= 0) {
1142  ml_logw ("Unable to fetch accelerators supported by the framework.");
1143  return;
1144  }
1145 
1150  accl_support = g_malloc (sizeof (gchar *) * (info.num_hw + 2 + 1));
1151 
1152  for (idx = 0; idx < info.num_hw; idx++) {
1153  accl_support[idx] = get_accl_hw_str (info.hw_list[idx]);
1154  }
1155  accl_support[info.num_hw] = ACCL_AUTO_STR;
1156  accl_support[info.num_hw + 1] = ACCL_DEFAULT_STR;
1157  accl_support[info.num_hw + 2] = NULL;
1158 
1160  match_accl = parse_accl_hw_all (accelerators, accl_support);
1161  g_free (accl_support);
1162 
1164  prop->num_hw = g_list_length (match_accl);
1165  prop->hw_list = g_malloc (sizeof (accl_hw) * prop->num_hw);
1166  for (iter = match_accl, idx = 0; iter != NULL; iter = iter->next, idx++) {
1167  prop->hw_list[idx] = GPOINTER_TO_INT (iter->data);
1168  if (prop->hw_list[idx] == ACCL_AUTO) {
1169  prop->hw_list[idx] = info.accl_auto;
1170  if (info.accl_auto < ACCL_NONE)
1171  prop->hw_list[idx] = info.hw_list[0];
1172  } else if (prop->hw_list[idx] == ACCL_DEFAULT) {
1173  prop->hw_list[idx] = info.accl_default;
1174  if (info.accl_default < ACCL_NONE)
1175  prop->hw_list[idx] = info.hw_list[0];
1176  }
1177  }
1178  g_list_free (match_accl);
1179 }
1180 
1184 static gchar *
1185 _detect_framework_from_config (const gchar * extension)
1186 {
1187  gchar *detected = NULL;
1188  gchar *fw_key;
1189  gchar *priority_str;
1190  gchar **priority_arr;
1191  guint i, len;
1192 
1197  fw_key = g_strdup_printf ("framework_priority_%s", extension);
1198  priority_str = nnsconf_get_custom_value_string ("filter", fw_key);
1199  g_free (fw_key);
1200 
1201  if (priority_str) {
1202  priority_arr = g_strsplit (priority_str, ",", -1);
1203  len = g_strv_length (priority_arr);
1204 
1205  for (i = 0; i < len; i++) {
1206  if (nnstreamer_filter_find (priority_arr[i])) {
1207  detected = g_strdup (priority_arr[i]);
1208  nns_logi ("Detected framework is %s.", detected);
1209  nns_logd
1210  ("If you want to change priority of framework for auto detection, please edit meson_option.txt. You can find the file at root path of nnstreamer.");
1211  break;
1212  }
1213  }
1214 
1215  g_free (priority_str);
1216  g_strfreev (priority_arr);
1217  }
1218 
1219  return detected;
1220 }
1221 
1231 gchar *
1232 gst_tensor_filter_detect_framework (const gchar * const *model_files,
1233  const guint num_models, const gboolean load_conf)
1234 {
1235  gchar *detected_fw = NULL;
1236  gchar **ext = NULL;
1237  gchar *pos;
1238  guint i;
1239 
1240  g_return_val_if_fail (model_files && num_models > 0, NULL);
1241 
1242  /* Supposed it is ONE if given model is directory */
1243  if (g_file_test (model_files[0], G_FILE_TEST_IS_DIR)) {
1244  detected_fw = g_strdup ("nnfw");
1245  goto done;
1246  }
1247 
1252  ext = g_malloc0 (sizeof (char *) * (num_models + 1));
1253  for (i = 0; i < num_models; i++) {
1254  if ((pos = strrchr (model_files[i], '.')) == NULL) {
1255  nns_logw ("Given model file %s has invalid extension.", model_files[i]);
1256  goto done;
1257  }
1258 
1259  ext[i] = g_ascii_strdown (pos, -1);
1260  }
1261 
1262  /* Detect framework based on file extension */
1263  if (num_models == 1) {
1264  if (load_conf) {
1265  detected_fw = _detect_framework_from_config (ext[0] + 1);
1266  if (detected_fw)
1267  goto done;
1268  }
1269 
1270  if (g_str_equal (ext[0], ".tflite"))
1271  detected_fw = g_strdup ("tensorflow-lite");
1272  else if (g_str_equal (ext[0], ".pb"))
1273  detected_fw = g_strdup ("tensorflow");
1274  else if (g_str_equal (ext[0], ".pt"))
1275  detected_fw = g_strdup ("pytorch");
1276  else if (g_str_equal (ext[0], ".dlc"))
1277  detected_fw = g_strdup ("snpe");
1278  else if (g_str_equal (ext[0], ".py"))
1279  detected_fw = g_strdup ("python");
1280  else if (g_str_equal (ext[0], ".graph"))
1281  detected_fw = g_strdup ("movidius-ncsdk2");
1282  else if (g_str_equal (ext[0], ".ini"))
1283  detected_fw = g_strdup ("nntrainer");
1284  else if (g_str_equal (ext[0], ".circle"))
1285  detected_fw = g_strdup ("nnfw");
1286  else if (g_str_equal (ext[0], NNSTREAMER_SO_FILE_EXTENSION))
1287  detected_fw = g_strdup ("custom");
1288  else if (g_str_equal (ext[0], ".bin") || g_str_equal (ext[0], ".xml"))
1289  detected_fw = g_strdup ("openvino");
1290  else if (g_str_equal (ext[0], ".tvn"))
1291  detected_fw = g_strdup ("trix-engine");
1292  } else if (num_models == 2) {
1293  if (g_str_equal (ext[0], ".pb") && g_str_equal (ext[1], ".pb") &&
1294  !g_str_equal (model_files[0], model_files[1]))
1295  detected_fw = g_strdup ("caffe2");
1296  else if ((g_str_equal (ext[0], ".so") && g_str_equal (ext[1], ".nb")) ||
1297  (g_str_equal (ext[1], ".so") && g_str_equal (ext[0], ".nb")))
1298  detected_fw = g_strdup ("vivante");
1299  } else {
1300  nns_logw ("Invalid number of model files.");
1301  }
1302 
1303 done:
1304  g_strfreev (ext);
1305 
1306  if (!detected_fw)
1307  nns_logw ("Cannot get any neural network framework for given model.");
1308  return detected_fw;
1309 }
1310 
1316 static void
1318  const char *fw_name)
1319 {
1321  const GstTensorFilterFramework *fw;
1322  gchar *detected_fw = NULL;
1323 
1324  if (fw_name == NULL)
1325  return;
1326 
1327  prop = &priv->prop;
1328 
1329  if (g_ascii_strcasecmp (fw_name, "auto") == 0) {
1330  if (prop->model_files == NULL) {
1331  /* If model file is not loaded, get framework after loading the model */
1332  g_free_const (prop->fwname);
1333  prop->fwname = g_strdup (fw_name);
1334  return;
1335  }
1336 
1337  detected_fw = gst_tensor_filter_detect_framework (prop->model_files,
1338  prop->num_models, TRUE);
1339  } else {
1340  detected_fw = g_strdup (fw_name);
1341  }
1342 
1343  /* init fw-name (case if fw-name is auto) */
1344  if (prop->fwname) {
1345  g_free_const (prop->fwname);
1346  prop->fwname = NULL;
1347  }
1348 
1349  nns_logd ("Framework = %s\n", fw_name);
1350 
1351  fw = nnstreamer_filter_find (detected_fw);
1352 
1353  if (fw) {
1355  if (GST_TF_FW_V1 (fw)) {
1357 
1359  if (fw->getFrameworkInfo (fw, prop, NULL, &info) < 0) {
1360  nns_logw ("Cannot get the given framework info, %s\n", fw_name);
1361  g_free (detected_fw);
1362  return;
1363  }
1364  }
1365  priv->fw = fw;
1366  prop->fwname = detected_fw;
1367 
1369  if (GST_TF_FW_V1 (priv->fw) && prop->accl_str) {
1370  gst_tensor_filter_parse_accelerator (priv, &priv->prop, prop->accl_str);
1371  }
1372  } else {
1373  nns_logw ("Cannot identify the given neural network framework, %s\n",
1374  fw_name);
1375  g_free (detected_fw);
1376  }
1377 }
1378 
1380 static gint
1382  GstTensorFilterProperties * prop, const GValue * value)
1383 {
1384  gint status;
1385  const gchar *fw_name = g_value_get_string (value);
1386  GValue val = G_VALUE_INIT;
1387 
1388  if (priv->fw != NULL) {
1389  if (g_strcmp0 (priv->prop.fwname, fw_name) != 0) {
1390  /* close old framework, if different */
1392  priv->fw = NULL;
1393  } else {
1394  ml_logd ("Framework = %s\n", fw_name);
1395  return 0;
1396  }
1397  }
1398 
1400 
1402  g_value_init (&val, G_TYPE_BOOLEAN);
1403  g_value_set_boolean (&val, priv->is_updatable);
1404  status = _gtfc_setprop_IS_UPDATABLE (priv, prop, &val);
1405  g_value_unset (&val);
1406  if (status != 0) {
1407  ml_logw ("Set property is-updatable failed with error: %d", status);
1408  return status;
1409  }
1410 
1412  if (prop->accl_str) {
1413  g_value_init (&val, G_TYPE_STRING);
1414  g_value_set_string (&val, prop->accl_str);
1415  status = _gtfc_setprop_ACCELERATOR (priv, prop, &val);
1416  g_value_unset (&val);
1417  if (status != 0) {
1418  ml_logw ("Set property accelerator failed with error: %d", status);
1419  return status;
1420  }
1421  }
1422 
1423  return 0;
1424 }
1425 
1427 static gint
1429  GstTensorFilterProperties * prop, const GValue * value)
1430 {
1431  gint status = 0;
1432  g_autofree gchar *model_files = mlagent_get_model_path_from (value);
1434 
1435  if (!model_files) {
1436  ml_loge ("Invalid model provided to the tensor-filter.");
1437  return 0;
1438  }
1439  _prop.model_files = NULL;
1440 
1441  if (prop->fw_opened) {
1443  memcpy (&_prop, prop, sizeof (GstTensorFilterProperties));
1444  _prop.model_files =
1445  (const gchar **) g_strdupv ((gchar **) prop->model_files);
1446  }
1447 
1449 
1450  if (prop->fwname != NULL && g_ascii_strcasecmp (prop->fwname, "auto") == 0)
1452 
1458  if (prop->fw_opened) {
1459  if (GST_TF_FW_V0 (priv->fw) && priv->is_updatable) {
1460  if (priv->fw->reloadModel &&
1461  priv->fw->reloadModel (prop, &priv->privateData) != 0) {
1462  status = -1;
1463  }
1464  } else if (GST_TF_FW_V1 (priv->fw) && priv->is_updatable) {
1466  data.model_files = prop->model_files;
1467  data.num_models = prop->num_models;
1469  if (priv->fw->eventHandler (priv->fw, &_prop, priv->privateData,
1470  RELOAD_MODEL, &data) != 0) {
1471  status = -1;
1472  }
1473  }
1474 
1475  if (status == 0) {
1476  g_strfreev_const (_prop.model_files);
1477  } else {
1478  ml_loge ("Fail to reload model\n");
1479  g_strfreev_const (prop->model_files);
1480  prop->model_files = _prop.model_files;
1481  prop->num_models = _prop.num_models;
1482  }
1483  }
1484 
1485  return 0;
1486 }
1487 
1489 static gint
1491  const GValue * value, const gboolean is_input)
1492 {
1494  GstTensorsInfo *info;
1495  unsigned int *rank;
1496  int configured;
1497 
1498  prop = &priv->prop;
1499 
1500  if (is_input) {
1501  info = &prop->input_meta;
1502  rank = prop->input_ranks;
1503  configured = prop->input_configured;
1504  } else {
1505  info = &prop->output_meta;
1506  rank = prop->output_ranks;
1507  configured = prop->output_configured;
1508  }
1509 
1510  if (!configured && value) {
1511  guint num_dims;
1512  gchar **str_dims;
1513  guint i;
1514 
1515  str_dims = g_strsplit_set (g_value_get_string (value), ",.", -1);
1516  num_dims = g_strv_length (str_dims);
1517 
1518  if (num_dims > NNS_TENSOR_SIZE_LIMIT) {
1519  nns_logw ("Invalid param, dimensions (%d) max (%d)\n",
1520  num_dims, NNS_TENSOR_SIZE_LIMIT);
1521 
1522  num_dims = NNS_TENSOR_SIZE_LIMIT;
1523  }
1524 
1525  for (i = 0; i < num_dims; ++i) {
1526  rank[i] = gst_tensor_parse_dimension (str_dims[i],
1527  gst_tensors_info_get_nth_info (info, i)->dimension);
1528  }
1529  g_strfreev (str_dims);
1530 
1531  if (num_dims > 0) {
1532  if (info->num_tensors > 0 && info->num_tensors != num_dims) {
1533  ml_logw
1534  ("Invalid dimension, given param does not match with old value.");
1535  }
1536 
1537  info->num_tensors = num_dims;
1538  }
1539  } else if (value) {
1541  ml_loge
1542  ("Cannot change dimension once the element/pipeline is configured.");
1543  }
1544  return 0;
1545 }
1546 
1548 static gint
1550  const GValue * value, const gboolean is_input)
1551 {
1553  GstTensorsInfo *info;
1554  int configured;
1555 
1556  prop = &priv->prop;
1557 
1558  if (is_input) {
1559  info = &prop->input_meta;
1560  configured = prop->input_configured;
1561  } else {
1562  info = &prop->output_meta;
1563  configured = prop->output_configured;
1564  }
1565 
1566  if (!configured && value) {
1567  guint num_types;
1568 
1569  num_types = gst_tensors_info_parse_types_string (info,
1570  g_value_get_string (value));
1571 
1572  if (num_types > 0) {
1573  if (info->num_tensors > 0 && info->num_tensors != num_types) {
1574  ml_logw ("Invalid type, given param does not match with old value.");
1575  }
1576 
1577  info->num_tensors = num_types;
1578  }
1579  } else if (value) {
1581  ml_loge ("Cannot change type once the element/pipeline is configured.");
1582  }
1583  return 0;
1584 }
1585 
1587 static gint
1589  const GValue * value, const gboolean is_input)
1590 {
1592  GstTensorsInfo *info;
1593  int configured;
1594 
1595  prop = &priv->prop;
1596 
1597  if (is_input) {
1598  info = &prop->input_meta;
1599  configured = prop->input_configured;
1600  } else {
1601  info = &prop->output_meta;
1602  configured = prop->output_configured;
1603  }
1604 
1605  if (!configured && value) {
1606  guint num_names;
1607 
1608  num_names = gst_tensors_info_parse_names_string (info,
1609  g_value_get_string (value));
1610 
1611  if (num_names > 0) {
1612  if (info->num_tensors > 0 && info->num_tensors != num_names) {
1613  ml_logw ("Invalid name, given param does not match with old value.");
1614  }
1615 
1616  info->num_tensors = num_names;
1617  }
1618  } else if (value) {
1620  ml_loge ("Cannot change name once the element/pipeline is configured.");
1621  }
1622  return 0;
1623 }
1624 
1626 static gint
1628  GstTensorFilterProperties * prop, const GValue * value)
1629 {
1630  gint status = 0;
1631  if (!priv->prop.fw_opened) {
1632  g_free_const (prop->custom_properties);
1633  prop->custom_properties = g_value_dup_string (value);
1634  } else {
1635  if (GST_TF_FW_V0 (priv->fw)) {
1636  ml_loge
1637  ("Cannot change custom-prop once the element/pipeline is configured.");
1638  } else if (GST_TF_FW_V1 (priv->fw)) {
1640 
1641  data.custom_properties = g_value_dup_string (value);
1642  status = priv->fw->eventHandler
1643  (priv->fw, prop, priv->privateData, CUSTOM_PROP, &data);
1644  if (status == 0) {
1645  g_free_const (prop->custom_properties);
1646  prop->custom_properties = g_value_dup_string (value);
1647  }
1648 
1649  g_free_const (data.custom_properties);
1650  }
1651  }
1652 
1653  return 0;
1654 }
1655 
1657 static gint
1659  GstTensorFilterProperties * prop, const GValue * value)
1660 {
1661  gint status = 0;
1662  const gchar *accelerators = g_value_get_string (value);
1663 
1664  if (priv->prop.fw_opened == TRUE) {
1665  if (GST_TF_FW_V0 (priv->fw)) {
1666  ml_loge
1667  ("Cannot change accelerator once the element/pipeline is configured.");
1668  } else if (GST_TF_FW_V1 (priv->fw)) {
1671  memcpy (&_prop, prop, sizeof (GstTensorFilterProperties));
1672 
1673  /* null-init hw list before parsing accel string (old ptr in _prop). */
1674  prop->num_hw = 0;
1675  prop->hw_list = NULL;
1676 
1677  gst_tensor_filter_parse_accelerator (priv, prop, accelerators);
1678  data.num_hw = prop->num_hw;
1679  data.hw_list = prop->hw_list;
1680 
1681  status = priv->fw->eventHandler
1682  (priv->fw, &_prop, priv->privateData, SET_ACCELERATOR, &data);
1683  if (status == 0) {
1684  g_free (_prop.hw_list);
1685  } else {
1686  prop->num_hw = _prop.num_hw;
1687  g_free (prop->hw_list);
1688  prop->hw_list = _prop.hw_list;
1689  }
1690  }
1691  return 0;
1692  }
1693 
1694  if (priv->fw) {
1695  if (GST_TF_FW_V0 (priv->fw)) {
1696  g_free_const (prop->accl_str);
1697  prop->accl_str = g_strdup (accelerators);
1698  } else if (GST_TF_FW_V1 (priv->fw)) {
1699  gst_tensor_filter_parse_accelerator (priv, prop, accelerators);
1700  }
1701  } else {
1702  g_free_const (prop->accl_str);
1703  prop->accl_str = g_strdup (accelerators);
1704  }
1705  return 0;
1706 }
1707 
1709 static gint
1711  GstTensorFilterProperties * prop, const GValue * value)
1712 {
1713  if (priv->fw) {
1714  if (GST_TF_FW_V0 (priv->fw) && priv->fw->reloadModel == NULL) {
1715  priv->is_updatable = FALSE;
1716  return 0;
1717  } else if (GST_TF_FW_V1 (priv->fw) &&
1718  priv->fw->eventHandler (priv->fw, prop, priv->privateData, RELOAD_MODEL,
1719  NULL)
1720  == -ENOENT) {
1721  priv->is_updatable = FALSE;
1722  return 0;
1723  }
1724  }
1725 
1726  priv->is_updatable = g_value_get_boolean (value);
1727  return 0;
1728 }
1729 
1731 static gint
1733  const GValue * value, const gboolean is_input)
1734 {
1736  GstTensorsInfo *info;
1737  tensors_layout *layout;
1738  int configured;
1739  event_ops evt;
1740  guint num_layouts;
1741 
1742  prop = &priv->prop;
1743 
1744  if (is_input) {
1745  info = &prop->input_meta;
1746  layout = &prop->input_layout;
1747  configured = prop->input_configured;
1748  evt = SET_INPUT_PROP;
1749  } else {
1750  info = &prop->output_meta;
1751  layout = &prop->output_layout;
1752  configured = prop->output_configured;
1753  evt = SET_OUTPUT_PROP;
1754  }
1755 
1756  if (!configured && value) {
1757  num_layouts = gst_tensors_parse_layouts_string (*layout,
1758  g_value_get_string (value));
1759 
1760  if (num_layouts > 0) {
1761  if (info->num_tensors > 0 && info->num_tensors != num_layouts) {
1762  ml_logw ("Invalid layout, given param does not fit.");
1763  }
1764 
1765  info->num_tensors = num_layouts;
1766  }
1767  } else if (value) {
1769  if (GST_TF_FW_V0 (priv->fw)) {
1770  /* Once configured, it cannot be changed in runtime */
1771  ml_loge ("Cannot change layout once the element/pipeline is configured.");
1772  } else if (GST_TF_FW_V1 (priv->fw)) {
1774 
1775  data.info = NULL;
1776  num_layouts = gst_tensors_parse_layouts_string (data.layout,
1777  g_value_get_string (value));
1778 
1779  if (num_layouts > 0) {
1780  if (info->num_tensors > 0 && info->num_tensors != num_layouts) {
1781  ml_logw ("Invalid layout, given param does not fit.");
1782  }
1783 
1784  if (priv->fw->eventHandler
1785  (priv->fw, prop, priv->privateData, evt, &data) == 0) {
1786  memcpy (*layout, data.layout,
1787  sizeof (tensor_layout) * (NNS_TENSOR_SIZE_LIMIT));
1788  } else {
1789  ml_logw ("Unable to update layout.");
1790  }
1791  }
1792  }
1793  }
1794  return 0;
1795 }
1796 
1798 static gint
1800  GstTensorFilterProperties * prop, const GValue * value)
1801 {
1802  gint latency_mode;
1803  UNUSED (prop);
1804 
1805  if (!value)
1806  return 0;
1807 
1808  latency_mode = g_value_get_int (value);
1809  if (latency_mode != 0 && latency_mode != 1) {
1810  ml_logw ("Invalid argument, neither 0 (OFF) nor 1 (ON).");
1811  return 0;
1812  }
1813 
1814  priv->latency_mode = latency_mode;
1815 
1816  return 0;
1817 }
1818 
1820 static gint
1822  GstTensorFilterProperties * prop, const GValue * value)
1823 {
1824  gint throughput_mode;
1825  UNUSED (prop);
1826 
1827  if (!value)
1828  return 0;
1829 
1830  throughput_mode = g_value_get_int (value);
1831  if (throughput_mode != 0 && throughput_mode != 1) {
1832  ml_logw ("Invalid argument, neither 0 (OFF) nor 1 (ON).");
1833  return 0;
1834  }
1835 
1836  priv->throughput_mode = throughput_mode;
1837 
1838  return 0;
1839 }
1840 
1842 static gint
1844  GList ** prop_list, const GValue * value)
1845 {
1846  guint64 val;
1847  const gchar *param = g_value_get_string (value);
1848  gchar **strv = g_strsplit_set (param, ",", -1);
1849  gint i, ret = 0, num = g_strv_length (strv);
1850 
1851  /* release old list */
1852  g_list_free (*prop_list);
1853  *prop_list = NULL;
1854 
1855  for (i = 0; i < num; i++) {
1856  val = g_ascii_strtoull (strv[i], NULL, 10);
1857  if (errno == ERANGE || val >= NNS_TENSOR_SIZE_LIMIT) {
1858  ml_loge ("Invalid value %s, cannot set combination option.", strv[i]);
1859  ret = ERANGE;
1860  break;
1861  }
1862  *prop_list = g_list_append (*prop_list, GUINT_TO_POINTER (val));
1863  }
1864  g_strfreev (strv);
1865 
1866  if (ret == 0 && num > 0)
1867  priv->combi.in_combi_defined = TRUE;
1868 
1869  return ret;
1870 }
1871 
1873 static gint
1875  GList ** prop_list1, GList ** prop_list2, const GValue * value)
1876 {
1877  guint64 val;
1878  const gchar *param = g_value_get_string (value);
1879  gchar **strv = g_strsplit_set (param, ",", -1);
1880  gint i, ret = 0, num = g_strv_length (strv);
1881 
1882  /* release old list */
1883  g_list_free (*prop_list1);
1884  g_list_free (*prop_list2);
1885  *prop_list1 = *prop_list2 = NULL;
1886 
1887  for (i = 0; i < num; i++) {
1888  if (strv[i][0] == 'i') {
1889  val = g_ascii_strtoull (&strv[i][1], NULL, 10);
1890  *prop_list1 = g_list_append (*prop_list1, GUINT_TO_POINTER (val));
1891  priv->combi.out_combi_i_defined = TRUE;
1892  } else if (strv[i][0] == 'o') {
1893  val = g_ascii_strtoull (&strv[i][1], NULL, 10);
1894  *prop_list2 = g_list_append (*prop_list2, GUINT_TO_POINTER (val));
1895  priv->combi.out_combi_o_defined = TRUE;
1896  } else {
1897  ml_loge ("Wrong format for output combination properties. "
1898  "Please specify for input tensor(s): i#num, for output tensor(s): o#num "
1899  "e.g., output-combination=i0,i2,o0,o1");
1900  ret = EINVAL;
1901  break;
1902  }
1903 
1904  if (errno == ERANGE || val >= NNS_TENSOR_SIZE_LIMIT) {
1905  ml_loge ("Invalid value %s, cannot set combination option.", strv[i]);
1906  ret = ERANGE;
1907  break;
1908  }
1909  }
1910  g_strfreev (strv);
1911 
1912  return ret;
1913 }
1914 
1916 static gint
1918  const GValue * value)
1919 {
1920  g_free (prop->shared_tensor_filter_key);
1921  prop->shared_tensor_filter_key = g_value_dup_string (value);
1922 
1923  G_LOCK (shared_model_table);
1924  if (!shared_model_table) {
1926  g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1927  }
1928  G_UNLOCK (shared_model_table);
1929 
1930  return 0;
1931 }
1932 
1936 static gint
1938  const GValue * value)
1939 {
1940  priv->prop.invoke_dynamic = g_value_get_boolean (value);
1941  priv->info.allocate_in_invoke = TRUE;
1942 
1943  return 0;
1944 }
1945 
1949 static gint
1951  const GValue * value)
1952 {
1953  priv->prop.suspend = g_value_get_uint (value);
1954 
1955  return 0;
1956 }
1957 
1966 gboolean
1968  guint prop_id, const GValue * value, GParamSpec * pspec)
1969 {
1970  gint status = 0;
1972  UNUSED (pspec);
1973 
1974  prop = &priv->prop;
1975 
1976  switch (prop_id) {
1977  case PROP_SILENT:
1978  priv->silent = g_value_get_boolean (value);
1979  break;
1980  case PROP_FRAMEWORK:
1981  status = _gtfc_setprop_FRAMEWORK (priv, prop, value);
1982  break;
1983  case PROP_MODEL:
1984  status = _gtfc_setprop_MODEL (priv, prop, value);
1985  break;
1986  case PROP_INPUT:
1987  status = _gtfc_setprop_DIMENSION (priv, value, TRUE);
1988  break;
1989  case PROP_OUTPUT:
1990  status = _gtfc_setprop_DIMENSION (priv, value, FALSE);
1991  break;
1992  case PROP_INPUTTYPE:
1993  status = _gtfc_setprop_TYPE (priv, value, TRUE);
1994  break;
1995  case PROP_OUTPUTTYPE:
1996  status = _gtfc_setprop_TYPE (priv, value, FALSE);
1997  break;
1998  case PROP_INPUTNAME:
1999  /* INPUTNAME is required by tensorflow to designate the order of tensors */
2000  status = _gtfc_setprop_NAME (priv, value, TRUE);
2001  break;
2002  case PROP_OUTPUTNAME:
2003  /* OUTPUTNAME is required by tensorflow to designate the order of tensors */
2004  status = _gtfc_setprop_NAME (priv, value, FALSE);
2005  break;
2006  case PROP_CUSTOM:
2007  status = _gtfc_setprop_CUSTOM (priv, prop, value);
2008  break;
2009  case PROP_ACCELERATOR:
2010  status = _gtfc_setprop_ACCELERATOR (priv, prop, value);
2011  break;
2012  case PROP_IS_UPDATABLE:
2013  status = _gtfc_setprop_IS_UPDATABLE (priv, prop, value);
2014  break;
2015  case PROP_INPUTLAYOUT:
2016  status = _gtfc_setprop_LAYOUT (priv, value, TRUE);
2017  break;
2018  case PROP_OUTPUTLAYOUT:
2019  status = _gtfc_setprop_LAYOUT (priv, value, FALSE);
2020  break;
2021  case PROP_LATENCY:
2022  status = _gtfc_setprop_LATENCY (priv, prop, value);
2023  break;
2024  case PROP_THROUGHPUT:
2025  status = _gtfc_setprop_THROUGHPUT (priv, prop, value);
2026  break;
2027  case PROP_INPUTCOMBINATION:
2028  status =
2029  _gtfc_setprop_INPUTCOMBINATION (priv, &priv->combi.in_combi, value);
2030  break;
2032  status = _gtfc_setprop_OUTPUTCOMBINATION (priv, &priv->combi.out_combi_i,
2033  &priv->combi.out_combi_o, value);
2034  break;
2036  status = _gtfc_setprop_SHARED_TENSOR_FILTER_KEY (prop, value);
2037  break;
2038  case PROP_LATENCY_REPORT:
2039  priv->latency_reporting = g_value_get_boolean (value);
2040  break;
2041  case PROP_INVOKE_DYNAMIC:
2042  status = _gtfc_setprop_PROP_INVOKE_DYNAMIC (priv, value);
2043  break;
2044  case PROP_SUSPEND:
2045  status = _gtfc_setprop_SUSPEND (priv, value);
2046  break;
2047  default:
2048  return FALSE;
2049  }
2050 
2052  if (0 != status)
2053  return FALSE;
2054 
2055  return TRUE;
2056 }
2057 
2058 
2062 static void
2064  GstTensorFilterPrivate * priv, guint prop_id)
2065 {
2066  GList *list;
2067  gchar *p;
2068  GPtrArray *arr = g_ptr_array_new ();
2069  gchar **strings;
2070 
2071  if (prop_id == PROP_INPUTCOMBINATION) {
2072  for (list = priv->combi.in_combi; list != NULL; list = list->next)
2073  g_ptr_array_add (arr, g_strdup_printf ("%u",
2074  GPOINTER_TO_UINT (list->data)));
2075  } else if (prop_id == PROP_OUTPUTCOMBINATION) {
2076  for (list = priv->combi.out_combi_i; list != NULL; list = list->next)
2077  g_ptr_array_add (arr, g_strdup_printf ("i%u",
2078  GPOINTER_TO_UINT (list->data)));
2079  for (list = priv->combi.out_combi_o; list != NULL; list = list->next)
2080  g_ptr_array_add (arr, g_strdup_printf ("o%u",
2081  GPOINTER_TO_UINT (list->data)));
2082  }
2083 
2084  g_ptr_array_add (arr, NULL);
2085  strings = (gchar **) g_ptr_array_free (arr, FALSE);
2086  g_strv_length (strings);
2087  p = g_strjoinv (",", strings);
2088 
2089  g_strfreev (strings);
2090  g_value_take_string (value, p);
2091 }
2092 
2101 gboolean
2103  guint prop_id, GValue * value, GParamSpec * pspec)
2104 {
2106  gchar *strval;
2107  UNUSED (pspec);
2108 
2109  prop = &priv->prop;
2110 
2111  switch (prop_id) {
2112  case PROP_SILENT:
2113  g_value_set_boolean (value, priv->silent);
2114  break;
2115  case PROP_FRAMEWORK:
2116  g_value_set_string (value, (prop->fwname != NULL) ? prop->fwname : "");
2117  break;
2118  case PROP_MODEL:
2119  {
2120  GString *gstr_models = g_string_new (NULL);
2121  gchar *models;
2122  int idx;
2123 
2124  /* return a comma-separated string */
2125  for (idx = 0; idx < prop->num_models; ++idx) {
2126  if (idx != 0) {
2127  g_string_append (gstr_models, ",");
2128  }
2129 
2130  g_string_append (gstr_models, prop->model_files[idx]);
2131  }
2132 
2133  models = g_string_free (gstr_models, FALSE);
2134  g_value_take_string (value, models);
2135  break;
2136  }
2137  case PROP_INPUT:
2139  g_value_take_string (value, strval);
2140  break;
2141  case PROP_OUTPUT:
2143  g_value_take_string (value, strval);
2144  break;
2145  case PROP_INPUTRANKS:
2147  g_value_take_string (value, strval);
2148  break;
2149  case PROP_OUTPUTRANKS:
2151  g_value_take_string (value, strval);
2152  break;
2153  case PROP_INPUTTYPE:
2155  g_value_take_string (value, strval);
2156  break;
2157  case PROP_OUTPUTTYPE:
2159  g_value_take_string (value, strval);
2160  break;
2161  case PROP_INPUTNAME:
2163  g_value_take_string (value, strval);
2164  break;
2165  case PROP_OUTPUTNAME:
2167  g_value_take_string (value, strval);
2168  break;
2169  case PROP_CUSTOM:
2170  g_value_set_string (value,
2171  (prop->custom_properties != NULL) ? prop->custom_properties : "");
2172  break;
2173  case PROP_SUBPLUGINS:
2174  {
2175  gchar **str_array = get_all_subplugins (NNS_SUBPLUGIN_FILTER);
2176 
2177  if (str_array) {
2178  g_value_take_string (value, g_strjoinv (",", str_array));
2179  g_strfreev (str_array);
2180  } else {
2181  g_value_set_string (value, "");
2182  }
2183  break;
2184  }
2185  case PROP_ACCELERATOR:
2186  {
2187  gint idx;
2188  GString *accl;
2189 
2190  if (priv->fw == NULL || GST_TF_FW_V0 (priv->fw)) {
2191  if (prop->accl_str != NULL) {
2192  g_value_set_string (value, prop->accl_str);
2193  } else {
2194  g_value_set_string (value, "");
2195  }
2196  } else if (GST_TF_FW_V1 (priv->fw)) {
2197  if (prop->num_hw == 0) {
2198  g_value_set_string (value, "");
2199  } else {
2200  accl = g_string_new (NULL);
2201 
2202  for (idx = 0; idx < prop->num_hw; idx++) {
2203  g_string_append (accl, get_accl_hw_str (prop->hw_list[idx]));
2204  }
2205  g_value_take_string (value, g_string_free (accl, FALSE));
2206  }
2207  }
2208  break;
2209  }
2210  case PROP_IS_UPDATABLE:
2211  g_value_set_boolean (value, priv->is_updatable);
2212  break;
2213  case PROP_INPUTLAYOUT:
2215  g_value_take_string (value, strval);
2216  break;
2217  case PROP_OUTPUTLAYOUT:
2219  g_value_take_string (value, strval);
2220  break;
2221  case PROP_LATENCY:
2222  if (priv->latency_mode == 1) {
2223  g_value_set_int (value, prop->latency);
2224  } else {
2225  /* invalid */
2226  g_value_set_int (value, -1);
2227  }
2228  break;
2229  case PROP_THROUGHPUT:
2230  if (priv->throughput_mode == 1) {
2231  g_value_set_int (value, prop->throughput);
2232  } else {
2233  /* invalid */
2234  g_value_set_int (value, -1);
2235  }
2236  break;
2237  case PROP_INPUTCOMBINATION:
2238  gst_tensor_filter_property_to_string (value, priv, prop_id);
2239  break;
2241  gst_tensor_filter_property_to_string (value, priv, prop_id);
2242  break;
2244  if (prop->shared_tensor_filter_key)
2245  g_value_set_string (value, prop->shared_tensor_filter_key);
2246  else
2247  g_value_set_string (value, "");
2248  break;
2249  case PROP_LATENCY_REPORT:
2250  g_value_set_boolean (value, priv->latency_reporting);
2251  break;
2252  case PROP_INVOKE_DYNAMIC:
2253  g_value_set_boolean (value, prop->invoke_dynamic);
2254  break;
2255  case PROP_SUSPEND:
2256  g_value_set_uint (value, prop->suspend);
2257  break;
2258  default:
2259  /* unknown property */
2260  return FALSE;
2261  }
2262 
2263  return TRUE;
2264 }
2265 
2269 gboolean
2271  const GstTensorsInfo * in, GstTensorsInfo * combined)
2272 {
2273  GList *list;
2274  guint i, idx = 0;
2275 
2276  g_return_val_if_fail (in != NULL, FALSE);
2277  g_return_val_if_fail (combined != NULL, FALSE);
2278 
2279  gst_tensors_info_init (combined);
2280 
2281  if (priv->combi.in_combi_defined) {
2282  for (list = priv->combi.in_combi; list != NULL; list = list->next) {
2283  i = GPOINTER_TO_UINT (list->data);
2284 
2285  if (i >= in->num_tensors) {
2286  nns_loge ("Invalid input index %u, failed to combine info.", i);
2287  goto error;
2288  }
2289 
2292 
2293  if (idx >= NNS_TENSOR_SIZE_LIMIT) {
2294  nns_loge ("The max number of tensors is %d.", NNS_TENSOR_SIZE_LIMIT);
2295  goto error;
2296  }
2297  }
2298 
2299  combined->num_tensors = idx;
2300  } else {
2301  gst_tensors_info_copy (combined, in);
2302  }
2303 
2304  return TRUE;
2305 
2306 error:
2307  gst_tensors_info_free (combined);
2308  return FALSE;
2309 }
2310 
2314 gboolean
2316  const GstTensorsInfo * in, const GstTensorsInfo * out,
2317  GstTensorsInfo * combined)
2318 {
2319  GList *list;
2320  guint i, idx = 0;
2321 
2322  g_return_val_if_fail (in != NULL, FALSE);
2323  g_return_val_if_fail (out != NULL, FALSE);
2324  g_return_val_if_fail (combined != NULL, FALSE);
2325 
2326  gst_tensors_info_init (combined);
2327 
2328  if (priv->combi.out_combi_i_defined || priv->combi.out_combi_o_defined) {
2329  if (priv->combi.out_combi_i_defined) {
2330  for (list = priv->combi.out_combi_i; list != NULL; list = list->next) {
2331  i = GPOINTER_TO_UINT (list->data);
2332 
2333  if (i >= in->num_tensors) {
2334  nns_loge ("Invalid input index %u, failed to combine info.", i);
2335  goto error;
2336  }
2337 
2340  }
2341  }
2342 
2343  if (priv->combi.out_combi_o_defined) {
2344  for (list = priv->combi.out_combi_o; list != NULL; list = list->next) {
2345  i = GPOINTER_TO_UINT (list->data);
2346 
2347  if (i >= out->num_tensors) {
2348  nns_loge ("Invalid output index %u, failed to combine info.", i);
2349  goto error;
2350  }
2351 
2354  }
2355  }
2356 
2357  combined->num_tensors = idx;
2358  combined->format = out->format;
2359  } else {
2360  gst_tensors_info_copy (combined, out);
2361  }
2362 
2363  return TRUE;
2364 
2365 error:
2366  gst_tensors_info_free (combined);
2367  return FALSE;
2368 }
2369 
2373 gboolean
2375  GstTensorsInfo * in, GstTensorsInfo * out)
2376 {
2377  int r = -1;
2378 
2379  g_return_val_if_fail (in != NULL, FALSE);
2380  g_return_val_if_fail (out != NULL, FALSE);
2381 
2382  gst_tensors_info_init (out);
2383 
2384  if (!gst_tensors_info_validate (in)) {
2385  nns_logw ("Given input info is invalid, cannot get output info.");
2386  return FALSE;
2387  }
2388 
2389  /* call setInputDimension with given input tensor */
2390  if (GST_TF_FW_V0 (priv->fw)) {
2391  gst_tensor_filter_v0_call (priv, r, setInputDimension, in, out);
2392  } else {
2393  gst_tensor_filter_v1_call (priv, r, getModelInfo, SET_INPUT_INFO, in, out);
2394  }
2395 
2396  if (r != 0) {
2397  nns_loge ("Failed to get output info from NN model.");
2398  return FALSE;
2399  }
2400 
2401  return TRUE;
2402 }
2403 
2408 void
2410 {
2412  GstTensorsInfo in_info, out_info;
2413  int res_in = -1, res_out = -1;
2414 
2415  prop = &priv->prop;
2416 
2417  gst_tensors_info_init (&in_info);
2418  gst_tensors_info_init (&out_info);
2419 
2420  if (GST_TF_FW_V1 (priv->fw)) {
2421  if (!prop->input_configured || !prop->output_configured) {
2422  gst_tensor_filter_v1_call (priv, res_in, getModelInfo, GET_IN_OUT_INFO,
2423  &in_info, &out_info);
2424  res_out = res_in;
2425  }
2426  } else {
2427  if (!prop->input_configured)
2428  gst_tensor_filter_v0_call (priv, res_in, getInputDimension, &in_info);
2429  if (!prop->output_configured)
2430  gst_tensor_filter_v0_call (priv, res_out, getOutputDimension, &out_info);
2431  }
2432 
2433  /* supposed fixed in-tensor info if getInputDimension was success. */
2434  if (!prop->input_configured && res_in == 0) {
2435  g_assert (in_info.num_tensors > 0);
2436 
2438  if (prop->input_meta.num_tensors > 0) {
2439  if (!gst_tensors_info_is_equal (&in_info, &prop->input_meta)) {
2440  gchar *cmpstr =
2441  gst_tensorsinfo_compare_to_string (&in_info, &prop->input_meta);
2442  ml_loge
2443  ("The input tensor is not compatible with the configuration of the model or tensor-filter property. The two tensor meta (GstTensorsInfo) are not compatible: %s\n",
2444  cmpstr);
2445  g_free (cmpstr);
2446  goto done;
2447  }
2448  } else {
2449  gst_tensors_info_copy (&prop->input_meta, &in_info);
2450  }
2451 
2452  prop->input_configured = TRUE;
2453  silent_debug_info (&in_info, "input tensor");
2454  }
2455 
2457  if (prop->invoke_dynamic) {
2458  prop->output_configured = TRUE;
2459  } else if (!prop->output_configured && res_out == 0) {
2460  /* supposed fixed out-tensor info if getOutputDimension was success. */
2461  g_assert (out_info.num_tensors > 0);
2462 
2464  if (prop->output_meta.num_tensors > 0) {
2465  if (!gst_tensors_info_is_equal (&out_info, &prop->output_meta)) {
2466  gchar *cmpstr =
2467  gst_tensorsinfo_compare_to_string (&out_info, &prop->output_meta);
2468  ml_logw
2469  ("The output tensor is not compatible with the configuration of the model or tensor-filter property. The two tensor meta (GstTensorsInfo) are not compatible: %s\n",
2470  cmpstr);
2471  g_free (cmpstr);
2472  goto done;
2473  }
2474  } else {
2475  gst_tensors_info_copy (&prop->output_meta, &out_info);
2476  }
2477 
2478  prop->output_configured = TRUE;
2479  silent_debug_info (&out_info, "output tensor");
2480  }
2481 
2482 done:
2483  gst_tensors_info_free (&in_info);
2484  gst_tensors_info_free (&out_info);
2485 }
2486 
2490 void
2492 {
2493  int run_without_model = 0;
2494 
2495  if (!priv->prop.fw_opened && priv->fw) {
2496  gint64 start_time, end_time;
2497 
2498  start_time = g_get_monotonic_time ();
2499  if (priv->fw->open) {
2500  /* at least one model should be configured before opening fw */
2501  if (GST_TF_FW_V0 (priv->fw)) {
2502  run_without_model = priv->fw->run_without_model;
2503  } else if (GST_TF_FW_V1 (priv->fw)) {
2504  run_without_model = priv->info.run_without_model;
2505  }
2506 
2507  if (G_UNLIKELY (!run_without_model) &&
2508  G_UNLIKELY (!(priv->prop.model_files &&
2509  priv->prop.num_models > 0 && priv->prop.model_files[0]))) {
2510  return;
2511  }
2512  /* 0 if successfully loaded. 1 if skipped (already loaded). */
2513  if (verify_model_path (priv)) {
2514  if (priv->fw->open (&priv->prop, &priv->privateData) >= 0)
2515  priv->prop.fw_opened = TRUE;
2516  }
2517  } else {
2518  priv->prop.fw_opened = TRUE;
2519  }
2520 
2521  if (priv->prop.fw_opened) {
2522  /* Update the framework info once it has been opened */
2523  if (GST_TF_FW_V1 (priv->fw) &&
2524  priv->fw->getFrameworkInfo (priv->fw, &priv->prop, priv->privateData,
2525  &priv->info) != 0) {
2526  priv->fw->close (&priv->prop, &priv->privateData);
2527  priv->prop.fw_opened = FALSE;
2528  }
2529  }
2530 
2531  end_time = g_get_monotonic_time ();
2532  if (priv->prop.fw_opened == TRUE &&
2533  priv->prop.fwname && priv->prop.model_files) {
2534  ml_logi ("Filter %s with model file %s is opened. It took %"
2535  G_GINT64_FORMAT " us", priv->prop.fwname, priv->prop.model_files[0],
2536  end_time - start_time);
2537  }
2538  }
2539 }
2540 
2544 void
2546 {
2547  if (priv->prop.fw_opened) {
2548  if (priv->fw && priv->fw->close) {
2549  priv->fw->close (&priv->prop, &priv->privateData);
2550  }
2551  priv->prop.fw_opened = FALSE;
2552  priv->privateData = NULL;
2553  }
2554 }
2555 
2559 void
2561 {
2563 
2565  g_free_const (priv->prop.fwname);
2566  priv->prop.fwname = NULL;
2567  priv->fw = NULL;
2568  priv->configured = FALSE;
2569 }
2570 
2576 accl_hw
2577 get_accl_hw_type (const gchar * key)
2578 {
2579  GEnumClass *enum_class;
2580  GEnumValue *enum_value;
2581 
2582  enum_class = g_type_class_ref (accl_hw_get_type ());
2583  enum_value = g_enum_get_value_by_name (enum_class, key);
2584  g_type_class_unref (enum_class);
2585 
2586  if (enum_value == NULL)
2587  return ACCL_NONE;
2588  return enum_value->value;
2589 }
2590 
2597 const gchar *
2599 {
2600  GEnumClass *enum_class;
2601  GEnumValue *enum_value;
2602 
2603  enum_class = g_type_class_ref (accl_hw_get_type ());
2604  enum_value = g_enum_get_value (enum_class, key);
2605  g_type_class_unref (enum_class);
2606 
2607  if (enum_value == NULL)
2608  return ACCL_NONE_STR;
2609  return enum_value->value_name;
2610 }
2611 
2619 static GList *
2620 parse_accl_hw_all (const gchar * accelerators,
2621  const gchar ** supported_accelerators)
2622 {
2623  GRegex *nnapi_elem;
2624  GMatchInfo *match_info;
2625  gboolean use_accl;
2626  accl_hw accl;
2627  gchar *regex_accl = NULL;
2628  gchar *regex_accl_elem = NULL;
2629  GList *match_accl = NULL;
2630 
2631  if (accelerators == NULL) {
2632  match_accl = g_list_append (match_accl, GINT_TO_POINTER (ACCL_DEFAULT));
2633  return match_accl;
2634  }
2635 
2636  /* If set by user, get the precise accelerator */
2637  regex_accl = create_regex (supported_accelerators, regex_accl_utils);
2638  use_accl = (gboolean) g_regex_match_simple (regex_accl, accelerators,
2639  G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY);
2640  g_free (regex_accl);
2641  if (use_accl) {
2643  accl = ACCL_AUTO;
2644  regex_accl_elem =
2645  create_regex (supported_accelerators, regex_accl_elem_utils);
2646  nnapi_elem =
2647  g_regex_new (regex_accl_elem, G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY,
2648  NULL);
2649  g_free (regex_accl_elem);
2650 
2652  if (g_regex_match (nnapi_elem, accelerators, G_REGEX_MATCH_NOTEMPTY,
2653  &match_info)) {
2654 
2655  while (g_match_info_matches (match_info)) {
2656  gchar *word = g_match_info_fetch (match_info, 0);
2657  accl = get_accl_hw_type (word);
2658  if (accl > 0 || (accl == 0 && g_strcmp0 (word, ACCL_NONE_STR) == 0)) {
2659  match_accl = g_list_append (match_accl, GINT_TO_POINTER (accl));
2660  }
2661  g_free (word);
2662  g_match_info_next (match_info, NULL);
2663  }
2664  } else {
2665  ml_logw
2666  ("Using AUTO accelerator config, User provided accelerator(s) do not intersect with framework's supported accelerators.");
2667  }
2668  g_match_info_free (match_info);
2669  g_regex_unref (nnapi_elem);
2670 
2671  if (g_list_length (match_accl) == 0) {
2672  match_accl = g_list_append (match_accl, GINT_TO_POINTER (ACCL_AUTO));
2673  }
2674  } else {
2675  match_accl = g_list_append (match_accl, GINT_TO_POINTER (ACCL_NONE));
2676  }
2677 
2678  return match_accl;
2679 }
2680 
2685 static const gchar **
2686 add_basic_supported_accelerators (const gchar ** supported_accelerators)
2687 {
2688  gint num_hw = 0, idx = 0;
2689  const gchar **accl_support;
2690 
2692  while (supported_accelerators[num_hw] != NULL)
2693  num_hw += 1;
2694  num_hw += 2;
2695 
2697  accl_support = g_try_malloc0 (sizeof (gchar *) * (num_hw + 1));
2698  if (accl_support == NULL) {
2699  ml_loge ("Failed to allocate memory for accelerators");
2700  return NULL;
2701  }
2702 
2704  while (supported_accelerators[idx] != NULL) {
2705  accl_support[idx] = supported_accelerators[idx];
2706  idx += 1;
2707  }
2708  accl_support[idx++] = ACCL_AUTO_STR;
2709  accl_support[idx++] = ACCL_DEFAULT_STR;
2710  accl_support[idx] = NULL;
2711 
2712  return accl_support;
2713 }
2714 
2721 static const gchar **
2722 filter_supported_accelerators (const gchar ** supported_accelerators)
2723 {
2724  gint num_hw = 0, idx = 0;
2725  const gchar **accl_support;
2726  gint neon_available = cpu_neon_accel_available ();
2727 
2729  while (supported_accelerators[num_hw] != NULL) {
2730  num_hw += 1;
2731  }
2732 
2734  accl_support = g_malloc (sizeof (gchar *) * (num_hw + 1));
2735 
2737  idx = 0;
2738  num_hw = 0;
2739  while (supported_accelerators[idx] != NULL) {
2740  if (g_ascii_strncasecmp (supported_accelerators[idx], ACCL_CPU_NEON_STR,
2741  strlen (ACCL_CPU_NEON_STR)) == 0 && neon_available != 0) {
2742  ml_logw ("Neon instructions are not available on this device.");
2743  } else {
2744  accl_support[num_hw] = supported_accelerators[idx];
2745  num_hw += 1;
2746  }
2747  idx += 1;
2748  }
2749  accl_support[num_hw] = NULL;
2750 
2751  return accl_support;
2752 }
2753 
2762 static accl_hw
2763 parse_accl_hw_util (const gchar * accelerators,
2764  const gchar ** supported_accelerators, const gchar * auto_accelerator,
2765  const gchar * default_accelerator)
2766 {
2767  GList *match_accl;
2768  accl_hw hw;
2769  const gchar **all_supported_accelerators;
2770 
2772  all_supported_accelerators =
2773  add_basic_supported_accelerators (supported_accelerators);
2774  if (all_supported_accelerators) {
2775  match_accl = parse_accl_hw_all (accelerators, all_supported_accelerators);
2776  g_free (all_supported_accelerators);
2777  } else {
2778  return ACCL_NONE;
2779  }
2780 
2781  if (NULL == match_accl) {
2782  ml_loge ("There is no match hardware accelerators from {%s}.\n",
2783  accelerators);
2784  return ACCL_NONE;
2785  }
2786 
2787  hw = GPOINTER_TO_INT (match_accl->data);
2788  g_list_free (match_accl);
2789 
2790  if (hw == ACCL_AUTO)
2791  return get_accl_hw_type (auto_accelerator);
2792  else if (hw == ACCL_DEFAULT)
2793  return get_accl_hw_type (default_accelerator);
2794 
2796  return hw;
2797 }
2798 
2803 static gint
2805 {
2806  const gchar **accl_support, **filtered_accl_support;
2807  gint ret = 0;
2808 
2810  accl_support = g_malloc (sizeof (gchar *) * (2));
2811 
2813  accl_support[0] = accl;
2814  accl_support[1] = NULL;
2815 
2816  filtered_accl_support = filter_supported_accelerators (accl_support);
2817  if (!filtered_accl_support || filtered_accl_support[0] == NULL) {
2818  ret = -ENOENT;
2819  } else {
2820  ret = 0;
2821  }
2822 
2823  g_free (filtered_accl_support);
2824  g_free (accl_support);
2825 
2826  return ret;
2827 }
2828 
2832 accl_hw
2834 {
2835  const gchar *in_accl = accl_args.in_accl;
2836  const gchar **sup_accl = accl_args.sup_accl;
2837  const gchar *def_accl, *auto_accl;
2838  const gchar **filtered_accl;
2839  accl_hw ret = ACCL_NONE;
2840 
2841  if (accl_args.sup_accl == NULL || accl_args.sup_accl[0] == NULL)
2842  return ret;
2843 
2845  filtered_accl = filter_supported_accelerators (accl_args.sup_accl);
2846  if (!filtered_accl) {
2847  return ret;
2848  }
2849 
2851  sup_accl = filtered_accl;
2852  if (sup_accl[0] == NULL) {
2853  g_free (filtered_accl);
2854  return ret;
2855  }
2856 
2858  if (accl_args.def_accl &&
2859  runtime_check_supported_accelerator (accl_args.def_accl) == 0) {
2860  def_accl = accl_args.def_accl;
2861  } else {
2862  def_accl = sup_accl[0];
2863  }
2864 
2866  if (accl_args.auto_accl &&
2868  auto_accl = accl_args.auto_accl;
2869  } else {
2870  auto_accl = sup_accl[0];
2871  }
2872 
2873  ret = parse_accl_hw_util (in_accl, sup_accl, auto_accl, def_accl);
2874  g_free (filtered_accl);
2875 
2876  return ret;
2877 }
2878 
2882 static GType
2884 {
2885  static gsize g_accl_hw_type_id_store = 0;
2886 
2887  if (g_once_init_enter (&g_accl_hw_type_id_store)) {
2888  static const GEnumValue values[] = {
2893 #if defined(__aarch64__) || defined(__arm__)
2894 
2896 #endif
2906  {0, NULL, NULL}
2907  };
2908 
2909  GType g_accl_hw_type_id =
2910  g_enum_register_static (g_intern_static_string ("accl_hw"), values);
2911  g_once_init_leave (&g_accl_hw_type_id_store, g_accl_hw_type_id);
2912  }
2913 
2914  return g_accl_hw_type_id_store;
2915 }
2916 
2922 gboolean
2923 gst_tensor_filter_check_hw_availability (const gchar * name, const accl_hw hw,
2924  const char *custom)
2925 {
2926  gint idx = 0;
2927  gboolean available = FALSE;
2930  const GstTensorFilterFramework *fw;
2931 
2932  if (!name) {
2933  nns_logw ("Cannot check hw availability, given framework name is NULL.");
2934  return FALSE;
2935  }
2936  if ((fw = nnstreamer_filter_find (name)) == NULL) {
2937  nns_logw ("Cannot find sub-plugin for %s.", name);
2938  return FALSE;
2939  }
2940 
2941  if (GST_TF_FW_V1 (fw))
2943 
2945  if (hw == ACCL_AUTO || hw == ACCL_DEFAULT) {
2946  available = TRUE;
2947  } else if (GST_TF_FW_V0 (fw)) {
2948  if (fw->checkAvailability && fw->checkAvailability (hw) == 0)
2949  available = TRUE;
2950  } else if (GST_TF_FW_V1 (fw)) {
2951  if (fw->getFrameworkInfo (fw, &prop, NULL, &info) == 0) {
2952  for (idx = 0; idx < info.num_hw; idx++) {
2953  if (info.hw_list[idx] == hw) {
2954  available = TRUE;
2955  break;
2956  }
2957  }
2958  }
2959  }
2960 
2961  /* handle custom option */
2962  if (available && custom) {
2965  int ret = 0;
2966 
2967  edata.hw = hw;
2968  edata.custom = custom;
2969 
2970  if (GST_TF_FW_V0 (fw)) {
2971  if (fw->handleEvent)
2972  ret = fw->handleEvent (evt, &edata);
2973  } else if (GST_TF_FW_V1 (fw)) {
2974  if (fw->eventHandler)
2975  ret = fw->eventHandler (fw, &prop, NULL, evt, &edata);
2976  }
2977 
2978  if (ret != 0 && ret != -ENOENT)
2979  available = FALSE;
2980  }
2981 
2982  return available;
2983 }
2984 
2985 /* extern functions for shared model representation */
2992 void *
2993 nnstreamer_filter_shared_model_get (void *instance, const char *key)
2994 {
2995  GstTensorFilterSharedModelRepresentation *model_rep = NULL;
2996 
2997  G_LOCK (shared_model_table);
2998  if (!shared_model_table) {
2999  ml_loge ("The shared model representation is not supported properly!");
3000  goto done;
3001  }
3002 
3003  model_rep = g_hash_table_lookup (shared_model_table, key);
3004  if (!model_rep) {
3005  ml_logi ("There is no value of the key: %s", key);
3006  goto done;
3007  }
3008  if (!g_list_find (model_rep->referred_list, instance))
3009  model_rep->referred_list =
3010  g_list_append (model_rep->referred_list, instance);
3011 
3012 done:
3013  G_UNLOCK (shared_model_table);
3014  return model_rep ? model_rep->shared_interpreter : NULL;
3015 }
3016 
3017 /* extern functions for shared model representation */
3025 void *
3027  void *interpreter)
3028 {
3030 
3031  /* validate arguments */
3032  if (!instance) {
3033  ml_loge ("The instance should NOT be NULL!");
3034  return NULL;
3035  }
3036  if (!key) {
3037  ml_loge ("The key should NOT be NULL!");
3038  return NULL;
3039  }
3040  if (!interpreter) {
3041  ml_loge ("The interpreter should NOT be NULL!");
3042  return NULL;
3043  }
3044 
3045  G_LOCK (shared_model_table);
3046  if (!shared_model_table) {
3047  ml_loge ("The shared model representation is not supported properly!");
3048  goto done;
3049  }
3050 
3051  if (g_hash_table_lookup (shared_model_table, key)) {
3056  interpreter = NULL;
3057  goto done;
3058  }
3060  g_malloc0 (sizeof (GstTensorFilterSharedModelRepresentation));
3061  model_rep->shared_interpreter = interpreter;
3062  model_rep->referred_list = g_list_append (model_rep->referred_list, instance);
3063  g_hash_table_insert (shared_model_table, g_strdup (key),
3064  (gpointer) model_rep);
3065 
3066 done:
3067  G_UNLOCK (shared_model_table);
3068  return interpreter;
3069 }
3070 
3071 /* extern functions for shared model representation */
3080 int
3081 nnstreamer_filter_shared_model_remove (void *instance, const char *key,
3082  void (*free_callback) (void *))
3083 {
3085  int ret = FALSE;
3086 
3087  /* search the table with key */
3088  G_LOCK (shared_model_table);
3089  if (!shared_model_table) {
3090  ml_loge ("The shared model representation is not supported properly!");
3091  goto done;
3092  }
3093 
3094  model_rep = g_hash_table_lookup (shared_model_table, key);
3095  if (!model_rep) {
3096  ml_loge ("There is no value of the key: %s", key);
3097  goto done;
3098  }
3099 
3100  /* remove instance from the list */
3101  model_rep->referred_list = g_list_remove (model_rep->referred_list, instance);
3102  ml_logd ("The referred instance of sharing key: %s has been removed!", key);
3103  ret = TRUE;
3104 
3105  /* remove key from table if list is empty */
3106  if (g_list_length (model_rep->referred_list) == 0) {
3107  if (free_callback)
3108  free_callback (model_rep->shared_interpreter);
3109  g_hash_table_remove (shared_model_table, key);
3110  }
3111 
3112 done:
3113  G_UNLOCK (shared_model_table);
3114  return ret;
3115 }
3116 
3117 /* extern functions for shared model representation */
3127 void
3128 nnstreamer_filter_shared_model_replace (void *instance, const char *key,
3129  void *new_interpreter, void (*replace_callback) (void *, void *),
3130  void (*free_callback) (void *))
3131 {
3133  GList *itr;
3134  UNUSED (instance);
3135 
3136  if (!key) {
3137  ml_loge ("The key should NOT be NULL!");
3138  return;
3139  }
3140 
3141  G_LOCK (shared_model_table);
3142  if (!shared_model_table) {
3143  ml_loge ("The shared model representation is not supported properly!");
3144  goto done;
3145  }
3146 
3147  model_rep = g_hash_table_lookup (shared_model_table, key);
3148  if (model_rep) {
3149  itr = model_rep->referred_list;
3150  while (itr) {
3151  replace_callback (itr->data, new_interpreter);
3152  itr = itr->next;
3153  }
3154 
3155  free_callback (model_rep->shared_interpreter);
3156  model_rep->shared_interpreter = new_interpreter;
3157  }
3158 
3159 done:
3160  G_UNLOCK (shared_model_table);
3161 }
REGEX_ACCL_ELEM_START
#define REGEX_ACCL_ELEM_START
Definition: tensor_filter_common.c:54
accl_hw
accl_hw
acceleration hw properties.
Definition: nnstreamer_plugin_api_filter.h:80
_GstTensorFilterFramework::run_without_model
int run_without_model
Definition: nnstreamer_plugin_api_filter.h:287
_GstTensorFilterPrivate::silent
gboolean silent
Definition: tensor_filter_common.h:161
nnstreamer_filter_probe
int nnstreamer_filter_probe(GstTensorFilterFramework *tfsp)
Filter's sub-plugin should call this function to register itself.
Definition: tensor_filter_common.c:611
gst_tensor_filter_get_type_string
static gchar * gst_tensor_filter_get_type_string(const GstTensorFilterProperties *prop, const gboolean is_input)
Get the type string of tensors.
Definition: tensor_filter_common.c:304
_GstTensorFilterFramework::invoke
int(* invoke)(const GstTensorFilterFramework *self, GstTensorFilterProperties *prop, void *private_data, const GstTensorMemory *input, GstTensorMemory *output)
Definition: nnstreamer_plugin_api_filter.h:395
_GstTensorFilterStatistics::latest_invoke_time
gint64 latest_invoke_time
Definition: tensor_filter_common.h:123
_GstTensorFilterFramework::invoke_NN
int(* invoke_NN)(const GstTensorFilterProperties *prop, void **private_data, const GstTensorMemory *input, GstTensorMemory *output)
Definition: nnstreamer_plugin_api_filter.h:292
ACCL_AUTO_STR
#define ACCL_AUTO_STR
Definition: nnstreamer_plugin_api_filter.h:22
_GstTensorFilterFramework::getOutputDimension
int(* getOutputDimension)(const GstTensorFilterProperties *prop, void **private_data, GstTensorsInfo *info)
Definition: nnstreamer_plugin_api_filter.h:315
GstTensorFilterSharedModelRepresentation
Data Structure to store shared table.
Definition: tensor_filter_common.h:144
g_assert
g_assert(sizeof(DTYPE_UNSIGNED)==sizeof(DTYPE_SIGNED))
_GstTensorFilterFramework::open
int(* open)(const GstTensorFilterProperties *prop, void **private_data)
Definition: nnstreamer_plugin_api_filter.h:257
NNS_SUBPLUGIN_FILTER
@ NNS_SUBPLUGIN_FILTER
Definition: nnstreamer_subplugin.h:41
gst_tensor_filter_parse_modelpaths_string
static void gst_tensor_filter_parse_modelpaths_string(GstTensorFilterProperties *prop, const gchar *model_files)
Parse the string of model.
Definition: tensor_filter_common.c:728
gst_tensor_get_type_string
const gchar * gst_tensor_get_type_string(tensor_type type)
Get type string of tensor type.
Definition: nnstreamer_plugin_api_util_impl.c:1296
PROP_IS_UPDATABLE
@ PROP_IS_UPDATABLE
Definition: tensor_filter_common.h:102
_NNS_LAYOUT_ANY
@ _NNS_LAYOUT_ANY
Definition: tensor_typedef.h:222
REGEX_ACCL_DELIMITER
#define REGEX_ACCL_DELIMITER
Definition: tensor_filter_common.c:63
data
svtc_1 data
Definition: gsttensor_if.c:844
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
gst_tensors_layout_init
static void gst_tensors_layout_init(tensors_layout layout)
Initialize the tensors layout.
Definition: tensor_filter_common.c:108
ml_logw
#define ml_logw
Definition: nnstreamer_log.h:77
gst_tensor_filter_common_open_fw
void gst_tensor_filter_common_open_fw(GstTensorFilterPrivate *priv)
Open NN framework.
Definition: tensor_filter_common.c:2491
G_LOCK_DEFINE_STATIC
G_LOCK_DEFINE_STATIC(shared_model_table)
mutex for shared model table.
_gtfc_setprop_SHARED_TENSOR_FILTER_KEY
static gint _gtfc_setprop_SHARED_TENSOR_FILTER_KEY(GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_SHARED_TENSOR_FILTER_KEY" for set-property.
Definition: tensor_filter_common.c:1917
NNS_TENSOR_SIZE_LIMIT
#define NNS_TENSOR_SIZE_LIMIT
The number of tensors NNStreamer supports is 256. The max memories of gst-buffer is 16 (See NNS_TENSO...
Definition: tensor_typedef.h:42
ACCL_GPU
@ ACCL_GPU
Definition: nnstreamer_plugin_api_filter.h:93
_gtfc_setprop_NAME
static gint _gtfc_setprop_NAME(GstTensorFilterPrivate *priv, const GValue *value, const gboolean is_input)
Handle "PROP_INPUTNAME" and "PROP_OUTPUTNAME" for set-property.
Definition: tensor_filter_common.c:1588
_gtfc_setprop_FRAMEWORK
static gint _gtfc_setprop_FRAMEWORK(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_FRAMEWORK" for set-property.
Definition: tensor_filter_common.c:1381
_GstTensorFilterPrivate::out_config
GstTensorsConfig out_config
Definition: tensor_filter_common.h:166
PROP_INPUTNAME
@ PROP_INPUTNAME
Definition: tensor_filter_common.h:91
gst_tensor_get_rank_dimension_string
gchar * gst_tensor_get_rank_dimension_string(const tensor_dim dim, const unsigned int rank)
Get dimension string from given tensor dimension and rank count.
Definition: nnstreamer_plugin_api_util_impl.c:1107
gst_tensor_filter_common_unload_fw
void gst_tensor_filter_common_unload_fw(GstTensorFilterPrivate *priv)
Unload NN framework.
Definition: tensor_filter_common.c:2545
FALSE
return FALSE
Definition: gsttensor_transform.c:590
gst_tensors_info_parse_names_string
guint gst_tensors_info_parse_names_string(GstTensorsInfo *info, const gchar *name_string)
Parse the string of names.
Definition: nnstreamer_plugin_api_util_impl.c:612
result
case tensor_data_s gboolean * result
Definition: gsttensor_if.c:839
_GstTensorFilterFramework::destroyNotify
void(* destroyNotify)(void **private_data, void *data)
Definition: nnstreamer_plugin_api_filter.h:346
PROP_OUTPUT
@ PROP_OUTPUT
Definition: gsttensor_debug.c:83
accl_hw_get_type
static GType accl_hw_get_type(void)
to get and register hardware accelerator backend enum
Definition: tensor_filter_common.c:2883
_GstTensorFilterPrivate::throughput_mode
gint throughput_mode
Definition: tensor_filter_common.h:169
_GstTensorFilterFrameworkEventData::data
void * data
Definition: nnstreamer_plugin_api_filter.h:206
_GstTensorFilterPrivate::latency_reporting
gboolean latency_reporting
Definition: tensor_filter_common.h:170
_GstTensorFilterFramework::getInputDimension
int(* getInputDimension)(const GstTensorFilterProperties *prop, void **private_data, GstTensorsInfo *info)
Definition: nnstreamer_plugin_api_filter.h:303
_GstTensorFilterFrameworkInfo::allocate_in_invoke
int allocate_in_invoke
Definition: nnstreamer_plugin_api_filter.h:162
gst_tensor_filter_common_set_property
gboolean gst_tensor_filter_common_set_property(GstTensorFilterPrivate *priv, guint prop_id, const GValue *value, GParamSpec *pspec)
Set the properties for tensor_filter.
Definition: tensor_filter_common.c:1967
GST_TF_FW_V0
#define GST_TF_FW_V0(fw)
Definition: tensor_filter_common.h:47
GstTensorsInfo
Internal meta data exchange format for a other/tensors instance.
Definition: tensor_typedef.h:273
ACCL_CPU_NEON_STR
#define ACCL_CPU_NEON_STR
Definition: nnstreamer_plugin_api_filter.h:25
mlagent_get_model_path_from
gchar * mlagent_get_model_path_from(const GValue *val)
Get a path of the model file from a given GValue.
Definition: ml_agent.c:33
parse_accl_args::sup_accl
const char ** sup_accl
Definition: nnstreamer_plugin_api_filter.h:525
_GstTensorFilterFrameworkInfo::accl_auto
accl_hw accl_auto
Definition: nnstreamer_plugin_api_filter.h:167
SET_ACCELERATOR
@ SET_ACCELERATOR
Definition: nnstreamer_plugin_api_filter.h:184
nns_logd
#define nns_logd
Definition: nnstreamer_log.h:143
gst_tensor_filter_common_get_combined_out_info
gboolean gst_tensor_filter_common_get_combined_out_info(GstTensorFilterPrivate *priv, const GstTensorsInfo *in, const GstTensorsInfo *out, GstTensorsInfo *combined)
Configure output tensor info with combi option.
Definition: tensor_filter_common.c:2315
prop
GstTensorSrcIIOChannelProperties * prop
DTYPE_UNSIGNED ( .
Definition: gsttensor_srciio.c:110
GstTensorFilterSharedModelRepresentation::shared_interpreter
void * shared_interpreter
Definition: tensor_filter_common.h:145
_GstTensorFilterPrivate::stat
GstTensorFilterStatistics stat
Definition: tensor_filter_common.h:157
_GstTensorFilterProperties::fw_opened
int fw_opened
Definition: nnstreamer_plugin_api_filter.h:115
gst_tensors_info_validate
gboolean gst_tensors_info_validate(const GstTensorsInfo *info)
Check the tensors info is valid.
Definition: nnstreamer_plugin_api_util_impl.c:404
PROP_INPUTLAYOUT
@ PROP_INPUTLAYOUT
Definition: tensor_filter_common.h:92
subplugin_set_custom_property_desc
void subplugin_set_custom_property_desc(subpluginType type, const char *name, const gchar *prop, va_list varargs)
common interface to set custom property description of a sub-plugin.
Definition: nnstreamer_subplugin.c:329
_GstTensorFilterProperties::output_configured
int output_configured
Definition: nnstreamer_plugin_api_filter.h:124
ACCL_NPU_MOVIDIUS
@ ACCL_NPU_MOVIDIUS
Definition: nnstreamer_plugin_api_filter.h:96
ACCL_DEFAULT_STR
#define ACCL_DEFAULT_STR
Definition: nnstreamer_plugin_api_filter.h:21
gst_tensor_info_copy
void gst_tensor_info_copy(GstTensorInfo *dest, const GstTensorInfo *src)
Copy tensor info.
Definition: nnstreamer_plugin_api_util_impl.c:248
nnstreamer_log.h
Internal log util for NNStreamer plugins and native APIs.
PROP_CUSTOM
@ PROP_CUSTOM
Definition: tensor_filter_common.h:99
subplugins
static GHashTable * subplugins[NNS_SUBPLUGIN_END]
Definition: nnstreamer_subplugin.c:47
ACCL_NONE
@ ACCL_NONE
Definition: nnstreamer_plugin_api_filter.h:83
_GstTensorFilterPrivate::config_path
gchar * config_path
Definition: tensor_filter_common.h:164
SET_INPUT_PROP
@ SET_INPUT_PROP
Definition: nnstreamer_plugin_api_filter.h:182
gst_tensors_info_init
void gst_tensors_info_init(GstTensorsInfo *info)
Initialize the tensors info structure.
Definition: nnstreamer_plugin_api_util_impl.c:325
shared_model_table
static GHashTable * shared_model_table
Definition: tensor_filter_common.c:102
_GstTensorFilterProperties::suspend
uint32_t suspend
Definition: nnstreamer_plugin_api_filter.h:139
ACCL_NPU_VIVANTE_STR
#define ACCL_NPU_VIVANTE_STR
Definition: nnstreamer_plugin_api_filter.h:31
PROP_OUTPUTLAYOUT
@ PROP_OUTPUTLAYOUT
Definition: tensor_filter_common.h:97
CUSTOM_PROP
@ CUSTOM_PROP
Definition: nnstreamer_plugin_api_filter.h:181
gst_tensors_parse_layouts_string
static guint gst_tensors_parse_layouts_string(tensors_layout layout, const gchar *layout_string)
Parse the string of tensor layouts.
Definition: tensor_filter_common.c:173
PROP_LATENCY
@ PROP_LATENCY
Definition: tensor_filter_common.h:103
nnstreamer_filter_validate
static gboolean nnstreamer_filter_validate(const GstTensorFilterFramework *tfsp)
Validate filter sub-plugin's data.
Definition: tensor_filter_common.c:560
_GstTensorFilterFramework
Tensor_Filter Subplugin definition.
Definition: nnstreamer_plugin_api_filter.h:249
gst_tensors_info_free
void gst_tensors_info_free(GstTensorsInfo *info)
Free allocated data in tensors info structure.
Definition: nnstreamer_plugin_api_util_impl.c:347
_GstTensorFilterPrivate::in_config
GstTensorsConfig in_config
Definition: tensor_filter_common.h:165
gst_tensor_filter_get_rank_string
static gchar * gst_tensor_filter_get_rank_string(const GstTensorFilterProperties *prop, gboolean isInput)
Get the rank string of the tensors.
Definition: tensor_filter_common.c:211
filter_supported_accelerators
static const gchar ** filter_supported_accelerators(const gchar **supported_accelerators)
Filter accelerators based on the runtime system.
Definition: tensor_filter_common.c:2722
_gtfc_setprop_OUTPUTCOMBINATION
static gint _gtfc_setprop_OUTPUTCOMBINATION(GstTensorFilterPrivate *priv, GList **prop_list1, GList **prop_list2, const GValue *value)
Handle "PROP_OUTPUTCOMBINATION" for set-property.
Definition: tensor_filter_common.c:1874
gst_tensor_get_layout_string
static const gchar * gst_tensor_get_layout_string(tensor_layout layout)
Get layout string of tensor layout.
Definition: tensor_filter_common.c:349
tensors_layout
tensor_layout tensors_layout[NNS_TENSOR_SIZE_LIMIT]
Definition: nnstreamer_plugin_api_filter.h:104
gst_tensor_parse_dimension
guint gst_tensor_parse_dimension(const gchar *dimstr, tensor_dim dim)
Parse tensor dimension parameter string.
Definition: nnstreamer_plugin_api_util_impl.c:1040
_GstTensorFilterStatistics::latency_ignore_count
guint latency_ignore_count
Definition: tensor_filter_common.h:125
ACCL_NPU_VIVANTE
@ ACCL_NPU_VIVANTE
Definition: nnstreamer_plugin_api_filter.h:98
_gtfc_setprop_CUSTOM
static gint _gtfc_setprop_CUSTOM(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_CUSTOM" for set-property.
Definition: tensor_filter_common.c:1627
gst_tensor_filter_property_to_string
static void gst_tensor_filter_property_to_string(GValue *value, GstTensorFilterPrivate *priv, guint prop_id)
Convert GList to GValue.
Definition: tensor_filter_common.c:2063
regex_accl_elem_utils
static const gchar * regex_accl_elem_utils[]
Definition: tensor_filter_common.c:75
get_accl_hw_str
const gchar * get_accl_hw_str(const accl_hw key)
return string based on accl_hw type
Definition: tensor_filter_common.c:2598
gst_tensors_info_get_types_string
gchar * gst_tensors_info_get_types_string(const GstTensorsInfo *info)
Get the string of types in tensors info.
Definition: nnstreamer_plugin_api_util_impl.c:714
nns_logi
#define nns_logi
Definition: nnstreamer_log.h:140
gst_tensor_filter_get_name_string
static gchar * gst_tensor_filter_get_name_string(const GstTensorFilterProperties *prop, const gboolean is_input)
Get the name string of tensors.
Definition: tensor_filter_common.c:327
_gtfc_setprop_LAYOUT
static gint _gtfc_setprop_LAYOUT(GstTensorFilterPrivate *priv, const GValue *value, const gboolean is_input)
Handle "PROP_INPUTLAYOUT" and "PROP_OUTPUTLAYOUT" for set-property.
Definition: tensor_filter_common.c:1732
_gtfc_setprop_THROUGHPUT
static gint _gtfc_setprop_THROUGHPUT(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_THROUGHPUT" for set-property.
Definition: tensor_filter_common.c:1821
_GstTensorFilterStatistics::recent_latencies
void * recent_latencies
Definition: tensor_filter_common.h:124
nnstreamer_filter_shared_model_get
void * nnstreamer_filter_shared_model_get(void *instance, const char *key)
Get the shared model representation that is already shared and has the same key.
Definition: tensor_filter_common.c:2993
ACCL_NPU_STR
#define ACCL_NPU_STR
Definition: nnstreamer_plugin_api_filter.h:28
REGEX_ACCL_START
#define REGEX_ACCL_START
Definition: tensor_filter_common.c:60
_GstTensorFilterFramework::eventHandler
int(* eventHandler)(const GstTensorFilterFramework *self, const GstTensorFilterProperties *prop, void *private_data, event_ops ops, GstTensorFilterFrameworkEventData *data)
Definition: nnstreamer_plugin_api_filter.h:445
SET_OUTPUT_PROP
@ SET_OUTPUT_PROP
Definition: nnstreamer_plugin_api_filter.h:183
PROP_SUSPEND
@ PROP_SUSPEND
Definition: tensor_filter_common.h:111
PROP_INPUT
@ PROP_INPUT
Definition: tensor_filter_common.h:89
g_free
g_free(self->option[(opnum) - 1])
opnum: \
_gtfc_setprop_MODEL
static gint _gtfc_setprop_MODEL(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_MODEL" for set-property.
Definition: tensor_filter_common.c:1428
_GstTensorFilterProperties::model_files
const char ** model_files
Definition: nnstreamer_plugin_api_filter.h:116
nnstreamer_filter_set_custom_property_desc
void nnstreamer_filter_set_custom_property_desc(const char *name, const char *prop,...)
set custom property description for tensor filter sub-plugin
Definition: tensor_filter_common.c:647
_GstTensorFilterStatistics::old_total_invoke_num
gint64 old_total_invoke_num
Definition: tensor_filter_common.h:121
ACCL_CPU
@ ACCL_CPU
Definition: nnstreamer_plugin_api_filter.h:90
gst_tensor_filter_common_free_property
void gst_tensor_filter_common_free_property(GstTensorFilterPrivate *priv)
Free the properties for tensor-filter.
Definition: tensor_filter_common.c:1065
g_value_set_string
g_value_set_string(value, self->option[opnum - 1])
opnum: \
_gtfc_setprop_IS_UPDATABLE
static gint _gtfc_setprop_IS_UPDATABLE(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_IS_UPDATABLE" for set-property.
Definition: tensor_filter_common.c:1710
parse_accl_hw_util
static accl_hw parse_accl_hw_util(const gchar *accelerators, const gchar **supported_accelerators, const gchar *auto_accelerator, const gchar *default_accelerator)
parse user given string to extract accelerator based on given regex
Definition: tensor_filter_common.c:2763
nnstreamer_filter_shared_model_remove
int nnstreamer_filter_shared_model_remove(void *instance, const char *key, void(*free_callback)(void *))
Remove the instance registered at the referred list of shared model table. If referred list is empty,...
Definition: tensor_filter_common.c:3081
gst_tensor_filter_v1_call
#define gst_tensor_filter_v1_call(priv, ret, funcname,...)
Definition: tensor_filter_common.h:61
REGEX_ACCL_ELEM_END
#define REGEX_ACCL_ELEM_END
Definition: tensor_filter_common.c:58
_gtfc_setprop_SUSPEND
static gint _gtfc_setprop_SUSPEND(GstTensorFilterPrivate *priv, const GValue *value)
Handle "PROP_SUSPEND" for set-property.
Definition: tensor_filter_common.c:1950
ACCL_NPU_SRCN_STR
#define ACCL_NPU_SRCN_STR
Definition: nnstreamer_plugin_api_filter.h:32
DESTROY_NOTIFY
@ DESTROY_NOTIFY
Definition: nnstreamer_plugin_api_filter.h:179
create_regex
static gchar * create_regex(const gchar **enum_list, const gchar **regex_utils)
create regex for the given string list and regex basic elements
Definition: tensor_filter_common.c:431
_gtfc_setprop_TYPE
static gint _gtfc_setprop_TYPE(GstTensorFilterPrivate *priv, const GValue *value, const gboolean is_input)
Handle "PROP_INPUTTYPE" and "PROP_OUTPUTTYPE" for set-property.
Definition: tensor_filter_common.c:1549
ACCL_NPU_SLSI_STR
#define ACCL_NPU_SLSI_STR
Definition: nnstreamer_plugin_api_filter.h:33
gst_tensor_filter_framework_info_init
static void gst_tensor_filter_framework_info_init(GstTensorFilterFrameworkInfo *info)
Initialize the GstTensorFilterFrameworkInfo object.
Definition: tensor_filter_common.c:528
ACCL_GPU_STR
#define ACCL_GPU_STR
Definition: nnstreamer_plugin_api_filter.h:26
nnstreamer_filter_find
const GstTensorFilterFramework * nnstreamer_filter_find(const char *name)
Find filter sub-plugin with the name.
Definition: tensor_filter_common.c:697
PROP_OUTPUTCOMBINATION
@ PROP_OUTPUTCOMBINATION
Definition: tensor_filter_common.h:106
PROP_FRAMEWORK
@ PROP_FRAMEWORK
Definition: gsttensor_trainer.c:100
gst_tensor_filter_get_available_framework
static void gst_tensor_filter_get_available_framework(GstTensorFilterPrivate *priv, const char *fw_name)
automatically selecting framework for tensor filter
Definition: tensor_filter_common.c:1317
_GstTensorFilterCombination::out_combi_i_defined
gboolean out_combi_i_defined
Definition: tensor_filter_common.h:137
gst_tensor_filter_common_get_out_info
gboolean gst_tensor_filter_common_get_out_info(GstTensorFilterPrivate *priv, GstTensorsInfo *in, GstTensorsInfo *out)
Get output tensor info from NN model with given input info.
Definition: tensor_filter_common.c:2374
event_ops
event_ops
Tensor_Filter Subplugin related events.
Definition: nnstreamer_plugin_api_filter.h:177
_NNS_LAYOUT_NCHW
@ _NNS_LAYOUT_NCHW
Definition: tensor_typedef.h:224
_gtfc_setprop_INPUTCOMBINATION
static gint _gtfc_setprop_INPUTCOMBINATION(GstTensorFilterPrivate *priv, GList **prop_list, const GValue *value)
Handle "PROP_INPUTCOMBINATION" for set-property.
Definition: tensor_filter_common.c:1843
PROP_MODEL
@ PROP_MODEL
Definition: tensor_filter_common.h:88
_GstTensorFilterFramework::name
char * name
Definition: nnstreamer_plugin_api_filter.h:284
PROP_INPUTTYPE
@ PROP_INPUTTYPE
Definition: tensor_filter_common.h:90
parse_accl_args::def_accl
const char * def_accl
Definition: nnstreamer_plugin_api_filter.h:527
PROP_OUTPUTRANKS
@ PROP_OUTPUTRANKS
Definition: tensor_filter_common.h:98
parse_accl_args
Accelerator related arguments for parsing.
Definition: nnstreamer_plugin_api_filter.h:523
GET_IN_OUT_INFO
@ GET_IN_OUT_INFO
Definition: nnstreamer_plugin_api_filter.h:193
_GstTensorFilterCombination::out_combi_i
GList * out_combi_i
Definition: tensor_filter_common.h:134
CHECK_HW_AVAILABILITY
@ CHECK_HW_AVAILABILITY
Definition: nnstreamer_plugin_api_filter.h:185
regex_accl_utils
static const gchar * regex_accl_utils[]
Definition: tensor_filter_common.c:66
add_basic_supported_accelerators
static const gchar ** add_basic_supported_accelerators(const gchar **supported_accelerators)
Added basic accelerators (auto, default) to supported accelerators.
Definition: tensor_filter_common.c:2686
PROP_SHARED_TENSOR_FILTER_KEY
@ PROP_SHARED_TENSOR_FILTER_KEY
Definition: tensor_filter_common.h:107
gst_tensors_config_free
void gst_tensors_config_free(GstTensorsConfig *config)
Free allocated data in tensors config structure.
Definition: nnstreamer_plugin_api_util_impl.c:845
register_subplugin
gboolean register_subplugin(subpluginType type, const char *name, const void *data)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:225
PROP_OUTPUTNAME
@ PROP_OUTPUTNAME
Definition: tensor_filter_common.h:96
PROP_LATENCY_REPORT
@ PROP_LATENCY_REPORT
Definition: tensor_filter_common.h:108
_GstTensorFilterFramework::checkAvailability
int(* checkAvailability)(accl_hw hw)
Definition: nnstreamer_plugin_api_filter.h:371
_gtfc_setprop_ACCELERATOR
static gint _gtfc_setprop_ACCELERATOR(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_ACCELERATOR" for set-property.
Definition: tensor_filter_common.c:1658
tensor_layout
enum _nns_tensor_layout tensor_layout
Tensor layout format for other/tensor.
_GstTensorFilterFrameworkInfo::statistics
const GstTensorFilterFrameworkStatistics * statistics
Definition: nnstreamer_plugin_api_filter.h:169
gst_tensors_rank_init
static void gst_tensors_rank_init(unsigned int ranks[])
Initialize the tensors ranks.
Definition: tensor_filter_common.c:121
nnstreamer_filter_find_best_fit
static const GstTensorFilterFramework * nnstreamer_filter_find_best_fit(const char *names)
Find sub-plugin filter given the name list.
Definition: tensor_filter_common.c:664
_GstTensorFilterStatistics::old_total_invoke_latency
gint64 old_total_invoke_latency
Definition: tensor_filter_common.h:122
_GstTensorFilterFrameworkInfo
Tensor_Filter Subplugin framework related information.
Definition: nnstreamer_plugin_api_filter.h:158
parse_accl_args::auto_accl
const char * auto_accl
Definition: nnstreamer_plugin_api_filter.h:526
_GstTensorFilterPrivate::info
GstTensorFilterFrameworkInfo info
Definition: tensor_filter_common.h:156
gst_tensor_filter_destroy_notify_util
void gst_tensor_filter_destroy_notify_util(GstTensorFilterPrivate *priv, void *data)
Free the data allocated for tensor filter output.
Definition: tensor_filter_common.c:786
silent_debug_info
#define silent_debug_info(i, msg)
Definition: tensor_filter_common.c:35
PROP_INPUTRANKS
@ PROP_INPUTRANKS
Definition: tensor_filter_common.h:93
gst_tensor_filter_install_properties
void gst_tensor_filter_install_properties(GObjectClass *gobject_class)
Installs all the properties for tensor_filter.
Definition: tensor_filter_common.c:888
gst_tensor_get_dimension_string
gchar * gst_tensor_get_dimension_string(const tensor_dim dim)
Get dimension string from given tensor dimension.
Definition: nnstreamer_plugin_api_util_impl.c:1083
RELOAD_MODEL
@ RELOAD_MODEL
Definition: nnstreamer_plugin_api_filter.h:180
gst_tensor_filter_properties_init
static void gst_tensor_filter_properties_init(GstTensorFilterProperties *prop)
Initialize the GstTensorFilterProperties object.
Definition: tensor_filter_common.c:510
ml_logi
#define ml_logi
Definition: nnstreamer_log.h:76
verify_model_path
static gboolean verify_model_path(const GstTensorFilterPrivate *priv)
Verify validity of path for given model file if verify_model_path is set.
Definition: tensor_filter_common.c:473
PROP_INVOKE_DYNAMIC
@ PROP_INVOKE_DYNAMIC
Definition: tensor_filter_common.h:109
get_all_subplugins
gchar ** get_all_subplugins(subpluginType type)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:176
ACCL_NPU_SR_STR
#define ACCL_NPU_SR_STR
Definition: nnstreamer_plugin_api_filter.h:34
ml_loge
#define ml_loge
Definition: nnstreamer_log.h:78
_GstTensorFilterProperties::num_models
int num_models
Definition: nnstreamer_plugin_api_filter.h:117
ACCL_NPU_MOVIDIUS_STR
#define ACCL_NPU_MOVIDIUS_STR
Definition: nnstreamer_plugin_api_filter.h:29
gst_tensorsinfo_compare_to_string
gchar * gst_tensorsinfo_compare_to_string(const GstTensorsInfo *info1, const GstTensorsInfo *info2)
Printout the comparison results of two tensors as a string.
Definition: tensor_filter_common.c:811
_GstTensorFilterFrameworkEventData
User data for the tensor_tilter subplugin related events.
Definition: nnstreamer_plugin_api_filter.h:200
ACCL_CPU_SIMD_STR
#define ACCL_CPU_SIMD_STR
Definition: nnstreamer_plugin_api_filter.h:24
REGEX_ACCL_ELEM_DELIMITER
#define REGEX_ACCL_ELEM_DELIMITER
Definition: tensor_filter_common.c:57
TRUE
return TRUE
Definition: gsttensor_if.c:897
_GstTensorFilterFramework::allocate_in_invoke
int allocate_in_invoke
Definition: nnstreamer_plugin_api_filter.h:286
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
_GstTensorFilterPrivate
Structure definition for common tensor-filter properties.
Definition: tensor_filter_common.h:152
nns_loge
#define nns_loge
Definition: nnstreamer_log.h:142
gst_tensor_filter_common_get_combined_in_info
gboolean gst_tensor_filter_common_get_combined_in_info(GstTensorFilterPrivate *priv, const GstTensorsInfo *in, GstTensorsInfo *combined)
Configure input tensor info with combi option.
Definition: tensor_filter_common.c:2270
ACCL_NPU_EDGE_TPU_STR
#define ACCL_NPU_EDGE_TPU_STR
Definition: nnstreamer_plugin_api_filter.h:30
g_free_const
#define g_free_const(x)
Free memory.
Definition: tensor_filter_common.c:87
cpu_neon_accel_available
gint cpu_neon_accel_available(void)
Check if neon is supported.
Definition: hw_accel.c:41
_GstTensorFilterProperties::input_configured
int input_configured
Definition: nnstreamer_plugin_api_filter.h:119
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
ACCL_NPU
@ ACCL_NPU
Definition: nnstreamer_plugin_api_filter.h:95
_GstTensorFilterFrameworkInfo::accl_default
accl_hw accl_default
Definition: nnstreamer_plugin_api_filter.h:168
_GstTensorFilterFrameworkInfo::hw_list
const accl_hw * hw_list
Definition: nnstreamer_plugin_api_filter.h:165
_GstTensorFilterCombination::in_combi
GList * in_combi
Definition: tensor_filter_common.h:133
_GstTensorFilterPrivate::fw
const GstTensorFilterFramework * fw
Definition: tensor_filter_common.h:158
parse_accl_args::in_accl
const char * in_accl
Definition: nnstreamer_plugin_api_filter.h:524
_GstTensorFilterFrameworkInfo::num_hw
int num_hw
Definition: nnstreamer_plugin_api_filter.h:166
_GstTensorFilterFramework::reloadModel
int(* reloadModel)(const GstTensorFilterProperties *prop, void **private_data)
Definition: nnstreamer_plugin_api_filter.h:353
_GstTensorFilterProperties::fwname
const char * fwname
Definition: nnstreamer_plugin_api_filter.h:114
_detect_framework_from_config
static gchar * _detect_framework_from_config(const gchar *extension)
Get available framework from config.
Definition: tensor_filter_common.c:1185
_GstTensorFilterProperties
GstTensorFilter's properties for NN framework (internal data structure)
Definition: nnstreamer_plugin_api_filter.h:112
nnstreamer_filter_exit
void nnstreamer_filter_exit(const char *name)
Filter's sub-plugin may call this to unregister itself.
Definition: tensor_filter_common.c:638
_GstTensorFilterPrivate::is_updatable
gboolean is_updatable
Definition: tensor_filter_common.h:163
_GstTensorFilterCombination::in_combi_defined
gboolean in_combi_defined
Definition: tensor_filter_common.h:136
nnstreamer_filter_shared_model_insert_and_get
void * nnstreamer_filter_shared_model_insert_and_get(void *instance, char *key, void *interpreter)
Insert the new shared model representation and get the value.
Definition: tensor_filter_common.c:3026
runtime_check_supported_accelerator
static gint runtime_check_supported_accelerator(const gchar *accl)
Check if this accelerator can be used based on the runtime system.
Definition: tensor_filter_common.c:2804
ACCL_NPU_SRCN
@ ACCL_NPU_SRCN
Definition: nnstreamer_plugin_api_filter.h:99
_GstTensorFilterStatistics::total_invoke_latency
gint64 total_invoke_latency
Definition: tensor_filter_common.h:120
gst_tensors_info_get_nth_info
GstTensorInfo * gst_tensors_info_get_nth_info(GstTensorsInfo *info, guint index)
Get the pointer of nth tensor information.
Definition: nnstreamer_plugin_api_util_impl.c:296
ACCL_AUTO
@ ACCL_AUTO
Definition: nnstreamer_plugin_api_filter.h:86
gst_tensor_filter_get_layout_string
static gchar * gst_tensor_filter_get_layout_string(const GstTensorFilterProperties *prop, const gboolean is_input)
Get the string of layout of tensors.
Definition: tensor_filter_common.c:372
_GstTensorFilterFrameworkInfo::run_without_model
int run_without_model
Definition: nnstreamer_plugin_api_filter.h:163
_gtfc_setprop_PROP_INVOKE_DYNAMIC
static gint _gtfc_setprop_PROP_INVOKE_DYNAMIC(GstTensorFilterPrivate *priv, const GValue *value)
Handle "PROP_INVOKE_DYNAMIC" for set-property.
Definition: tensor_filter_common.c:1937
gst_tensor_filter_statistics_init
static void gst_tensor_filter_statistics_init(GstTensorFilterStatistics *stat)
Initialize the GstTensorFilterFrameworkInfo object.
Definition: tensor_filter_common.c:545
_GstTensorFilterStatistics
Structure definition for tensor-filter statistics.
Definition: tensor_filter_common.h:117
_GstTensorFilterFramework::setInputDimension
int(* setInputDimension)(const GstTensorFilterProperties *prop, void **private_data, const GstTensorsInfo *in_info, GstTensorsInfo *out_info)
Definition: nnstreamer_plugin_api_filter.h:327
_GstTensorFilterFramework::getModelInfo
int(* getModelInfo)(const GstTensorFilterFramework *self, const GstTensorFilterProperties *prop, void *private_data, model_info_ops ops, GstTensorsInfo *in_info, GstTensorsInfo *out_info)
Definition: nnstreamer_plugin_api_filter.h:420
_GstTensorFilterPrivate::configured
gboolean configured
Definition: tensor_filter_common.h:162
_GstTensorFilterProperties::num_hw
int num_hw
Definition: nnstreamer_plugin_api_filter.h:131
hw_accel.h
Common hardware acceleration availability header.
REGEX_ACCL_SUFFIX
#define REGEX_ACCL_SUFFIX
Definition: tensor_filter_common.c:62
PROP_CONFIG
@ PROP_CONFIG
Definition: gsttensor_decoder.c:78
REGEX_ACCL_ELEM_SUFFIX
#define REGEX_ACCL_ELEM_SUFFIX
Definition: tensor_filter_common.c:56
_GstTensorFilterCombination::out_combi_o
GList * out_combi_o
Definition: tensor_filter_common.h:135
gst_tensor_parse_layout_string
static tensor_layout gst_tensor_parse_layout_string(const gchar *layoutstr)
Get tensor layout from string input.
Definition: tensor_filter_common.c:134
gst_tensor_filter_common_get_property
gboolean gst_tensor_filter_common_get_property(GstTensorFilterPrivate *priv, guint prop_id, GValue *value, GParamSpec *pspec)
Get the properties for tensor_filter.
Definition: tensor_filter_common.c:2102
gst_tensor_filter_load_tensor_info
void gst_tensor_filter_load_tensor_info(GstTensorFilterPrivate *priv)
Load tensor info from NN model. (both input and output tensor)
Definition: tensor_filter_common.c:2409
gst_tensors_info_is_equal
gboolean gst_tensors_info_is_equal(const GstTensorsInfo *i1, const GstTensorsInfo *i2)
Compare tensors info.
Definition: nnstreamer_plugin_api_util_impl.c:454
_GstTensorFilterFramework::allocateInInvoke
int(* allocateInInvoke)(void **private_data)
Definition: nnstreamer_plugin_api_filter.h:378
SET_INPUT_INFO
@ SET_INPUT_INFO
Definition: nnstreamer_plugin_api_filter.h:194
nnstreamer_filter_shared_model_replace
void nnstreamer_filter_shared_model_replace(void *instance, const char *key, void *new_interpreter, void(*replace_callback)(void *, void *), void(*free_callback)(void *))
Helper to reload interpreter for instances that has shared key. replace_callback is called iterating ...
Definition: tensor_filter_common.c:3128
gst_tensor_filter_check_hw_availability
gboolean gst_tensor_filter_check_hw_availability(const gchar *name, const accl_hw hw, const char *custom)
Check if the given hw is supported by the framework.
Definition: tensor_filter_common.c:2923
_GstTensorFilterFrameworkEventData::custom
const char * custom
Definition: nnstreamer_plugin_api_filter.h:235
_gtfc_setprop_LATENCY
static gint _gtfc_setprop_LATENCY(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const GValue *value)
Handle "PROP_LATENCY" for set-property.
Definition: tensor_filter_common.c:1799
nns_logw
#define nns_logw
Definition: nnstreamer_log.h:141
get_accl_hw_type
accl_hw get_accl_hw_type(const gchar *key)
return accl_hw type from string
Definition: tensor_filter_common.c:2577
gst_tensor_filter_allocate_in_invoke
gboolean gst_tensor_filter_allocate_in_invoke(GstTensorFilterPrivate *priv)
check if the allocate_in_invoke is valid for the framework
Definition: tensor_filter_common.c:757
_GstTensorFilterFrameworkInfo::name
const char * name
Definition: nnstreamer_plugin_api_filter.h:160
parse_accl_hw_fill
accl_hw parse_accl_hw_fill(parse_accl_args accl_args)
parse user given string to extract accelerator based on given regex filling in optional arguments
Definition: tensor_filter_common.c:2833
REGEX_ACCL_PREFIX
#define REGEX_ACCL_PREFIX
Definition: tensor_filter_common.c:61
_GstTensorFilterFramework::handleEvent
int(* handleEvent)(event_ops ops, GstTensorFilterFrameworkEventData *data)
Definition: nnstreamer_plugin_api_filter.h:361
GstTensorsInfo::num_tensors
unsigned int num_tensors
Definition: tensor_typedef.h:275
gst_tensor_filter_parse_accelerator
static void gst_tensor_filter_parse_accelerator(GstTensorFilterPrivate *priv, GstTensorFilterProperties *prop, const char *accelerators)
Parse the hardware accelerators to be used for this framework.
Definition: tensor_filter_common.c:1123
NNSTREAMER_SO_FILE_EXTENSION
#define NNSTREAMER_SO_FILE_EXTENSION
Definition: nnstreamer_conf.h:53
PROP_THROUGHPUT
@ PROP_THROUGHPUT
Definition: tensor_filter_common.h:104
_gtfc_setprop_DIMENSION
static gint _gtfc_setprop_DIMENSION(GstTensorFilterPrivate *priv, const GValue *value, const gboolean is_input)
Handle "PROP_INPUT" and "PROP_OUTPUT" for set-property.
Definition: tensor_filter_common.c:1490
PROP_INPUTCOMBINATION
@ PROP_INPUTCOMBINATION
Definition: tensor_filter_common.h:105
_GstTensorFilterFramework::verify_model_path
int verify_model_path
Definition: nnstreamer_plugin_api_filter.h:288
PROP_SUBPLUGINS
@ PROP_SUBPLUGINS
Definition: gsttensor_converter.c:124
tensor_filter_common.h
Common functions for various tensor_filters.
gst_tensors_config_init
void gst_tensors_config_init(GstTensorsConfig *config)
Initialize the tensors config info structure (for other/tensors)
Definition: nnstreamer_plugin_api_util_impl.c:830
ml_logd
#define ml_logd
Definition: nnstreamer_log.h:79
gst_tensor_filter_common_init_property
void gst_tensor_filter_common_init_property(GstTensorFilterPrivate *priv)
Initialize the properties for tensor-filter.
Definition: tensor_filter_common.c:1041
_GstTensorFilterPrivate::combi
GstTensorFilterCombination combi
Definition: tensor_filter_common.h:173
ACCL_CPU_SIMD
@ ACCL_CPU_SIMD
Definition: nnstreamer_plugin_api_filter.h:91
gst_tensor_filter_get_dimension_string
static gchar * gst_tensor_filter_get_dimension_string(const GstTensorFilterProperties *prop, const gboolean isInput)
Get the dimension string of tensors considering rank count.
Definition: tensor_filter_common.c:259
GstTensorFilterSharedModelRepresentation::referred_list
GList * referred_list
Definition: tensor_filter_common.h:146
_NNS_LAYOUT_NHWC
@ _NNS_LAYOUT_NHWC
Definition: tensor_typedef.h:223
ACCL_CPU_NEON
@ ACCL_CPU_NEON
Definition: nnstreamer_plugin_api_filter.h:92
_GstTensorFilterPrivate::prop
GstTensorFilterProperties prop
Definition: tensor_filter_common.h:155
gst_tensor_info_get_rank
guint gst_tensor_info_get_rank(const GstTensorInfo *info)
Get tensor rank.
Definition: nnstreamer_plugin_api_util_impl.c:285
GstTensorInfo::type
tensor_type type
Definition: tensor_typedef.h:266
ACCL_NONE_STR
#define ACCL_NONE_STR
Definition: nnstreamer_plugin_api_filter.h:20
gst_tensor_filter_detect_framework
gchar * gst_tensor_filter_detect_framework(const gchar *const *model_files, const guint num_models, const gboolean load_conf)
Get neural network framework name from given model file. This does not guarantee the framework is ava...
Definition: tensor_filter_common.c:1232
ml_agent.h
Internal header to make a bridge between NNS filters and the ML Agent service.
gst_tensors_info_get_names_string
gchar * gst_tensors_info_get_names_string(const GstTensorsInfo *info)
Get the string of tensor names in tensors info.
Definition: nnstreamer_plugin_api_util_impl.c:749
_GstTensorFilterFrameworkInfo::verify_model_path
int verify_model_path
Definition: nnstreamer_plugin_api_filter.h:164
nnsconf_get_custom_value_string
gchar * nnsconf_get_custom_value_string(const gchar *group, const gchar *key)
Public function defined in the header.
Definition: nnstreamer_conf.c:557
ACCL_NPU_SR
@ ACCL_NPU_SR
Definition: nnstreamer_plugin_api_filter.h:101
strcpy2
static gchar * strcpy2(gchar *dest, const gchar *src)
copy the string from src to destination
Definition: tensor_filter_common.c:414
ACCL_NPU_SLSI
@ ACCL_NPU_SLSI
Definition: nnstreamer_plugin_api_filter.h:100
gst_tensors_info_copy
void gst_tensors_info_copy(GstTensorsInfo *dest, const GstTensorsInfo *src)
Copy tensor info.
Definition: nnstreamer_plugin_api_util_impl.c:502
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_aggregator.c:70
ACCL_CPU_STR
#define ACCL_CPU_STR
Definition: nnstreamer_plugin_api_filter.h:23
GstTensorInfo::dimension
tensor_dim dimension
Definition: tensor_typedef.h:267
_GstTensorFilterCombination::out_combi_o_defined
gboolean out_combi_o_defined
Definition: tensor_filter_common.h:138
_GstTensorFilterProperties::hw_list
accl_hw * hw_list
Definition: nnstreamer_plugin_api_filter.h:130
PROP_ACCELERATOR
@ PROP_ACCELERATOR
Definition: tensor_filter_common.h:101
gst_tensor_filter_common_close_fw
void gst_tensor_filter_common_close_fw(GstTensorFilterPrivate *priv)
Close NN framework.
Definition: tensor_filter_common.c:2560
PROP_OUTPUTTYPE
@ PROP_OUTPUTTYPE
Definition: tensor_filter_common.h:95
gst_tensorsinfo_compare_print
void gst_tensorsinfo_compare_print(const GstTensorsInfo *info1, const GstTensorsInfo *info2)
Printout the comparison results of two tensors.
Definition: tensor_filter_common.c:874
REGEX_ACCL_END
#define REGEX_ACCL_END
Definition: tensor_filter_common.c:64
_GstTensorFilterFrameworkEventData::hw
accl_hw hw
Definition: nnstreamer_plugin_api_filter.h:234
_GstTensorFilterFrameworkInfo::allow_in_place
int allow_in_place
Definition: nnstreamer_plugin_api_filter.h:161
_GstTensorFilterPrivate::latency_mode
gint latency_mode
Definition: tensor_filter_common.h:168
_GstTensorFilterPrivate::privateData
void * privateData
Definition: tensor_filter_common.h:154
gst_tensors_info_parse_types_string
guint gst_tensors_info_parse_types_string(GstTensorsInfo *info, const gchar *type_string)
Parse the string of types.
Definition: nnstreamer_plugin_api_util_impl.c:572
if
if(!gst_tensordec_process_plugin_options(self,(opnum) - 1)) GST_ERROR_OBJECT(self
_NNS_LAYOUT_NONE
@ _NNS_LAYOUT_NONE
Definition: tensor_typedef.h:225
REGEX_ACCL_ELEM_PREFIX
#define REGEX_ACCL_ELEM_PREFIX
Definition: tensor_filter_common.c:55
ACCL_NPU_EDGE_TPU
@ ACCL_NPU_EDGE_TPU
Definition: nnstreamer_plugin_api_filter.h:97
_GstTensorFilterFramework::getFrameworkInfo
int(* getFrameworkInfo)(const GstTensorFilterFramework *self, const GstTensorFilterProperties *prop, void *private_data, GstTensorFilterFrameworkInfo *fw_info)
Definition: nnstreamer_plugin_api_filter.h:407
parse_accl_hw_all
static GList * parse_accl_hw_all(const gchar *accelerators, const gchar **supported_accelerators)
parse user given string to extract list of accelerators based on given regex
Definition: tensor_filter_common.c:2620
GST_TF_FW_V1
#define GST_TF_FW_V1(fw)
Definition: tensor_filter_common.h:48
GstTensorsInfo::format
tensor_format format
Definition: tensor_typedef.h:278
_GstTensorFilterStatistics::total_invoke_num
gint64 total_invoke_num
Definition: tensor_filter_common.h:119
_GstTensorFilterProperties::invoke_dynamic
int invoke_dynamic
Definition: nnstreamer_plugin_api_filter.h:137
ACCL_DEFAULT
@ ACCL_DEFAULT
Definition: nnstreamer_plugin_api_filter.h:87
get_subplugin
const void * get_subplugin(subpluginType type, const char *name)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:141
unregister_subplugin
gboolean unregister_subplugin(subpluginType type, const char *name)
Public function defined in the header.
Definition: nnstreamer_subplugin.c:289
g_strfreev_const
#define g_strfreev_const(x)
Definition: tensor_filter_common.c:88
_GstTensorFilterFramework::close
void(* close)(const GstTensorFilterProperties *prop, void **private_data)
Definition: nnstreamer_plugin_api_filter.h:267
gst_tensor_filter_v0_call
#define gst_tensor_filter_v0_call(priv, ret, funcname,...)
Invoke callbacks of nn framework. Guarantees calling open for the first call.
Definition: tensor_filter_common.h:53