diff --git a/tools/benchmark_tool/openvino/tools/benchmark/utils/inputs_filling.py b/tools/benchmark_tool/openvino/tools/benchmark/utils/inputs_filling.py index 25b452633b4..824d01b2232 100644 --- a/tools/benchmark_tool/openvino/tools/benchmark/utils/inputs_filling.py +++ b/tools/benchmark_tool/openvino/tools/benchmark/utils/inputs_filling.py @@ -155,13 +155,13 @@ def get_image_tensors(image_paths, info, batch_sizes): logger.warning(f"Image is resized from ({image.shape[:-1]}) to ({new_im_size})") image = cv2.resize(image, new_im_size) - if info.scale or info.mean: + if info.scale.size or info.mean.size: blue, green, red = cv2.split(image) - if info.mean: + if info.mean.size: blue = np.subtract(blue, info.mean[0]) green = np.subtract(green, info.mean[1]) red = np.subtract(red, info.mean[2]) - if info.scale: + if info.scale.size: blue = np.divide(blue, info.scale[0]) green = np.divide(green, info.scale[1]) red = np.divide(red, info.scale[2]) @@ -314,20 +314,22 @@ def parse_path(path, app_input_info): """ Parse "input_1:file1/dir1,file2/dir2,input_2:file3/dir3 or file1/dir1,file2/dir2" into two dicts - with binary files and with images """ - input_names = sorted(list(info.name for info in app_input_info)) + input_names = list(info.name for info in app_input_info) + input_node_names = list(info.node_name for info in app_input_info) parsed_names = re.findall(r"([^,]\w+):", path) - wrong_names = list(name for name in parsed_names if name not in input_names) + wrong_names = list(name for name in parsed_names if name not in input_names + input_node_names) if wrong_names: raise Exception( f"Wrong input mapping! Cannot find inputs: {wrong_names}. " f"Available inputs: {input_names}. " "Please check `-i` input data" ) + tensor_names = [parsed_name if parsed_name in input_names else input_names[input_node_names.index(parsed_name)] for parsed_name in parsed_names] input_pathes = [path for path in re.split(r"[^,]\w+:", path) if path] input_path_mapping = defaultdict(list) # input mapping is used - if parsed_names: - input_path_mapping = {input_: files.strip(",").split(",") for input_, files in zip(parsed_names, input_pathes)} + if tensor_names: + input_path_mapping = {input_: files.strip(",").split(",") for input_, files in zip(tensor_names, input_pathes)} else: input_files = list() _input_pathes = input_pathes[0].strip(",").split(",") diff --git a/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py b/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py index aa75c0f938c..d21ac3173fe 100644 --- a/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py +++ b/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py @@ -86,27 +86,35 @@ def pre_post_processing(model: Model, app_inputs_info, input_precision: str, out pre_post_processor.output(i).tensor().set_element_type(element_type) user_precision_map = {} if input_output_precision: - user_precision_map = _parse_arg_map(input_output_precision) + user_precision_map = parse_input_output_precision(input_output_precision) input_names = get_input_output_names(model.inputs) + input_node_names = get_node_names(model.inputs) output_names = get_input_output_names(model.outputs) + output_node_names = get_node_names(model.outputs) for node_name, precision in user_precision_map.items(): user_precision_map[node_name] = get_element_type(precision) for name, element_type in user_precision_map.items(): - if name in input_names: - port = input_names.index(name) - app_inputs_info[port].element_type = element_type - pre_post_processor.input(name).tensor().set_element_type(element_type) - elif name in output_names: - pre_post_processor.output(name).tensor().set_element_type(element_type) + if name in input_names or name in input_node_names: + input_index = input_names.index(name) if name in input_names else input_node_names.index(name) + app_inputs_info[input_index].element_type = element_type + pre_post_processor.input(input_index).tensor().set_element_type(element_type) + elif name in output_names or name in output_node_names: + if name in output_names: + pre_post_processor.output(name).tensor().set_element_type(element_type) + else: + pre_post_processor.output(output_node_names.index(name)).tensor().set_element_type(element_type) else: - raise Exception(f"Node '{name}' does not exist in network") + raise Exception(f"Node '{name}' does not exist in model") # update app_inputs_info if not input_precision: inputs = model.inputs + input_node_names = get_node_names(model.inputs) for i in range(len(inputs)): - if app_inputs_info[i].name in user_precision_map.keys(): + if app_inputs_info[i].name in user_precision_map: app_inputs_info[i].element_type = user_precision_map[app_inputs_info[i].name] + elif input_node_names[i] in user_precision_map: + app_inputs_info[i].element_type = user_precision_map[input_node_names[i]] elif app_inputs_info[i].is_image: app_inputs_info[i].element_type = Type.u8 pre_post_processor.input(i).tensor().set_element_type(Type.u8) @@ -118,14 +126,19 @@ def pre_post_processing(model: Model, app_inputs_info, input_precision: str, out model = pre_post_processor.build() -def _parse_arg_map(arg_map: str): +def parse_input_output_precision(arg_map: str): arg_map = arg_map.replace(" ", "") pairs = [x.strip() for x in arg_map.split(',')] parsed_map = {} for pair in pairs: key_value = [x.strip() for x in pair.split(':')] - parsed_map.update({key_value[0]:key_value[1]}) + name, precision = key_value[0], key_value[1] + # input's name can contain ':' + if len(key_value) == 3: + name = key_value[0] + ':' + key_value[1] + precision = key_value[2] + parsed_map.update({name:precision}) return parsed_map @@ -346,6 +359,8 @@ def get_command_line_arguments(argv): def get_input_output_names(ports): return [port.any_name for port in ports] +def get_node_names(ports): + return [port.node.friendly_name for port in ports] def get_data_shapes_map(data_shape_string, input_names): # Parse parameter string like "input0[shape1][shape2],input1[shape1]" or "[shape1][shape2]" (applied to all inputs) @@ -419,9 +434,10 @@ class AppInputInfo: self.original_shape = None self.partial_shape = None self.data_shapes = [] - self.scale = [] - self.mean = [] + self.scale = np.empty([0]) + self.mean = np.empty([0]) self.name = None + self.node_name = None @property def is_image(self): @@ -528,6 +544,7 @@ def parse_batch_size(batch_size_str): def get_inputs_info(shape_string, data_shape_string, layout_string, batch_size, scale_string, mean_string, inputs): input_names = get_input_output_names(inputs) + input_node_names = get_node_names(inputs) shape_map = parse_input_parameters(shape_string, input_names) data_shape_map = get_data_shapes_map(data_shape_string, input_names) layout_map = parse_input_parameters(layout_string, input_names) @@ -539,19 +556,26 @@ def get_inputs_info(shape_string, data_shape_string, layout_string, batch_size, info = AppInputInfo() # Input name info.name = input_names[i] + # Input node name + info.node_name = input_node_names[i] # Input precision info.element_type = inputs[i].element_type # Shape info.original_shape = inputs[i].partial_shape - if info.name in shape_map.keys(): + if info.name in shape_map: info.partial_shape = parse_partial_shape(shape_map[info.name]) reshape = True + elif info.node_name in shape_map: + info.partial_shape = parse_partial_shape(shape_map[info.node_name]) + reshape = True else: info.partial_shape = inputs[i].partial_shape # Layout - if info.name in layout_map.keys(): + if info.name in layout_map: info.layout = Layout(layout_map[info.name]) + elif info.node_name in layout_map: + info.layout = Layout(layout_map[info.node_name]) elif inputs[i].node.layout != Layout(): info.layout = inputs[i].node.layout else: @@ -592,8 +616,9 @@ def get_inputs_info(shape_string, data_shape_string, layout_string, batch_size, raise Exception(f"Batch dimension is not specified for this model!") # Data shape - if info.name in data_shape_map.keys() and info.is_dynamic: - for p_shape in data_shape_map[info.name]: + if (info.name in data_shape_map or info.node_name in data_shape_map) and info.is_dynamic: + used_name = info.name if info.name in data_shape_map else info.node_name + for p_shape in data_shape_map[used_name]: if p_shape.is_dynamic: raise Exception(f"Data shape always should be static, {str(p_shape)} is dynamic.") elif info.partial_shape.compatible(p_shape): @@ -601,7 +626,7 @@ def get_inputs_info(shape_string, data_shape_string, layout_string, batch_size, else: raise Exception(f"Data shape '{str(p_shape)}' provided for input '{info.name}' " f"is not compatible with partial shape '{str(info.partial_shape)}' for this input.") - elif info.name in data_shape_map.keys(): + elif info.name in data_shape_map or input_node_names[i] in data_shape_map: logger.warning(f"Input '{info.name}' has static shape. Provided data shapes for this input will be ignored.") input_info.append(info) @@ -612,9 +637,13 @@ def get_inputs_info(shape_string, data_shape_string, layout_string, batch_size, for input in input_info: if input.name in scale_map: - input.scale = scale_map[input.name] + input.scale = scale_map[input.name] + elif input.node_name in scale_map: + input.scale = scale_map[input.node_name] if input.name in mean_map: input.mean = mean_map[input.name] + elif input.node_name in mean_map: + input.mean = mean_map[input.node_name] return input_info, reshape