Support of unnamed input for MO Python API. (#16373)
* Support of unnamed input for MO Python API. * Code correction, tests fix. * Small fix. * Added tests for unnamed input, code fixes. * Small code correction. * Removed code comment. * Added tests, fixed bugs. * Minor corrections, added comments. * Code refactoring. * Added defaults for InputCutInfo. * Fixed error. * Small fixes. * Removed wrong change. * Fixed error. * Corrected input description.
This commit is contained in:
@@ -43,6 +43,27 @@ class TestComplexParams(CommonMOConvertTest):
|
||||
# save model to .pb and return path to the model
|
||||
return save_to_pb(tf_net, tmp_dir)
|
||||
|
||||
def create_tf_model_no_concat(self, tmp_dir):
|
||||
import tensorflow as tf
|
||||
|
||||
tf.compat.v1.reset_default_graph()
|
||||
|
||||
with tf.compat.v1.Session() as sess:
|
||||
inp1 = tf.compat.v1.placeholder(tf.float32, [1, 3, 2, 2], 'Input1')
|
||||
inp2 = tf.compat.v1.placeholder(tf.float32, [1, 3, 2, 2], 'Input2')
|
||||
inp3 = tf.compat.v1.placeholder(tf.bool, [], 'Input3')
|
||||
output2 = inp3
|
||||
|
||||
relu1 = tf.nn.sigmoid(inp1, name='Relu1')
|
||||
relu2 = tf.nn.sigmoid(inp2, name='Relu2')
|
||||
output = relu1 + relu2
|
||||
|
||||
tf.compat.v1.global_variables_initializer()
|
||||
tf_net = sess.graph_def
|
||||
|
||||
# save model to .pb and return path to the model
|
||||
return save_to_pb(tf_net, tmp_dir)
|
||||
|
||||
def create_tf_model_single_input_output(self, tmp_dir):
|
||||
#
|
||||
# Create Tensorflow model with single input/output
|
||||
@@ -119,8 +140,8 @@ class TestComplexParams(CommonMOConvertTest):
|
||||
[Dimension(), 3, Dimension(4, -1), Dimension(-1, 5)]],
|
||||
'input':['Input1', 'Input2', 'Relu3']},
|
||||
'params_ref': {'input_shape': "[?,1..3,4..,..5],[?,1..3,4,..5],[?,3,4..,..5]", 'input': 'Input1,Input2,Relu3'}},
|
||||
{'params_test': {'input': [InputCutInfo("Relu1", Shape([3, 2]), Type(np.int32), None),
|
||||
InputCutInfo("Relu2", PartialShape([Dimension(3, 10), Dimension(2, -1)]), np.int32, None),
|
||||
{'params_test': {'input': [InputCutInfo("Relu1", Shape([3, 2]), Type(np.int32)),
|
||||
InputCutInfo("Relu2", PartialShape([Dimension(3, 10), Dimension(2, -1)]), np.int32),
|
||||
InputCutInfo("Relu3", [3, 2], Type(np.int32), [1, 2, 3, 4, 5, 6])]},
|
||||
'params_ref': {'input': "Relu1[3 2]{i32},Relu2[3..10 2..]{i32},Relu3[3 2]{i32}->[1 2 3 4 5 6]"}},
|
||||
{'params_test': {'input': [("Relu1", Shape([3, 2]), Type(np.int32)),
|
||||
@@ -150,7 +171,14 @@ class TestComplexParams(CommonMOConvertTest):
|
||||
'Input2': LayoutMap(source_layout="nc??", target_layout=Layout("n??c")),
|
||||
'Input3': LayoutMap(source_layout="abcd", target_layout="acdb")}},
|
||||
'params_ref': {'layout': "Input1(nchw->nhwc),Input2(nc??->n??c),Input3(abcd->acdb)"}},
|
||||
|
||||
{'params_test': {'input': [PartialShape([2, 3, 4]), [2, 3, 4], [Dimension(2), Dimension(3), Dimension(4)]]},
|
||||
'params_ref': {'input_shape': "[2,3,4],[2,3,4],[2,3,4]", 'input': 'Input1,Input2,Input3'}},
|
||||
{'params_test': {'input': [np.int32, Type(np.int32), np.int32]},
|
||||
'params_ref': {'input': 'Input1{i32},Input2{i32},Input3{i32}'}},
|
||||
{'params_test': {'input': [InputCutInfo(shape=[1], type=np.int32, value=[10]),
|
||||
InputCutInfo(shape=[1], type=np.int32, value=[20]),
|
||||
InputCutInfo(shape=[1], type=np.int32, value=[30])]},
|
||||
'params_ref': {'input': 'Input1[1]{i32}->[10],Input2[1]{i32}->[20],Input3[1]{i32}->[30]'}}
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("params", test_data)
|
||||
@@ -165,6 +193,39 @@ class TestComplexParams(CommonMOConvertTest):
|
||||
ref_params.update({'input_model': tf_net_path})
|
||||
self._test(temp_dir, test_params, ref_params)
|
||||
|
||||
test_data = [
|
||||
{'params_test': {'input_shape': [[Dimension(1), 2, 3], [Dimension(1), 2, 3]],
|
||||
'freeze_placeholder_with_value': 'Input3->[1]'},
|
||||
|
||||
'params_ref': {'input_shape': '[1,2,3],[1,2,3]',
|
||||
'freeze_placeholder_with_value': 'Input3->[1]'}},
|
||||
{'params_test': {'input': [PartialShape([Dimension(-1), 5, 6]), [-1, 5, 6]],
|
||||
'freeze_placeholder_with_value': 'Input3->[1]'},
|
||||
|
||||
'params_ref': {'input': 'Input1[?,5,6],Input2[?,5,6]',
|
||||
'freeze_placeholder_with_value': 'Input3->[1]'}},
|
||||
{'params_test': {'input': [np.float16, np.float16],
|
||||
'input_shape': [[10, 20], [10, 20]],
|
||||
'freeze_placeholder_with_value': 'Input3->[1]'},
|
||||
|
||||
'params_ref': {'input': 'Input1{f16},Input2{f16}',
|
||||
'input_shape': "[10,20],[10,20]",
|
||||
'freeze_placeholder_with_value': 'Input3->[1]'}},
|
||||
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("params", test_data)
|
||||
@pytest.mark.nightly
|
||||
def test_mo_convert_tf_model_no_concat(self, params, ie_device, precision, ir_version,
|
||||
temp_dir, use_new_frontend, use_old_api):
|
||||
tf_net_path = self.create_tf_model_no_concat(temp_dir)
|
||||
|
||||
test_params = params['params_test']
|
||||
ref_params = params['params_ref']
|
||||
test_params.update({'input_model': tf_net_path})
|
||||
ref_params.update({'input_model': tf_net_path})
|
||||
self._test(temp_dir, test_params, ref_params)
|
||||
|
||||
test_data = [
|
||||
{'params_test': {'input_shape': PartialShape([2, 3, 4])},
|
||||
'params_ref': {'input_shape': "[2,3,4]"}},
|
||||
@@ -191,7 +252,29 @@ class TestComplexParams(CommonMOConvertTest):
|
||||
{'params_test': {'layout': LayoutMap(source_layout=Layout("nchw"), target_layout="nhwc")},
|
||||
'params_ref': {'layout': "nchw->nhwc"}},
|
||||
{'params_test': {'layout': Layout("nchw")},
|
||||
'params_ref': {'layout': "nchw"}}
|
||||
'params_ref': {'layout': "nchw"}},
|
||||
{'params_test': {'input': [3, 2]},
|
||||
'params_ref': {'input': "Input[3 2]"}},
|
||||
{'params_test': {'input': [Dimension(3,10), 2]},
|
||||
'params_ref': {'input': "Input[3..10 2]"}},
|
||||
{'params_test': {'input': (-1, 10)},
|
||||
'params_ref': {'input': "Input[?,10]"}},
|
||||
{'params_test': {'input': PartialShape([-1, 10])},
|
||||
'params_ref': {'input': "Input[?,10]"}},
|
||||
{'params_test': {'input': np.int32},
|
||||
'params_ref': {'input': "Input{i32}"}},
|
||||
{'params_test': {'input': InputCutInfo(shape=[1], type=np.int32, value=[10])},
|
||||
'params_ref': {'input': "Input[1]{i32}->[10]"}},
|
||||
{'params_test': {'input': (np.int32, [1, 2, 3])},
|
||||
'params_ref': {'input': "Input[1,2,3]{i32}"}},
|
||||
{'params_test': {'input_shape': [Dimension(3, 10), 10, -1]},
|
||||
'params_ref': {'input_shape': '[3..10,10,?]'}},
|
||||
{'params_test': {'input': [Dimension(3, 10), 10, -1]},
|
||||
'params_ref': {'input': 'Input[3..10,10,?]'}},
|
||||
{'params_test': {'input': PartialShape([1, 100, 100, 3]), 'mean_values': [0.5, 1.3, 0.67]},
|
||||
'params_ref': {'input': "Input[1,100,100,3]", 'mean_values': "[0.5,1.3,0.67]"}},
|
||||
{'params_test': {'input': [1, 100, 100, 3], 'scale_values': [0.5, 1.3, 0.67]},
|
||||
'params_ref': {'input': "Input[1,100,100,3]", 'scale_values': "[0.5,1.3,0.67]"}},
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("params", test_data)
|
||||
|
||||
@@ -11,8 +11,8 @@ from openvino.tools.mo.convert_impl import _convert
|
||||
from openvino.tools.mo.utils.cli_parser import get_all_cli_parser
|
||||
from openvino.tools.mo.utils.logger import get_logger_state, restore_logger_state
|
||||
|
||||
InputCutInfo = namedtuple("InputInfo", ["name", "shape", "type", "value"])
|
||||
LayoutMap = namedtuple("LayoutMap", ["source_layout", "target_layout"])
|
||||
InputCutInfo = namedtuple("InputInfo", ["name", "shape", "type", "value"], defaults=[None, None, None, None])
|
||||
LayoutMap = namedtuple("LayoutMap", ["source_layout", "target_layout"], defaults=[None, None])
|
||||
|
||||
|
||||
def convert_model(
|
||||
@@ -118,15 +118,15 @@ def convert_model(
|
||||
|
||||
:param input:
|
||||
Input can be set by passing a list of InputCutInfo objects or by a list
|
||||
of tuples. Each tuple should contain input name and optionally input
|
||||
of tuples. Each tuple can contain optionally input name, input
|
||||
type or input shape. Example: input=("op_name", PartialShape([-1,
|
||||
3, 100, 100]), Type(np.float32)). Alternatively input can be set by
|
||||
a string or list of strings of the following format. Quoted list of comma-separated
|
||||
input nodes names with shapes, data types, and values for freezing.
|
||||
The order of inputs in converted model is the same as order of specified
|
||||
operation names. The shape and value are specified as comma-separated
|
||||
lists. The data type of input node is specified in braces and can have
|
||||
one of the values: f64 (float64), f32 (float32), f16 (float16), i64
|
||||
If operation names are specified, the order of inputs in converted
|
||||
model will be the same as order of specified operation names (applicable for TF2, ONNX, MxNet).
|
||||
The shape and value are specified as comma-separated lists. The data type of input node is specified
|
||||
in braces and can have one of the values: f64 (float64), f32 (float32), f16 (float16), i64
|
||||
(int64), i32 (int32), u8 (uint8), boolean (bool). Data type is optional.
|
||||
If it's not specified explicitly then there are two options: if input
|
||||
node is a parameter, data type is taken from the original node dtype,
|
||||
|
||||
@@ -23,6 +23,7 @@ from openvino.tools.mo.moc_frontend.pipeline import moc_pipeline
|
||||
from openvino.tools.mo.moc_frontend.serialize import moc_emit_ir
|
||||
from openvino.tools.mo.graph.graph import Graph
|
||||
from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
|
||||
from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
|
||||
from openvino.tools.mo.pipeline.common import prepare_emit_ir
|
||||
from openvino.tools.mo.pipeline.unified import unified_pipeline
|
||||
from openvino.tools.mo.utils import import_extensions
|
||||
@@ -31,7 +32,8 @@ from openvino.tools.mo.utils.cli_parser import check_available_transforms, \
|
||||
get_common_cli_options, get_freeze_placeholder_values, get_kaldi_cli_options, get_layout_values, \
|
||||
get_mean_scale_dictionary, get_mxnet_cli_options, get_onnx_cli_options, \
|
||||
get_placeholder_shapes, get_tf_cli_options, parse_transform, parse_tuple_pairs, \
|
||||
get_model_name_from_args, depersonalize, get_mo_convert_params
|
||||
get_model_name_from_args, depersonalize, get_mo_convert_params, input_to_input_cut_info, \
|
||||
input_shape_to_input_cut_info, freeze_placeholder_to_input_cut_info
|
||||
|
||||
from openvino.tools.mo.utils.error import Error
|
||||
from openvino.tools.mo.utils.version import VersionChecker
|
||||
@@ -48,6 +50,7 @@ from openvino.tools.mo.moc_frontend.shape_utils import parse_input_shapes, get_s
|
||||
# pylint: disable=no-name-in-module,import-error
|
||||
from openvino.frontend import FrontEndManager, OpConversionFailure, ProgressReporterExtension, TelemetryExtension
|
||||
from openvino.runtime import get_version as get_rt_version
|
||||
from openvino.runtime import Type, PartialShape
|
||||
|
||||
|
||||
def load_extensions(argv: argparse.Namespace, is_tf: bool, is_caffe: bool, is_mxnet: bool, is_kaldi: bool,
|
||||
@@ -234,17 +237,22 @@ def arguments_post_parsing(argv: argparse.Namespace):
|
||||
raise Error('Incorrect saved model tag was provided. Specify --saved_model_tags with no spaces in it')
|
||||
argv.saved_model_tags = argv.saved_model_tags.split(',')
|
||||
|
||||
if hasattr(argv, 'is_python_api_used') and argv.is_python_api_used:
|
||||
python_api_params_parsing(argv)
|
||||
else:
|
||||
argv.inputs_list, argv.placeholder_shapes, argv.placeholder_data_types = get_placeholder_shapes(
|
||||
argv.input, argv.input_shape, argv.batch)
|
||||
argv.freeze_placeholder_with_value, argv.input = get_freeze_placeholder_values(
|
||||
argv.input,
|
||||
argv.freeze_placeholder_with_value)
|
||||
argv.unnamed_freeze_placeholder_with_value = {}
|
||||
|
||||
argv.output = argv.output.split(',') if argv.output else None
|
||||
|
||||
inputs_list, argv.placeholder_shapes, argv.placeholder_data_types = get_placeholder_shapes(
|
||||
argv.input, argv.input_shape, argv.batch)
|
||||
argv.inputs_list = inputs_list
|
||||
|
||||
argv.layout_values = get_layout_values(argv.layout, argv.source_layout, argv.target_layout)
|
||||
mean_values = parse_tuple_pairs(argv.mean_values)
|
||||
scale_values = parse_tuple_pairs(argv.scale_values)
|
||||
mean_scale = get_mean_scale_dictionary(mean_values, scale_values, argv.input)
|
||||
argv.mean_scale_values = mean_scale
|
||||
argv.layout_values = get_layout_values(argv.layout, argv.source_layout, argv.target_layout)
|
||||
|
||||
if not os.path.exists(argv.output_dir):
|
||||
try:
|
||||
@@ -260,9 +268,6 @@ def arguments_post_parsing(argv: argparse.Namespace):
|
||||
|
||||
log.debug("Placeholder shapes : {}".format(argv.placeholder_shapes))
|
||||
|
||||
argv.freeze_placeholder_with_value, argv.input = get_freeze_placeholder_values(argv.input,
|
||||
argv.freeze_placeholder_with_value)
|
||||
|
||||
load_extensions(argv, is_tf, is_caffe, is_mxnet, is_kaldi, is_onnx)
|
||||
|
||||
return argv
|
||||
@@ -692,6 +697,91 @@ def input_model_is_object(argv):
|
||||
return True
|
||||
|
||||
|
||||
def python_api_params_parsing(argv: argparse.Namespace):
|
||||
"""
|
||||
Parses params passed to convert_model and wraps resulting values into dictionaries or lists.
|
||||
After working of this method following values are set in argv:
|
||||
|
||||
argv.input, argv.inputs_list - list of input names. Both values are used in some parts of MO.
|
||||
Could be good to refactor it and use only one of these values.
|
||||
|
||||
argv.placeholder_shapes - dictionary where key is node name, value is PartialShape,
|
||||
or list of PartialShape if node names were not set.
|
||||
|
||||
argv.placeholder_data_types - dictionary where key is node name, value is node np.type,
|
||||
or list of np.types if node names were not set.
|
||||
|
||||
argv.freeze_placeholder_with_value - dictionary where key is node name, value is np.ndarray
|
||||
|
||||
argv.unnamed_freeze_placeholder_with_value - list with np.ndarray
|
||||
|
||||
:param argv: MO arguments
|
||||
"""
|
||||
# Parse input to list of InputCutInfo
|
||||
inputs = input_to_input_cut_info(argv.input)
|
||||
|
||||
# Make list of input names
|
||||
input_names_list = []
|
||||
for inp in inputs:
|
||||
if inp.name is not None:
|
||||
input_names_list.append(inp.name)
|
||||
if len(input_names_list) > 0:
|
||||
assert len(input_names_list) == len(inputs), "--input parameter has unnamed inputs and named inputs. " \
|
||||
"Please either set names for all inputs, " \
|
||||
"or do not set names for all inputs."
|
||||
argv.inputs_list = input_names_list
|
||||
argv.input = ','.join(input_names_list)
|
||||
|
||||
# Parse input_shape param and update InputCutInfo list
|
||||
input_shape_to_input_cut_info(argv.input_shape, inputs)
|
||||
|
||||
# Parse freeze_placeholder_with_value.
|
||||
# values for freezing can be set both by named and unnamed approach if
|
||||
# 'input' was used without names and 'freeze_placeholder_with_value' was used with names.
|
||||
# So named and unnamed values are stored separately.
|
||||
argv.freeze_placeholder_with_value, argv.unnamed_freeze_placeholder_with_value = \
|
||||
freeze_placeholder_to_input_cut_info(argv.freeze_placeholder_with_value, inputs)
|
||||
|
||||
if len(input_names_list) > 0:
|
||||
# Named inputs case
|
||||
shape_dict = {}
|
||||
data_type_dict = {}
|
||||
for inp in inputs:
|
||||
if inp.shape is not None:
|
||||
# Wrap shape to PartialShape for uniformity of stored values
|
||||
shape_dict[inp.name] = PartialShape(inp.shape)
|
||||
else:
|
||||
shape_dict[inp.name] = None
|
||||
if inp.type is not None:
|
||||
# Convert type to numpy type for uniformity of stored values
|
||||
if isinstance(inp.type, str):
|
||||
data_type_dict[inp.name] = destination_type_to_np_data_type(inp.type)
|
||||
elif isinstance(inp.type, Type):
|
||||
data_type_dict[inp.name] = inp.type.to_dtype().type
|
||||
else:
|
||||
data_type_dict[inp.name] = inp.type
|
||||
argv.placeholder_shapes = shape_dict if shape_dict else None
|
||||
argv.placeholder_data_types = data_type_dict if data_type_dict else {}
|
||||
else:
|
||||
# Unnamed inputs case
|
||||
shape_list = []
|
||||
data_type_list = []
|
||||
for inp in inputs:
|
||||
if inp.shape is not None:
|
||||
# Wrap shape to PartialShape for uniformity of stored values
|
||||
shape_list.append(PartialShape(inp.shape))
|
||||
if inp.type is not None:
|
||||
# Convert type to numpy type for uniformity of stored values
|
||||
if isinstance(inp.type, str):
|
||||
data_type_list.append(destination_type_to_np_data_type(inp.type))
|
||||
elif isinstance(inp.type, Type):
|
||||
data_type_list.append(inp.type.to_dtype().type)
|
||||
else:
|
||||
data_type_list.append(inp.type)
|
||||
argv.placeholder_shapes = shape_list if shape_list else None
|
||||
argv.placeholder_data_types = data_type_list if data_type_list else {}
|
||||
|
||||
|
||||
def pack_params_to_args_namespace(args: dict, cli_parser: argparse.ArgumentParser):
|
||||
if len(args) > 0:
|
||||
args_string = params_to_string(**args)
|
||||
@@ -711,8 +801,10 @@ def pack_params_to_args_namespace(args: dict, cli_parser: argparse.ArgumentParse
|
||||
# so we need to set them in argv separately
|
||||
if value is not None and getattr(argv, key, None) != value:
|
||||
setattr(argv, key, value)
|
||||
argv.is_python_api_used = True
|
||||
else:
|
||||
argv = cli_parser.parse_args()
|
||||
argv.is_python_api_used = False
|
||||
return argv
|
||||
|
||||
|
||||
|
||||
@@ -616,6 +616,8 @@ def input_user_data_repack(graph: Graph, input_user_shapes: [None, list, dict, n
|
||||
if freeze_placeholder is None:
|
||||
_freeze_placeholder = None
|
||||
else:
|
||||
if isinstance(freeze_placeholder, list):
|
||||
raise Error('Unnamed inputs with values are not supported for legacy frontend. Please provide input names.')
|
||||
for placeholder_name, value in freeze_placeholder.items():
|
||||
placeholder_id, direction, port = get_node_id_with_ports(graph, placeholder_name)
|
||||
if port is None and placeholder_id in placeholders_ids:
|
||||
@@ -628,6 +630,10 @@ def input_user_data_repack(graph: Graph, input_user_shapes: [None, list, dict, n
|
||||
{'direction': direction, 'port': port, 'name': placeholder_name, 'id': new_placeholder_id,
|
||||
'value': value})
|
||||
|
||||
if isinstance(input_user_shapes, list):
|
||||
if len(input_user_shapes) == 1 and isinstance(input_user_shapes[0], PartialShape):
|
||||
input_user_shapes = input_user_shapes[0]
|
||||
|
||||
# input user shapes restructure
|
||||
if input_user_shapes is None:
|
||||
# None User did not provide neither --input nor --input_shape keys
|
||||
|
||||
@@ -252,6 +252,9 @@ def fe_input_user_data_repack(
|
||||
"input_name": input_name
|
||||
}
|
||||
)
|
||||
# case when single unnamed input shape and type was specified
|
||||
if input_name in input_user_data_types:
|
||||
_input_shapes[-1]['data_type'] = input_user_data_types[input_name]
|
||||
_input_names.append(input_name)
|
||||
break
|
||||
else:
|
||||
@@ -268,6 +271,9 @@ def fe_input_user_data_repack(
|
||||
"input_name": input_name
|
||||
}
|
||||
)
|
||||
# case when types were specified for unnamed inputs
|
||||
if input_name in input_user_data_types:
|
||||
_input_shapes[-1]['data_type'] = input_user_data_types[input_name]
|
||||
# mark-up Place names we already put into the _input_names
|
||||
# to avoid duplicates in updates by freeze_placeholder below
|
||||
_input_names.append(input_name)
|
||||
@@ -324,6 +330,99 @@ def fe_output_user_data_repack(input_model: InputModel, outputs: list, framework
|
||||
return _outputs
|
||||
|
||||
|
||||
def find_first_unused_input(model_inputs: list, freeze_placeholder: dict, param_dict: dict, param_name: str):
|
||||
"""
|
||||
Finds first input in model_inputs, which is not present in freeze_placeholder dictionary or param_dict.
|
||||
|
||||
:param model_inputs: list of model inputs
|
||||
:param freeze_placeholder: dictionary where key is input name, value is input value for freezing.
|
||||
:param param_dict: dictionary where key is input name, value is parameter value (shape or type).
|
||||
:param param_name: name of parameter used in exception message.
|
||||
|
||||
:return: first input name, which is not present in freeze_placeholder dictionary or param_dict.
|
||||
"""
|
||||
for inp in model_inputs:
|
||||
input_names = inp.get_names()
|
||||
name_found = False
|
||||
for input_name in input_names:
|
||||
if input_name in freeze_placeholder or input_name in param_dict:
|
||||
name_found = True
|
||||
break
|
||||
if name_found:
|
||||
continue
|
||||
return input_names[0]
|
||||
raise Error("Could not set {}, as model does not have enough inputs.".format(param_name))
|
||||
|
||||
|
||||
def convert_params_lists_to_dicts(input_model,
|
||||
input_user_shapes: [list, dict],
|
||||
input_user_data_types: [list, dict],
|
||||
freeze_placeholder: dict,
|
||||
unnamed_freeze_placeholders: list):
|
||||
"""
|
||||
Convert lists of unnamed params to dicts using input names from input_model.
|
||||
|
||||
:param input_model: openvino.runtime.InputModel
|
||||
:param input_user_shapes: list of input shapes or dictionary where key is input name, value is input shape from user.
|
||||
:param input_user_data_types: list of input types or dictionary where key is input name, value is input type from user.
|
||||
:param freeze_placeholder: dictionary where key is input name, value is input value from user.
|
||||
:param unnamed_freeze_placeholders: list of unnamed input values from user.
|
||||
|
||||
:return: (input_user_shapes_dict, input_user_data_types_dict, freeze_placeholder), where
|
||||
input_user_shapes_dict - dictionary where key is input name, value is shape from user;
|
||||
input_user_data_types_dict - dictionary where key is input name, value is type from user;
|
||||
freeze_placeholder - dictionary where key is input name, value is input value from user;
|
||||
"""
|
||||
from openvino.runtime import PartialShape
|
||||
model_inputs = input_model.get_inputs()
|
||||
input_user_data_types_dict = {}
|
||||
input_user_shapes_dict = {}
|
||||
|
||||
# input_user_shapes is list only if unnamed inputs were used
|
||||
if isinstance(input_user_shapes, list):
|
||||
|
||||
# this cycle adds each unnamed shape to dictionary using name from model_inputs
|
||||
for idx, shape in enumerate(input_user_shapes):
|
||||
assert isinstance(shape, PartialShape), "Got incorrect format of input shapes {}.".format(type(shape))
|
||||
|
||||
inp_name = find_first_unused_input(model_inputs, freeze_placeholder, input_user_shapes_dict, "shape")
|
||||
input_user_shapes_dict[inp_name] = shape
|
||||
else:
|
||||
input_user_shapes_dict = input_user_shapes
|
||||
|
||||
# input_user_data_types is list only if unnamed inputs were used
|
||||
if isinstance(input_user_data_types, list):
|
||||
from openvino.runtime import Type
|
||||
|
||||
if input_user_shapes_dict is None:
|
||||
input_user_shapes_dict = {}
|
||||
|
||||
# this cycle adds each unnamed type to dictionary using name from model_inputs
|
||||
for idx, node_type in enumerate(input_user_data_types):
|
||||
assert isinstance(node_type, (type, Type)), "Got incorrect format of input types. " \
|
||||
"Expected numpy type or openvino.runtime.Type, " \
|
||||
"got {}.".format(type(node_type))
|
||||
|
||||
inp_name = find_first_unused_input(model_inputs, freeze_placeholder, input_user_data_types_dict, "type")
|
||||
input_user_data_types_dict[inp_name] = node_type
|
||||
# FE postprocessing expects input_user_shapes_dict to always have shapes for corresponding types.
|
||||
# If shape is not set it is expected to have None shape in input_user_shapes_dict dictionary.
|
||||
if inp_name not in input_user_shapes_dict:
|
||||
input_user_shapes_dict[inp_name] = None
|
||||
else:
|
||||
input_user_data_types_dict = input_user_data_types
|
||||
|
||||
# unnamed_freeze_placeholders is always list, it is not empty only if unnamed inputs were used.
|
||||
for value in unnamed_freeze_placeholders:
|
||||
assert isinstance(value, list), "Got incorrect format of input values. " \
|
||||
"Expected list, " \
|
||||
"got {}.".format(type(value))
|
||||
inp_name = find_first_unused_input(model_inputs, freeze_placeholder, {}, "input value")
|
||||
freeze_placeholder[inp_name] = value
|
||||
|
||||
return input_user_shapes_dict, input_user_data_types_dict, freeze_placeholder
|
||||
|
||||
|
||||
def fe_user_data_repack(
|
||||
input_model: InputModel,
|
||||
input_user_shapes: [None, list, dict, np.array],
|
||||
|
||||
@@ -16,7 +16,7 @@ from openvino.runtime.utils.types import get_element_type, \
|
||||
get_numpy_ctype # pylint: disable=no-name-in-module,import-error
|
||||
from openvino.tools.mo.middle.passes.infer import validate_batch_in_shape
|
||||
from openvino.tools.mo.moc_frontend.analysis import json_model_analysis_dump
|
||||
from openvino.tools.mo.moc_frontend.extractor import fe_user_data_repack
|
||||
from openvino.tools.mo.moc_frontend.extractor import fe_user_data_repack, convert_params_lists_to_dicts
|
||||
from openvino.tools.mo.utils.class_registration import get_enabled_and_disabled_transforms
|
||||
from openvino.tools.mo.utils.error import Error
|
||||
|
||||
@@ -34,6 +34,10 @@ def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
|
||||
else:
|
||||
input_model = moc_front_end.load(argv.input_model)
|
||||
|
||||
argv.placeholder_shapes, argv.placeholder_data_types, argv.freeze_placeholder_with_value = convert_params_lists_to_dicts(
|
||||
input_model, argv.placeholder_shapes, argv.placeholder_data_types,
|
||||
argv.freeze_placeholder_with_value, argv.unnamed_freeze_placeholder_with_value)
|
||||
|
||||
user_shapes, outputs, freeze_placeholder = fe_user_data_repack(
|
||||
input_model, argv.placeholder_shapes, argv.placeholder_data_types,
|
||||
argv.output, argv.freeze_placeholder_with_value, moc_front_end.get_name())
|
||||
|
||||
@@ -21,7 +21,6 @@ from openvino.runtime import Layout, PartialShape, Dimension, Shape, Type
|
||||
import openvino
|
||||
from openvino.tools.mo.front.extractor import split_node_in_port
|
||||
from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
|
||||
from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
|
||||
from openvino.tools.mo.utils.error import Error
|
||||
from openvino.tools.mo.utils.utils import refer_to_faq_msg, get_mo_root_dir
|
||||
from openvino.tools.mo.utils.help import get_convert_model_help_specifics, get_to_string_methods_for_params
|
||||
@@ -122,52 +121,6 @@ def is_shape_type(value):
|
||||
return False
|
||||
|
||||
|
||||
def shape_to_str(shape, separator):
|
||||
if isinstance(shape, str):
|
||||
return shape
|
||||
if isinstance(shape, PartialShape):
|
||||
return shape.to_string()
|
||||
if isinstance(shape, Shape):
|
||||
return PartialShape(shape).to_string()
|
||||
if isinstance(shape, list) or isinstance(shape, tuple):
|
||||
dims = []
|
||||
for dim in shape:
|
||||
if isinstance(dim, Dimension):
|
||||
dims.append(dim.to_string())
|
||||
elif isinstance(dim, int):
|
||||
dims.append(str(dim))
|
||||
else:
|
||||
raise Exception("Incorrect type of dimension. Expected Dimension or int, got {}".format(type(dim)))
|
||||
return "[" + separator.join(dims) + "]"
|
||||
raise Exception("Incorrect shape type. Expected PartialShape, Shape, [Dimension, ...] or [int, ...], "
|
||||
"got {}".format(type(shape)))
|
||||
|
||||
|
||||
def input_shape_to_str(input_shape):
|
||||
if input_shape is None or isinstance(input_shape, str):
|
||||
return input_shape
|
||||
if isinstance(input_shape, list):
|
||||
if len(input_shape) > 0 and isinstance(input_shape[0], int) or isinstance(input_shape[0], Dimension):
|
||||
# The case when shape is specified as list of int or Dimension
|
||||
return shape_to_str(input_shape, ',')
|
||||
# The case when list of shapes is specified
|
||||
shapes = []
|
||||
for shape in input_shape:
|
||||
shapes.append(shape_to_str(shape, ','))
|
||||
return ','.join(shapes)
|
||||
return shape_to_str(input_shape, ',')
|
||||
|
||||
|
||||
def type_to_str(type_obj):
|
||||
if isinstance(type_obj, str):
|
||||
return type_obj
|
||||
if isinstance(type_obj, type):
|
||||
return np_data_type_to_destination_type(type_obj)
|
||||
if isinstance(type_obj, Type):
|
||||
return type_obj.get_type_name()
|
||||
raise Exception("Incorrect type. Expected Type or numpy type, got {}".format(type(type_obj)))
|
||||
|
||||
|
||||
def value_to_str(value, separator):
|
||||
if isinstance(value, np.ndarray):
|
||||
values = []
|
||||
@@ -186,22 +139,32 @@ def value_to_str(value, separator):
|
||||
raise Exception("Incorrect value type. Expected np.ndarray or list, got {}".format(type(value)))
|
||||
|
||||
|
||||
def single_input_to_str(input):
|
||||
def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type, type]):
|
||||
"""
|
||||
Parses parameters of single input to InputCutInfo.
|
||||
:param input: input cut parameters of single input
|
||||
:return: InputCutInfo
|
||||
"""
|
||||
if isinstance(input, str):
|
||||
return input
|
||||
# Parse params from string
|
||||
node_name, shape, value, data_type = parse_input_value(input)
|
||||
return openvino.tools.mo.InputCutInfo(node_name,
|
||||
PartialShape(shape) if shape is not None else None,
|
||||
data_type,
|
||||
value)
|
||||
if isinstance(input, openvino.tools.mo.InputCutInfo):
|
||||
if not isinstance(input.name, str):
|
||||
raise Exception("Input name should be string, got {}".format(input.name))
|
||||
input_str = input.name
|
||||
assert input_str is not None, "Incorrect InputCutInfo. 'name' should be set."
|
||||
if input.shape is not None:
|
||||
input_str += shape_to_str(input.shape, " ")
|
||||
if input.type is not None:
|
||||
input_str += "{" + type_to_str(input.type) + "}"
|
||||
if input.value is not None:
|
||||
input_str += "->" + value_to_str(input.value, " ")
|
||||
return input_str
|
||||
if isinstance(input, tuple):
|
||||
# Wrap input.shape to PartialShape if possible and wrap to InputCutInfo
|
||||
return openvino.tools.mo.InputCutInfo(input.name,
|
||||
PartialShape(input.shape) if input.shape is not None else None,
|
||||
input.type,
|
||||
input.value)
|
||||
if isinstance(input, (tuple, list, PartialShape)):
|
||||
# If input represents list with shape, wrap it to list. Single PartialShape also goes to this condition.
|
||||
# Check of all dimensions will be in is_shape_type(val) method below
|
||||
if len(input) > 0 and isinstance(input[0], (int, Dimension)):
|
||||
input = [input]
|
||||
|
||||
# Check values of tuple or list and collect to InputCutInfo
|
||||
name = None
|
||||
inp_type = None
|
||||
shape = None
|
||||
@@ -210,38 +173,147 @@ def single_input_to_str(input):
|
||||
if name is not None:
|
||||
raise Exception("More than one input name provided: {}".format(input))
|
||||
name = val
|
||||
elif isinstance(val, type) or isinstance(val, Type):
|
||||
elif isinstance(val, (type, Type)):
|
||||
if inp_type is not None:
|
||||
raise Exception("More than one input type provided: {}".format(input))
|
||||
inp_type = type_to_str(val)
|
||||
inp_type = val
|
||||
elif is_shape_type(val):
|
||||
if shape is not None:
|
||||
raise Exception("More than one input shape provided: {}".format(input))
|
||||
shape = shape_to_str(val, " ")
|
||||
shape = PartialShape(val)
|
||||
else:
|
||||
raise Exception("Incorrect input parameters provided. Expected input name and "
|
||||
"optionally input type or input shape. Got unknown object: {}".format(val))
|
||||
if name is None:
|
||||
raise Exception("Input name was not provided for following input {}.".format(input))
|
||||
if shape is not None:
|
||||
name += shape
|
||||
if inp_type is not None:
|
||||
name += "{" + inp_type + "}"
|
||||
return name
|
||||
raise Exception("Incorrect input parameters provided. Expected tuple with input name, "
|
||||
"input type or input shape. Got unknown object: {}".format(val))
|
||||
return openvino.tools.mo.InputCutInfo(name,
|
||||
PartialShape(shape) if shape is not None else None,
|
||||
inp_type,
|
||||
None)
|
||||
# Case when only type is set
|
||||
if isinstance(input, (type, Type)):
|
||||
return openvino.tools.mo.InputCutInfo(None, None, input, None)
|
||||
|
||||
# We don't expect here single unnamed value. If list of int is set it is considered as shape.
|
||||
# Setting of value is expected only using InputCutInfo or string analog.
|
||||
|
||||
raise Exception("Unexpected object provided for input. Expected openvino.tools.mo.InputCutInfo "
|
||||
"or tuple or str. Got {}".format(type(input)))
|
||||
|
||||
|
||||
def input_to_str(input):
|
||||
if input is None or isinstance(input, str):
|
||||
return input
|
||||
def input_to_input_cut_info(input: [str, tuple, list]):
|
||||
"""
|
||||
Parses 'input' to list of InputCutInfo.
|
||||
:param input: input cut parameters passed by user
|
||||
:return: list of InputCutInfo with input cut parameters
|
||||
"""
|
||||
if input is None:
|
||||
return []
|
||||
if isinstance(input, str):
|
||||
inputs = []
|
||||
# Split to list of string
|
||||
for input_value in split_inputs(input):
|
||||
|
||||
# Parse string with parameters for single input
|
||||
node_name, shape, value, data_type = parse_input_value(input_value)
|
||||
inputs.append(openvino.tools.mo.InputCutInfo(node_name,
|
||||
PartialShape(shape) if shape is not None else None,
|
||||
data_type,
|
||||
value))
|
||||
return inputs
|
||||
if isinstance(input, openvino.tools.mo.InputCutInfo):
|
||||
# Wrap to list and return
|
||||
return [input]
|
||||
if isinstance(input, tuple):
|
||||
# Case when input is single shape set in tuple
|
||||
if len(input) > 0 and isinstance(input[0], (int, Dimension)):
|
||||
input = [input]
|
||||
# Case when input is set as tuple. Expected that it is always single input.
|
||||
return [single_input_to_input_cut_info(input)]
|
||||
if isinstance(input, list):
|
||||
inputs_str = []
|
||||
# Case when input is single shape set in list
|
||||
if len(input) > 0 and isinstance(input[0], (int, Dimension)):
|
||||
input = [input]
|
||||
inputs = []
|
||||
# Case when input is set as list. Expected that it is list of params for different inputs.
|
||||
for inp in input:
|
||||
inputs_str.append(single_input_to_str(inp))
|
||||
return ','.join(inputs_str)
|
||||
return single_input_to_str(input)
|
||||
inputs.append(single_input_to_input_cut_info(inp))
|
||||
return inputs
|
||||
# Case when single type or value is set, or unknown object
|
||||
return [single_input_to_input_cut_info(input)]
|
||||
|
||||
|
||||
def input_shape_to_input_cut_info(input_shape: [str, Shape, PartialShape, list, tuple], inputs: list):
|
||||
"""
|
||||
Parses 'input_shape' to list of PartialShape and updates 'inputs'.
|
||||
:param input_shape: input shapes passed by user
|
||||
:param inputs: list of InputCutInfo with information from 'input' parameter
|
||||
"""
|
||||
if input_shape is None:
|
||||
return
|
||||
if isinstance(input_shape, str):
|
||||
# Split input_shape to list of string
|
||||
input_shape = split_shapes(input_shape)
|
||||
if isinstance(input_shape, (Shape, PartialShape)):
|
||||
# Whap single shape to list
|
||||
input_shape = [input_shape]
|
||||
if isinstance(input_shape, (list, tuple)):
|
||||
# Check case when single shape is passed as list or tuple
|
||||
if len(input_shape) > 0 and isinstance(input_shape[0], (int, Dimension)):
|
||||
input_shape = [input_shape]
|
||||
|
||||
if len(inputs) > 0 and len(input_shape) > 0:
|
||||
assert len(inputs) == len(input_shape), "Different numbers of inputs were specified in --input parameter " \
|
||||
"and --input_shapes. --input has {} items, --input_shape has {} item.".format(len(inputs), len(input_shape))
|
||||
|
||||
# Update inputs with information from 'input_shape'
|
||||
if len(inputs) > 0:
|
||||
for idx, shape in enumerate(input_shape):
|
||||
shape = PartialShape(shape)
|
||||
assert inputs[idx].shape is None, "Shape was set in both --input and in --input_shape parameter." \
|
||||
"Please use either --input or --input_shape for shape setting."
|
||||
inputs[idx] = openvino.tools.mo.InputCutInfo(inputs[idx].name, shape, inputs[idx].type, inputs[idx].value)
|
||||
|
||||
else:
|
||||
for shape in input_shape:
|
||||
inputs.append(openvino.tools.mo.InputCutInfo(None, PartialShape(shape), None, None))
|
||||
return
|
||||
|
||||
raise Exception("Unexpected object provided for input_shape. Expected PartialShape, Shape, tuple, list or str. "
|
||||
"Got {}".format(type(input_shape)))
|
||||
|
||||
|
||||
def freeze_placeholder_to_input_cut_info(argv_freeze_placeholder_with_value: str, inputs: list):
|
||||
"""
|
||||
Parses 'argv_freeze_placeholder_with_value' to dictionary and collects unnamed inputs from 'inputs' to list.
|
||||
:param argv_freeze_placeholder_with_value: string set by user.
|
||||
As it was planned to be deprecated no Python analogs were made.
|
||||
:param inputs: list of InputCutInfo with information from 'input' parameter
|
||||
:returns (placeholder_values, unnamed_placeholder_values), where
|
||||
placeholder_values - dictionary where key is node name, value is node value,
|
||||
unnamed_placeholder_values - list with unnamed node values
|
||||
"""
|
||||
# Parse argv_freeze_placeholder_with_value to dictionary with names and values
|
||||
placeholder_values = parse_freeze_placeholder_values(argv_freeze_placeholder_with_value)
|
||||
unnamed_placeholder_values = []
|
||||
|
||||
# Collect values for freezing from 'inputs'
|
||||
if inputs is not None and len(inputs) > 0:
|
||||
for input in inputs:
|
||||
node_name = input.name
|
||||
value = input.value
|
||||
if value is None:
|
||||
continue
|
||||
# Check for value conflict
|
||||
if node_name in placeholder_values and placeholder_values[node_name] != value:
|
||||
raise Error("Overriding replacement value of the placeholder with name '{}': old value = {}, new value = {}"
|
||||
".".format(node_name, placeholder_values[node_name], value))
|
||||
if node_name is not None:
|
||||
# Named input case, add to dictionary
|
||||
placeholder_values[node_name] = value
|
||||
else:
|
||||
# Unnamed input case, add to list
|
||||
unnamed_placeholder_values.append(value)
|
||||
|
||||
return placeholder_values, unnamed_placeholder_values
|
||||
|
||||
|
||||
def mean_scale_value_to_str(value):
|
||||
@@ -1329,6 +1401,30 @@ def get_layout_values(argv_layout: str = '', argv_source_layout: str = '', argv_
|
||||
return res_list
|
||||
|
||||
|
||||
def parse_freeze_placeholder_values(argv_freeze_placeholder_with_value: str):
|
||||
"""
|
||||
Parses parse_freeze_placeholder_values string.
|
||||
:param argv_freeze_placeholder_with_value: string information on freezing placeholders
|
||||
:return: dictionary where key is node name, value is node value.
|
||||
"""
|
||||
placeholder_values = {}
|
||||
if argv_freeze_placeholder_with_value is not None:
|
||||
for plh_with_value in argv_freeze_placeholder_with_value.split(','):
|
||||
plh_with_value = plh_with_value.split('->')
|
||||
if len(plh_with_value) != 2:
|
||||
raise Error("Wrong replacement syntax. Use --freeze_placeholder_with_value "
|
||||
"\"node1_name->value1,node2_name->value2\"")
|
||||
node_name = plh_with_value[0]
|
||||
value = plh_with_value[1]
|
||||
if node_name in placeholder_values and placeholder_values[node_name] != value:
|
||||
raise Error("Overriding replacement value of the placeholder with name '{}': old value = {}, new value = {}"
|
||||
".".format(node_name, placeholder_values[node_name], value))
|
||||
if '[' in value.strip(' '):
|
||||
value = value.replace('[', '').replace(']', '').split(' ')
|
||||
placeholder_values[node_name] = value
|
||||
return placeholder_values
|
||||
|
||||
|
||||
def get_freeze_placeholder_values(argv_input: str, argv_freeze_placeholder_with_value: str):
|
||||
"""
|
||||
Parses values for placeholder freezing and input node names
|
||||
@@ -1347,24 +1443,9 @@ def get_freeze_placeholder_values(argv_input: str, argv_freeze_placeholder_with_
|
||||
parsed placeholders with values for freezing
|
||||
input nodes cleaned from shape info
|
||||
"""
|
||||
placeholder_values = {}
|
||||
placeholder_values = parse_freeze_placeholder_values(argv_freeze_placeholder_with_value)
|
||||
input_node_names = None
|
||||
|
||||
if argv_freeze_placeholder_with_value is not None:
|
||||
for plh_with_value in argv_freeze_placeholder_with_value.split(','):
|
||||
plh_with_value = plh_with_value.split('->')
|
||||
if len(plh_with_value) != 2:
|
||||
raise Error("Wrong replacement syntax. Use --freeze_placeholder_with_value "
|
||||
"\"node1_name->value1,node2_name->value2\"")
|
||||
node_name = plh_with_value[0]
|
||||
value = plh_with_value[1]
|
||||
if node_name in placeholder_values and placeholder_values[node_name] != value:
|
||||
raise Error("Overriding replacement value of the placeholder with name '{}': old value = {}, new value = {}"
|
||||
".".format(node_name, placeholder_values[node_name], value))
|
||||
if '[' in value.strip(' '):
|
||||
value = value.replace('[', '').replace(']', '').split(' ')
|
||||
placeholder_values[node_name] = value
|
||||
|
||||
if argv_input is not None:
|
||||
input_node_names = ''
|
||||
# walkthrough all input values and save values for freezing
|
||||
@@ -1608,7 +1689,7 @@ def get_tuple_values(argv_values: str or tuple, num_exp_values: int = 3, t=float
|
||||
return mean_values_matches
|
||||
|
||||
|
||||
def get_mean_scale_dictionary(mean_values, scale_values, argv_input: str):
|
||||
def get_mean_scale_dictionary(mean_values, scale_values, argv_input: list):
|
||||
"""
|
||||
This function takes mean_values and scale_values, checks and processes them into convenient structure
|
||||
|
||||
@@ -1629,7 +1710,7 @@ def get_mean_scale_dictionary(mean_values, scale_values, argv_input: str):
|
||||
res = {}
|
||||
# collect input names
|
||||
if argv_input:
|
||||
inputs = [get_node_name_with_port_from_input_value(input_value) for input_value in split_inputs(argv_input)]
|
||||
inputs = [get_node_name_with_port_from_input_value(input_value) for input_value in split_inputs(argv_input)]
|
||||
else:
|
||||
inputs = []
|
||||
if type(mean_values) is dict:
|
||||
|
||||
@@ -143,13 +143,11 @@ def get_convert_model_help_specifics():
|
||||
|
||||
# TODO: remove this when internal converting of params to string is removed
|
||||
def get_to_string_methods_for_params():
|
||||
from openvino.tools.mo.utils.cli_parser import path_to_str_or_object, input_shape_to_str, str_list_to_str, \
|
||||
from openvino.tools.mo.utils.cli_parser import path_to_str_or_object, str_list_to_str, \
|
||||
mean_scale_value_to_str, source_target_layout_to_str, layout_param_to_str, transform_param_to_str, \
|
||||
extensions_to_str_or_extensions_class, batch_to_int, transformations_config_to_str, input_to_str
|
||||
extensions_to_str_or_extensions_class, batch_to_int, transformations_config_to_str
|
||||
return {
|
||||
'input_model': path_to_str_or_object,
|
||||
'input_shape': input_shape_to_str,
|
||||
'input': input_to_str,
|
||||
'output': str_list_to_str,
|
||||
'mean_values': mean_scale_value_to_str,
|
||||
'scale_values': mean_scale_value_to_str,
|
||||
|
||||
@@ -5,120 +5,12 @@ import numpy as np
|
||||
from openvino.runtime import Layout, PartialShape, Dimension, Shape, Type
|
||||
|
||||
from openvino.tools.mo import InputCutInfo, LayoutMap
|
||||
from openvino.tools.mo.utils.cli_parser import input_to_str, mean_scale_value_to_str, \
|
||||
transform_param_to_str, input_shape_to_str, str_list_to_str, source_target_layout_to_str, layout_param_to_str
|
||||
from openvino.tools.mo.utils.cli_parser import mean_scale_value_to_str, \
|
||||
transform_param_to_str, str_list_to_str, source_target_layout_to_str, layout_param_to_str
|
||||
from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
|
||||
|
||||
|
||||
class TestConvertingConvertArgumentsToString(UnitTestWithMockedTelemetry):
|
||||
def test_input_to_str(self):
|
||||
inp1 = InputCutInfo(name="data:0", shape=None, type=None, value=None)
|
||||
self.assertTrue(input_to_str(inp1) == "data:0")
|
||||
|
||||
inp2 = InputCutInfo("data:0", [1, 3, 100, 100], type=None, value=None)
|
||||
self.assertTrue(input_to_str(inp2) == "data:0[1 3 100 100]")
|
||||
|
||||
inp3 = InputCutInfo("data:0", type=np.int32, value=None, shape=None)
|
||||
self.assertTrue(input_to_str(inp3) == "data:0{i32}")
|
||||
|
||||
inp4 = InputCutInfo("data:0", value=[2, 4, 5], type=None, shape=None)
|
||||
self.assertTrue(input_to_str(inp4) == "data:0->[2 4 5]")
|
||||
|
||||
inp5 = InputCutInfo("data:0", [1, 3, 100, 100], np.uint8, value=None)
|
||||
self.assertTrue(input_to_str(inp5) == "data:0[1 3 100 100]{u8}")
|
||||
|
||||
inp6 = InputCutInfo("data:0", [2, 5, 7], value=[1, 2, 3, 4, 5], type=None)
|
||||
self.assertTrue(input_to_str(inp6) == "data:0[2 5 7]->[1 2 3 4 5]")
|
||||
|
||||
inp7 = InputCutInfo("0:data1", type=np.float64, value=[1.6, 7.2, 5.66], shape=None)
|
||||
self.assertTrue(input_to_str(inp7) == "0:data1{f64}->[1.6 7.2 5.66]")
|
||||
|
||||
inp8 = InputCutInfo("data2", [4, 5, 6], np.int64, [5, 4, 3, 2, 1])
|
||||
self.assertTrue(input_to_str(inp8) == "data2[4 5 6]{i64}->[5 4 3 2 1]")
|
||||
|
||||
inp9 = InputCutInfo("data", [1], bool, True)
|
||||
self.assertTrue(input_to_str(inp9) == "data[1]{boolean}->True")
|
||||
|
||||
inp = [inp6, inp7, inp8]
|
||||
self.assertTrue(input_to_str(inp) == "data:0[2 5 7]->[1 2 3 4 5],"
|
||||
"0:data1{f64}->[1.6 7.2 5.66],"
|
||||
"data2[4 5 6]{i64}->[5 4 3 2 1]")
|
||||
|
||||
inp = ["data:0[2 5 7]->[1 2 3 4 5]", "0:data1{f64}->[1.6 7.2 5.66]", "data2[4 5 6]{i64}->[5 4 3 2 1]"]
|
||||
self.assertTrue(input_to_str(inp) == "data:0[2 5 7]->[1 2 3 4 5],"
|
||||
"0:data1{f64}->[1.6 7.2 5.66],"
|
||||
"data2[4 5 6]{i64}->[5 4 3 2 1]")
|
||||
|
||||
inp9 = InputCutInfo("data1", PartialShape([Dimension(-1), Dimension(2, -1),
|
||||
Dimension(-1, 10), 100, Dimension(2, 12)]), type=None, value=None)
|
||||
self.assertTrue(input_to_str(inp9) == "data1[?,2..,..10,100,2..12]")
|
||||
|
||||
inp10 = InputCutInfo("data2", [Dimension(-1), Dimension(2, -1),
|
||||
Dimension(-1, 10), 100, Dimension(2, 12)], np.uint8, value=None)
|
||||
self.assertTrue(input_to_str(inp10) == "data2[? 2.. ..10 100 2..12]{u8}")
|
||||
|
||||
inp11 = InputCutInfo("data3", Shape([4, 5, 6]), np.int64, [5, 4, 3, 2, 1])
|
||||
self.assertTrue(input_to_str(inp11) == "data3[4,5,6]{i64}->[5 4 3 2 1]")
|
||||
|
||||
inp12 = InputCutInfo("data4", PartialShape.dynamic(), type=None, value=None)
|
||||
self.assertTrue(input_to_str(inp12) == "data4[...]")
|
||||
|
||||
inp = [inp9, inp10, inp11, inp12]
|
||||
self.assertTrue(input_to_str(inp) == "data1[?,2..,..10,100,2..12],"
|
||||
"data2[? 2.. ..10 100 2..12]{u8},"
|
||||
"data3[4,5,6]{i64}->[5 4 3 2 1],"
|
||||
"data4[...]")
|
||||
|
||||
inp1 = ("data:0")
|
||||
self.assertTrue(input_to_str(inp1) == "data:0")
|
||||
|
||||
inp2 = ([1, 3, 100, 100], "data:0")
|
||||
self.assertTrue(input_to_str(inp2) == "data:0[1 3 100 100]")
|
||||
|
||||
inp3 = ("data:0", np.int32)
|
||||
self.assertTrue(input_to_str(inp3) == "data:0{i32}")
|
||||
|
||||
inp4 = (np.uint8, [1, 3, 100, 100], "data:0")
|
||||
self.assertTrue(input_to_str(inp4) == "data:0[1 3 100 100]{u8}")
|
||||
|
||||
inp = [inp1, inp2, inp3, inp4]
|
||||
self.assertTrue(input_to_str(inp) == "data:0,"
|
||||
"data:0[1 3 100 100],"
|
||||
"data:0{i32},"
|
||||
"data:0[1 3 100 100]{u8}")
|
||||
|
||||
inp5 = ("data1", PartialShape([Dimension(-1), Dimension(2, -1), Dimension(-1, 10), 100, Dimension(2, 12)]))
|
||||
self.assertTrue(input_to_str(inp5) == "data1[?,2..,..10,100,2..12]")
|
||||
|
||||
inp6 = ("data2", [Dimension(-1), Dimension(2, -1), Dimension(-1, 10), 100, Dimension(2, 12)], np.uint8)
|
||||
self.assertTrue(input_to_str(inp6) == "data2[? 2.. ..10 100 2..12]{u8}")
|
||||
|
||||
inp7 = ("data3", Shape([4, 5, 6]), np.int64)
|
||||
self.assertTrue(input_to_str(inp7) == "data3[4,5,6]{i64}")
|
||||
|
||||
inp8 = ("data4", PartialShape.dynamic())
|
||||
self.assertTrue(input_to_str(inp8) == "data4[...]")
|
||||
|
||||
inp = [inp5, inp6, inp7, inp8]
|
||||
self.assertTrue(input_to_str(inp) == "data1[?,2..,..10,100,2..12],"
|
||||
"data2[? 2.. ..10 100 2..12]{u8},"
|
||||
"data3[4,5,6]{i64},"
|
||||
"data4[...]")
|
||||
|
||||
self.assertRaises(Exception, input_to_str, **{"input": InputCutInfo(0.5, [1, 2, 3], None, None)})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": InputCutInfo("name", 0.5, None, None)})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": InputCutInfo("name", [1, 2, 3], 0.5, None)})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": InputCutInfo("name", [1, 2, 3], None, int)})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": InputCutInfo("name", [1, 2, 3], None, int)})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ([2, 3], Shape([1, 2]))})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ("name", [int, 2, 3])})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ("name", "name1", [2, 3])})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ("name", [2, 3], Shape([1, 2]))})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ("name", int, Type(float))})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": Exception})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ("name", Exception)})
|
||||
self.assertRaises(Exception, input_to_str, **{"input": ("name", Dimension(1))})
|
||||
|
||||
def test_mean_scale_value_to_str(self):
|
||||
values = [0.5, 1.3, 0.67]
|
||||
self.assertTrue(mean_scale_value_to_str(values) == "[0.5,1.3,0.67]")
|
||||
@@ -164,32 +56,6 @@ class TestConvertingConvertArgumentsToString(UnitTestWithMockedTelemetry):
|
||||
{('a', 'b'): False})})
|
||||
self.assertRaises(Exception, transform_param_to_str, **{"value": Dimension(1)})
|
||||
|
||||
def test_input_shape_to_str(self):
|
||||
input_shape1 = [1, 3, 100, 100]
|
||||
self.assertTrue(input_shape_to_str(input_shape1) == "[1,3,100,100]")
|
||||
|
||||
input_shape2 = PartialShape([1, 3, 100, 100])
|
||||
self.assertTrue(input_shape_to_str(input_shape2) == "[1,3,100,100]")
|
||||
|
||||
input_shape3 = PartialShape([Dimension(-1), Dimension(2, -1), Dimension(-1, 10), 100, Dimension(2, 12)])
|
||||
self.assertTrue(input_shape_to_str(input_shape3) == "[?,2..,..10,100,2..12]")
|
||||
|
||||
input_shape4 = PartialShape.dynamic()
|
||||
self.assertTrue(input_shape_to_str(input_shape4) == "[...]")
|
||||
|
||||
input_shape5 = Shape([1, 2, 3, 4])
|
||||
self.assertTrue(input_shape_to_str(input_shape5) == "[1,2,3,4]")
|
||||
|
||||
input_shape6 = [Dimension(-1), Dimension(2, -1), Dimension(-1, 10), 100, Dimension(2, 12)]
|
||||
self.assertTrue(input_shape_to_str(input_shape6) == "[?,2..,..10,100,2..12]")
|
||||
|
||||
input_shape = [input_shape1, input_shape2, input_shape3, input_shape4, input_shape5, input_shape6]
|
||||
self.assertTrue(input_shape_to_str(input_shape) == "[1,3,100,100],[1,3,100,100],[?,2..,..10,100,2..12],"
|
||||
"[...],[1,2,3,4],[?,2..,..10,100,2..12]")
|
||||
|
||||
self.assertRaises(Exception, input_shape_to_str, **{"input_shape": [int, 1]})
|
||||
self.assertRaises(Exception, input_shape_to_str, **{"input_shape": Dimension(1)})
|
||||
|
||||
def test_str_list_to_str(self):
|
||||
list_str = ["data1", "data2", "data3"]
|
||||
self.assertTrue(str_list_to_str(list_str) == "data1,data2,data3")
|
||||
|
||||
@@ -1985,8 +1985,8 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
|
||||
assert argv.reverse_input_channels == args['reverse_input_channels']
|
||||
assert argv.scale == 0.5
|
||||
assert argv.batch == 1
|
||||
assert argv.input_shape == "[1,100,100,3],[2,3]"
|
||||
assert argv.input == "name,a[1 2 3]{f32}->[5 6 7]"
|
||||
assert argv.input_shape == [PartialShape([1,100,100,3]), [2,3]]
|
||||
assert argv.input == ['name', InputCutInfo("a", [1,2,3], numpy.float32, [5, 6, 7])]
|
||||
assert argv.output == "a,b,c"
|
||||
assert argv.mean_values == "[0.5,0.3]"
|
||||
assert argv.scale_values == "a[0.4],b[0.5,0.6]"
|
||||
@@ -1995,7 +1995,7 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
|
||||
assert argv.transform == "LowLatency2[use_const_initializer=False]"
|
||||
|
||||
for arg, value in vars(argv).items():
|
||||
if arg not in args:
|
||||
if arg not in args and arg != 'is_python_api_used':
|
||||
assert value == cli_parser.get_default(arg)
|
||||
|
||||
def test_not_existing_dir(self):
|
||||
|
||||
Reference in New Issue
Block a user