35 #define silent_debug_info(i,msg) do { \
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); \
43 dim_str = gst_tensor_get_dimension_string (nth->dimension); \
44 ml_logd ("[%d] type=%d dim=%s", info_idx, nth->type, dim_str); \
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 ")?"
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 ")*[)]?))"
87 #define g_free_const(x) g_free((void*)(long)(x))
88 #define g_strfreev_const(x) g_strfreev((void*)(long)(x))
92 const gchar ** supported_accelerators);
136 gchar *layout_string;
139 if (layoutstr == NULL)
143 layout_string = g_strdup (layoutstr);
144 g_strstrip (layout_string);
147 if (0 == strlen (layout_string))
150 if (g_ascii_strcasecmp (layoutstr,
"NCHW") == 0) {
152 }
else if (g_ascii_strcasecmp (layoutstr,
"NHWC") == 0) {
154 }
else if (g_ascii_strcasecmp (layoutstr,
"ANY") == 0) {
157 nns_logw (
"Invalid layout, defaulting to none layout.");
174 const gchar * layout_string)
176 guint num_layouts = 0;
178 g_return_val_if_fail (layout != NULL, 0);
184 str_layouts = g_strsplit_set (layout_string,
",.", -1);
185 num_layouts = g_strv_length (str_layouts);
188 nns_logw (
"Invalid param, layouts (%d) max (%d)\n",
194 for (i = 0; i < num_layouts; i++) {
198 g_strfreev (str_layouts);
214 gchar *rank_str = NULL;
219 g_return_val_if_fail (
prop != NULL, NULL);
222 _ranks =
prop->input_ranks;
223 _meta = &
prop->input_meta;
225 _ranks =
prop->output_ranks;
226 _meta = &
prop->output_meta;
230 GString *rank = g_string_new (NULL);
234 g_string_append_printf (rank,
"%u", _ranks[i]);
236 g_string_append_printf (rank,
"%u",
240 if (i < _meta->num_tensors - 1)
241 g_string_append_printf (rank,
",");
243 rank_str = g_string_free (rank,
FALSE);
245 rank_str = g_strdup (
"");
260 const gboolean isInput)
262 gchar *dim_str = NULL;
264 const unsigned int *_rank;
267 tinfo = &
prop->input_meta;
268 _rank =
prop->input_ranks;
270 tinfo = &
prop->output_meta;
271 _rank =
prop->output_ranks;
276 GString *dimensions = g_string_new (NULL);
282 g_string_append (dimensions, dim_str);
284 if (i < tinfo->num_tensors - 1) {
285 g_string_append (dimensions,
",");
289 dim_str = g_string_free (dimensions,
FALSE);
291 dim_str = g_strdup (
"");
305 const gboolean is_input)
310 info = (is_input) ? &
prop->input_meta : &
prop->output_meta;
315 type_str = g_strdup (
"");
328 const gboolean is_input)
333 info = (is_input) ? &
prop->input_meta : &
prop->output_meta;
338 name_str = g_strdup (
"");
373 const gboolean is_input)
375 gchar *layout_str = NULL;
380 info = &
prop->input_meta;
381 layout = &
prop->input_layout;
383 info = &
prop->output_meta;
384 layout = &
prop->output_layout;
389 GString *layouts = g_string_new (NULL);
394 if (i < info->num_tensors - 1) {
395 g_string_append (layouts,
",");
399 layout_str = g_string_free (layouts,
FALSE);
401 layout_str = g_strdup (
"");
417 ml_loge (
"Failed to copy a string. The variables shouldn't be NULL.");
420 memcpy (dest, src, strlen (src));
421 return dest + strlen (src);
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 =
".";
440 gchar *regex_escaped;
442 if (iterator == NULL)
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]);
456 regex_ptr =
strcpy2 (regex_ptr, regex_utils[4]);
460 regex_split = g_strsplit_set (regex, escape_chars, -1);
461 regex_escaped = g_strjoinv (escape_separator, regex_split);
462 g_strfreev (regex_split);
464 return regex_escaped;
472 static inline gboolean
484 if (g_strcmp0 (
prop->fwname,
"custom-easy") == 0)
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]);
615 const char *name = NULL;
624 ml_loge (
"getFrameworkInfo() failed.\n");
652 va_start (varargs,
prop);
670 if (names == NULL || names[0] ==
'\0')
673 subplugins = g_strsplit_set (names,
" ,;", -1);
676 for (i = 0; i < len; i++) {
702 g_return_val_if_fail (name != NULL, NULL);
729 const gchar * model_files)
737 gchar **models = g_strsplit_set (model_files,
",", -1);
738 guint i, num = g_strv_length (models);
740 for (i = 0; i < num; i++)
741 g_strstrip (models[i]);
743 prop->model_files = (
const gchar **) models;
744 prop->num_models = num;
746 prop->model_files = NULL;
747 prop->num_models = 0;
759 int allocate_in_invoke = 0;
768 allocate_in_invoke =
TRUE;
770 allocate_in_invoke =
FALSE;
777 return allocate_in_invoke;
815 gchar *line, *tmp, *left, *right;
818 g_return_val_if_fail (info1 != NULL && info2 != NULL, NULL);
829 g_strdup_printf (
"%s [%s]",
833 left = g_strdup (
"None");
841 g_strdup_printf (
"%s [%s]",
845 right = g_strdup (
"None");
848 line = g_strdup_printf (
"%2d : %s | %s %s\n", i, left, right,
849 g_str_equal (left, right) ?
"" :
"Not equal");
855 tmp = g_strdup_printf (
"%s%s",
result, line);
879 "cannot compare NULL metadata(GstTensorsInfo) with others" :
result);
892 static gchar *strprint = NULL;
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));
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}.",
906 g_param_spec_string (
"framework",
"Framework", strprint,
"auto",
907 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
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));
921 g_param_spec_string (
"inputname",
"Name of Input Tensor",
922 "The Name of Input Tensor",
"",
923 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
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));
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));
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));
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));
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));
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));
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));
963 g_param_spec_string (
"sub-plugins",
"Sub-plugins",
964 "Registrable sub-plugins list",
"",
965 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
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));
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).",
987 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
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).",
995 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
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));
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));
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));
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));
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));
1093 while ((latency = g_queue_pop_tail (queue)) != NULL)
1095 g_queue_free (queue);
1106 value = g_list_next (value);
1128 const gchar **accl_support;
1129 GList *match_accl, *iter;
1133 prop->hw_list = NULL;
1141 if (status != 0 || info.
hw_list == NULL || info.
num_hw <= 0) {
1142 ml_logw (
"Unable to fetch accelerators supported by the framework.");
1150 accl_support = g_malloc (
sizeof (gchar *) * (info.
num_hw + 2 + 1));
1152 for (idx = 0; idx < info.
num_hw; idx++) {
1157 accl_support[info.
num_hw + 2] = NULL;
1164 prop->num_hw = g_list_length (match_accl);
1166 for (iter = match_accl, idx = 0; iter != NULL; iter = iter->next, idx++) {
1167 prop->hw_list[idx] = GPOINTER_TO_INT (iter->data);
1178 g_list_free (match_accl);
1187 gchar *detected = NULL;
1189 gchar *priority_str;
1190 gchar **priority_arr;
1197 fw_key = g_strdup_printf (
"framework_priority_%s", extension);
1202 priority_arr = g_strsplit (priority_str,
",", -1);
1203 len = g_strv_length (priority_arr);
1205 for (i = 0; i < len; i++) {
1207 detected = g_strdup (priority_arr[i]);
1208 nns_logi (
"Detected framework is %s.", detected);
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.");
1216 g_strfreev (priority_arr);
1233 const guint num_models,
const gboolean load_conf)
1235 gchar *detected_fw = NULL;
1240 g_return_val_if_fail (model_files && num_models > 0, NULL);
1243 if (g_file_test (model_files[0], G_FILE_TEST_IS_DIR)) {
1244 detected_fw = g_strdup (
"nnfw");
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]);
1259 ext[i] = g_ascii_strdown (pos, -1);
1263 if (num_models == 1) {
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");
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");
1300 nns_logw (
"Invalid number of model files.");
1307 nns_logw (
"Cannot get any neural network framework for given model.");
1318 const char *fw_name)
1322 gchar *detected_fw = NULL;
1324 if (fw_name == NULL)
1329 if (g_ascii_strcasecmp (fw_name,
"auto") == 0) {
1330 if (
prop->model_files == NULL) {
1333 prop->fwname = g_strdup (fw_name);
1340 detected_fw = g_strdup (fw_name);
1346 prop->fwname = NULL;
1349 nns_logd (
"Framework = %s\n", fw_name);
1360 nns_logw (
"Cannot get the given framework info, %s\n", fw_name);
1366 prop->fwname = detected_fw;
1373 nns_logw (
"Cannot identify the given neural network framework, %s\n",
1385 const gchar *fw_name = g_value_get_string (value);
1386 GValue val = G_VALUE_INIT;
1388 if (priv->
fw != NULL) {
1389 if (g_strcmp0 (priv->
prop.
fwname, fw_name) != 0) {
1394 ml_logd (
"Framework = %s\n", fw_name);
1402 g_value_init (&val, G_TYPE_BOOLEAN);
1405 g_value_unset (&val);
1407 ml_logw (
"Set property is-updatable failed with error: %d", status);
1412 if (
prop->accl_str) {
1413 g_value_init (&val, G_TYPE_STRING);
1416 g_value_unset (&val);
1418 ml_logw (
"Set property accelerator failed with error: %d", status);
1436 ml_loge (
"Invalid model provided to the tensor-filter.");
1441 if (
prop->fw_opened) {
1445 (
const gchar **) g_strdupv ((gchar **)
prop->model_files);
1450 if (
prop->fwname != NULL && g_ascii_strcasecmp (
prop->fwname,
"auto") == 0)
1458 if (
prop->fw_opened) {
1466 data.model_files =
prop->model_files;
1467 data.num_models =
prop->num_models;
1478 ml_loge (
"Fail to reload model\n");
1491 const GValue * value,
const gboolean is_input)
1501 info = &
prop->input_meta;
1502 rank =
prop->input_ranks;
1503 configured =
prop->input_configured;
1505 info = &
prop->output_meta;
1506 rank =
prop->output_ranks;
1507 configured =
prop->output_configured;
1510 if (!configured && value) {
1515 str_dims = g_strsplit_set (g_value_get_string (value),
",.", -1);
1516 num_dims = g_strv_length (str_dims);
1519 nns_logw (
"Invalid param, dimensions (%d) max (%d)\n",
1525 for (i = 0; i < num_dims; ++i) {
1529 g_strfreev (str_dims);
1534 (
"Invalid dimension, given param does not match with old value.");
1542 (
"Cannot change dimension once the element/pipeline is configured.");
1550 const GValue * value,
const gboolean is_input)
1559 info = &
prop->input_meta;
1560 configured =
prop->input_configured;
1562 info = &
prop->output_meta;
1563 configured =
prop->output_configured;
1566 if (!configured && value) {
1570 g_value_get_string (value));
1572 if (num_types > 0) {
1574 ml_logw (
"Invalid type, given param does not match with old value.");
1581 ml_loge (
"Cannot change type once the element/pipeline is configured.");
1589 const GValue * value,
const gboolean is_input)
1598 info = &
prop->input_meta;
1599 configured =
prop->input_configured;
1601 info = &
prop->output_meta;
1602 configured =
prop->output_configured;
1605 if (!configured && value) {
1609 g_value_get_string (value));
1611 if (num_names > 0) {
1613 ml_logw (
"Invalid name, given param does not match with old value.");
1620 ml_loge (
"Cannot change name once the element/pipeline is configured.");
1633 prop->custom_properties = g_value_dup_string (value);
1637 (
"Cannot change custom-prop once the element/pipeline is configured.");
1641 data.custom_properties = g_value_dup_string (value);
1646 prop->custom_properties = g_value_dup_string (value);
1662 const gchar *accelerators = g_value_get_string (value);
1667 (
"Cannot change accelerator once the element/pipeline is configured.");
1675 prop->hw_list = NULL;
1697 prop->accl_str = g_strdup (accelerators);
1703 prop->accl_str = g_strdup (accelerators);
1733 const GValue * value,
const gboolean is_input)
1745 info = &
prop->input_meta;
1746 layout = &
prop->input_layout;
1747 configured =
prop->input_configured;
1750 info = &
prop->output_meta;
1751 layout = &
prop->output_layout;
1752 configured =
prop->output_configured;
1756 if (!configured && value) {
1758 g_value_get_string (value));
1760 if (num_layouts > 0) {
1762 ml_logw (
"Invalid layout, given param does not fit.");
1771 ml_loge (
"Cannot change layout once the element/pipeline is configured.");
1777 g_value_get_string (value));
1779 if (num_layouts > 0) {
1781 ml_logw (
"Invalid layout, given param does not fit.");
1786 memcpy (*layout,
data.layout,
1789 ml_logw (
"Unable to update layout.");
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).");
1824 gint throughput_mode;
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).");
1844 GList ** prop_list,
const GValue * value)
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);
1852 g_list_free (*prop_list);
1855 for (i = 0; i < num; i++) {
1856 val = g_ascii_strtoull (strv[i], NULL, 10);
1858 ml_loge (
"Invalid value %s, cannot set combination option.", strv[i]);
1862 *prop_list = g_list_append (*prop_list, GUINT_TO_POINTER (val));
1866 if (ret == 0 && num > 0)
1875 GList ** prop_list1, GList ** prop_list2,
const GValue * value)
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);
1883 g_list_free (*prop_list1);
1884 g_list_free (*prop_list2);
1885 *prop_list1 = *prop_list2 = NULL;
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));
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));
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");
1905 ml_loge (
"Invalid value %s, cannot set combination option.", strv[i]);
1918 const GValue * value)
1921 prop->shared_tensor_filter_key = g_value_dup_string (value);
1926 g_hash_table_new_full (g_str_hash, g_str_equal,
g_free,
g_free);
1938 const GValue * value)
1951 const GValue * value)
1968 guint prop_id,
const GValue * value, GParamSpec * pspec)
1978 priv->
silent = g_value_get_boolean (value);
2068 GPtrArray *arr = g_ptr_array_new ();
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)));
2077 g_ptr_array_add (arr, g_strdup_printf (
"i%u",
2078 GPOINTER_TO_UINT (list->data)));
2080 g_ptr_array_add (arr, g_strdup_printf (
"o%u",
2081 GPOINTER_TO_UINT (list->data)));
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);
2089 g_strfreev (strings);
2090 g_value_take_string (value, p);
2103 guint prop_id, GValue * value, GParamSpec * pspec)
2113 g_value_set_boolean (value, priv->
silent);
2120 GString *gstr_models = g_string_new (NULL);
2125 for (idx = 0; idx <
prop->num_models; ++idx) {
2127 g_string_append (gstr_models,
",");
2130 g_string_append (gstr_models,
prop->model_files[idx]);
2133 models = g_string_free (gstr_models,
FALSE);
2134 g_value_take_string (value, models);
2139 g_value_take_string (value, strval);
2143 g_value_take_string (value, strval);
2147 g_value_take_string (value, strval);
2151 g_value_take_string (value, strval);
2155 g_value_take_string (value, strval);
2159 g_value_take_string (value, strval);
2163 g_value_take_string (value, strval);
2167 g_value_take_string (value, strval);
2171 (
prop->custom_properties != NULL) ?
prop->custom_properties :
"");
2178 g_value_take_string (value, g_strjoinv (
",", str_array));
2179 g_strfreev (str_array);
2191 if (
prop->accl_str != NULL) {
2197 if (
prop->num_hw == 0) {
2200 accl = g_string_new (NULL);
2202 for (idx = 0; idx <
prop->num_hw; idx++) {
2205 g_value_take_string (value, g_string_free (accl,
FALSE));
2215 g_value_take_string (value, strval);
2219 g_value_take_string (value, strval);
2223 g_value_set_int (value,
prop->latency);
2226 g_value_set_int (value, -1);
2231 g_value_set_int (value,
prop->throughput);
2234 g_value_set_int (value, -1);
2244 if (
prop->shared_tensor_filter_key)
2253 g_value_set_boolean (value,
prop->invoke_dynamic);
2256 g_value_set_uint (value,
prop->suspend);
2276 g_return_val_if_fail (in != NULL,
FALSE);
2277 g_return_val_if_fail (combined != NULL,
FALSE);
2282 for (list = priv->
combi.
in_combi; list != NULL; list = list->next) {
2283 i = GPOINTER_TO_UINT (list->data);
2286 nns_loge (
"Invalid input index %u, failed to combine info.", i);
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);
2331 i = GPOINTER_TO_UINT (list->data);
2334 nns_loge (
"Invalid input index %u, failed to combine info.", i);
2345 i = GPOINTER_TO_UINT (list->data);
2348 nns_loge (
"Invalid output index %u, failed to combine info.", i);
2379 g_return_val_if_fail (in != NULL,
FALSE);
2380 g_return_val_if_fail (out != NULL,
FALSE);
2385 nns_logw (
"Given input info is invalid, cannot get output info.");
2397 nns_loge (
"Failed to get output info from NN model.");
2413 int res_in = -1, res_out = -1;
2421 if (!
prop->input_configured || !
prop->output_configured) {
2423 &in_info, &out_info);
2427 if (!
prop->input_configured)
2429 if (!
prop->output_configured)
2434 if (!
prop->input_configured && res_in == 0) {
2438 if (
prop->input_meta.num_tensors > 0) {
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",
2457 if (
prop->invoke_dynamic) {
2459 }
else if (!
prop->output_configured && res_out == 0) {
2464 if (
prop->output_meta.num_tensors > 0) {
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",
2493 int run_without_model = 0;
2496 gint64 start_time, end_time;
2498 start_time = g_get_monotonic_time ();
2507 if (G_UNLIKELY (!run_without_model) &&
2525 &priv->
info) != 0) {
2531 end_time = g_get_monotonic_time ();
2534 ml_logi (
"Filter %s with model file %s is opened. It took %"
2536 end_time - start_time);
2579 GEnumClass *enum_class;
2580 GEnumValue *enum_value;
2583 enum_value = g_enum_get_value_by_name (enum_class, key);
2584 g_type_class_unref (enum_class);
2586 if (enum_value == NULL)
2588 return enum_value->value;
2600 GEnumClass *enum_class;
2601 GEnumValue *enum_value;
2604 enum_value = g_enum_get_value (enum_class, key);
2605 g_type_class_unref (enum_class);
2607 if (enum_value == NULL)
2609 return enum_value->value_name;
2621 const gchar ** supported_accelerators)
2624 GMatchInfo *match_info;
2627 gchar *regex_accl = NULL;
2628 gchar *regex_accl_elem = NULL;
2629 GList *match_accl = NULL;
2631 if (accelerators == NULL) {
2632 match_accl = g_list_append (match_accl, GINT_TO_POINTER (
ACCL_DEFAULT));
2638 use_accl = (gboolean) g_regex_match_simple (regex_accl, accelerators,
2639 G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY);
2647 g_regex_new (regex_accl_elem, G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY,
2649 g_free (regex_accl_elem);
2652 if (g_regex_match (nnapi_elem, accelerators, G_REGEX_MATCH_NOTEMPTY,
2655 while (g_match_info_matches (match_info)) {
2656 gchar *word = g_match_info_fetch (match_info, 0);
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));
2662 g_match_info_next (match_info, NULL);
2666 (
"Using AUTO accelerator config, User provided accelerator(s) do not intersect with framework's supported accelerators.");
2668 g_match_info_free (match_info);
2669 g_regex_unref (nnapi_elem);
2671 if (g_list_length (match_accl) == 0) {
2672 match_accl = g_list_append (match_accl, GINT_TO_POINTER (
ACCL_AUTO));
2675 match_accl = g_list_append (match_accl, GINT_TO_POINTER (
ACCL_NONE));
2685 static const gchar **
2688 gint num_hw = 0, idx = 0;
2689 const gchar **accl_support;
2692 while (supported_accelerators[num_hw] != NULL)
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");
2704 while (supported_accelerators[idx] != NULL) {
2705 accl_support[idx] = supported_accelerators[idx];
2710 accl_support[idx] = NULL;
2712 return accl_support;
2721 static const gchar **
2724 gint num_hw = 0, idx = 0;
2725 const gchar **accl_support;
2729 while (supported_accelerators[num_hw] != NULL) {
2734 accl_support = g_malloc (
sizeof (gchar *) * (num_hw + 1));
2739 while (supported_accelerators[idx] != NULL) {
2742 ml_logw (
"Neon instructions are not available on this device.");
2744 accl_support[num_hw] = supported_accelerators[idx];
2749 accl_support[num_hw] = NULL;
2751 return accl_support;
2764 const gchar ** supported_accelerators,
const gchar * auto_accelerator,
2765 const gchar * default_accelerator)
2769 const gchar **all_supported_accelerators;
2772 all_supported_accelerators =
2774 if (all_supported_accelerators) {
2776 g_free (all_supported_accelerators);
2781 if (NULL == match_accl) {
2782 ml_loge (
"There is no match hardware accelerators from {%s}.\n",
2787 hw = GPOINTER_TO_INT (match_accl->data);
2788 g_list_free (match_accl);
2806 const gchar **accl_support, **filtered_accl_support;
2810 accl_support = g_malloc (
sizeof (gchar *) * (2));
2813 accl_support[0] = accl;
2814 accl_support[1] = NULL;
2817 if (!filtered_accl_support || filtered_accl_support[0] == NULL) {
2823 g_free (filtered_accl_support);
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;
2846 if (!filtered_accl) {
2851 sup_accl = filtered_accl;
2852 if (sup_accl[0] == NULL) {
2862 def_accl = sup_accl[0];
2870 auto_accl = sup_accl[0];
2885 static gsize g_accl_hw_type_id_store = 0;
2887 if (g_once_init_enter (&g_accl_hw_type_id_store)) {
2888 static const GEnumValue values[] = {
2893 #if defined(__aarch64__) || defined(__arm__)
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);
2914 return g_accl_hw_type_id_store;
2927 gboolean available =
FALSE;
2933 nns_logw (
"Cannot check hw availability, given framework name is NULL.");
2937 nns_logw (
"Cannot find sub-plugin for %s.", name);
2952 for (idx = 0; idx < info.
num_hw; idx++) {
2953 if (info.
hw_list[idx] == hw) {
2962 if (available && custom) {
2978 if (ret != 0 && ret != -ENOENT)
2999 ml_loge (
"The shared model representation is not supported properly!");
3005 ml_logi (
"There is no value of the key: %s", key);
3033 ml_loge (
"The instance should NOT be NULL!");
3037 ml_loge (
"The key should NOT be NULL!");
3041 ml_loge (
"The interpreter should NOT be NULL!");
3047 ml_loge (
"The shared model representation is not supported properly!");
3064 (gpointer) model_rep);
3082 void (*free_callback) (
void *))
3090 ml_loge (
"The shared model representation is not supported properly!");
3096 ml_loge (
"There is no value of the key: %s", key);
3102 ml_logd (
"The referred instance of sharing key: %s has been removed!", key);
3129 void *new_interpreter,
void (*replace_callback) (
void *,
void *),
3130 void (*free_callback) (
void *))
3137 ml_loge (
"The key should NOT be NULL!");
3143 ml_loge (
"The shared model representation is not supported properly!");
3151 replace_callback (itr->data, new_interpreter);