Removed InputCutInfo, disabled input cut in OVC. (#18927)

* Fixed output_model logic.

* Removed InputCutInfo, disabled input cut in ovc.

* Disabled output cut, added tests for setting shapes or types for not all inputs.

* Returned support of numpy type.

* Separated MO and OVC python API tests.

* Small corrections.

* Added output dir test, exceptions test.

* Tests fixed.

* Corrected extension param description.

* Corrected input description, minor code corrections.
This commit is contained in:
Anastasiia Pnevskaia authored and GitHub committed 2023-08-10 23:47:27 +04:00
1 parent 5f71679fb9
commit 59872ee072
39 files changed
+2883 -836

No files matched your search

+9
View File
@@ -551,6 +551,15 @@ jobs:
TEST_DEVICE: CPU
displayName: 'TensorFlow Lite Layer Tests - TFL FE'
- script: |
set -e
python3 -m pip install -r $(LAYER_TESTS_DIR)/requirements.txt
$(RUN_PREFIX) python3 -m pytest $(LAYER_TESTS_DIR)/ovc_python_api_tests/ --junitxml=./TEST-test_ovc_convert.xmlTEST
env:
PYTHONPATH: $(LAYER_TESTS_DIR)
TEST_DEVICE: CPU
displayName: 'OVC Python API Tests'
- script: |
set -e
python3 -m pip install -r $(LAYER_TESTS_DIR)/requirements.txt
+1 -1
View File
@@ -57,6 +57,6 @@ except ImportError:
# Tools
try:
# Model Conversion API - ovc should reside in the main namespace
from openvino.tools.ovc import convert_model, InputCutInfo
from openvino.tools.ovc import convert_model
except ImportError:
pass
@@ -53,7 +53,7 @@ class CommonMOConvertTest:
ir_ref = core.read_model(Path(temp_dir, 'model_ref.xml'))
flag, msg = compare_functions(ir_test, ir_ref)
assert flag, '\n'.join(msg)
assert flag, msg
def _test_by_ref_graph(self, temp_dir, test_params, ref_graph, compare_tensor_names=True, compare_layout=True):
"""
@@ -5,9 +5,8 @@ import numpy as np
import os
import pytest
from openvino.runtime import Model, Layout, PartialShape, Shape, layout_helpers, Type, Dimension
from openvino.tools.ovc import InputCutInfo
from openvino.tools.mo import LayoutMap
from openvino.tools.mo import LayoutMap, InputCutInfo
import openvino.runtime as ov
from common.mo_convert_test_class import CommonMOConvertTest
from common.tf_layer_test_class import save_to_pb
@@ -134,11 +133,11 @@ class TestComplexParams(CommonMOConvertTest):
{'params_test': {'input_shape': [PartialShape([2, 3, 4]),
[2, 3, 4],
[Dimension(2), Dimension(3), Dimension(4)]],
'input':['Input1', 'Input2', 'Relu3'], 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
'input':['Input1', 'Input2', 'Relu3'], 'compress_to_fp16': True},
'params_ref': {'input_shape': "[2,3,4],[2,3,4],[2,3,4]", 'input': 'Input1,Input2,Relu3'}},
{'params_test': {'input_shape': [PartialShape([Dimension(), Dimension(1, 3), Dimension(4, -1), Dimension(-1, 5)]),
[Dimension(), Dimension(1, 3), 4, Dimension(-1, 5)],
[Dimension(), 3, Dimension(4, -1), Dimension(-1, 5)]], 'use_convert_model_from_mo': True,
[Dimension(), 3, Dimension(4, -1), Dimension(-1, 5)]],
'compress_to_fp16': True,
'input':['Input1', 'Input2', 'Relu3']},
'params_ref': {'input_shape': "[?,1..3,4..,..5],[?,1..3,4,..5],[?,3,4..,..5]", 'input': 'Input1,Input2,Relu3'}},
@@ -153,32 +152,27 @@ class TestComplexParams(CommonMOConvertTest):
{'params_test': {'output': ["Sigmoid_0", "Sigmoid_2"]},
'params_ref': {'output': "Sigmoid_0,Sigmoid_2"}},
{'params_test': {'mean_values': {'Input1': [0.5,1.3,0.67], 'Input2':[4.2, 6.7, 3.15], 'Input3':[0.757, 4.6, 7.3]},
'use_convert_model_from_mo': True, 'compress_to_fp16': True},
'compress_to_fp16': True},
'params_ref': {'mean_values': "Input1[0.5,1.3,0.67],Input2[4.2,6.7,3.15],Input3[0.757,4.6,7.3]"}},
{'params_test': {
'mean_values': [[0.5, 1.3, 0.67], [4.2, 6.7, 3.15], [0.757, 4.6, 7.3]], 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
'mean_values': [[0.5, 1.3, 0.67], [4.2, 6.7, 3.15], [0.757, 4.6, 7.3]], 'compress_to_fp16': True},
'params_ref': {'mean_values': "[0.5,1.3,0.67],[4.2,6.7,3.15],[0.757,4.6,7.3]"}},
{'params_test': {'scale_values': {'Input1': [0.5,1.3,0.67], 'Input2':[4.2, 6.7, 3.15], 'Input3':[0.757, 4.6, 7.3]},
'use_convert_model_from_mo': True, 'compress_to_fp16': True},
'compress_to_fp16': True},
'params_ref': {'scale_values': "Input1[0.5,1.3,0.67],Input2[4.2,6.7,3.15],Input3[0.757,4.6,7.3]"}},
{'params_test': {
'scale_values': [[0.5, 1.3, 0.67], [4.2, 6.7, 3.15], [0.757, 4.6, 7.3]], 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
'scale_values': [[0.5, 1.3, 0.67], [4.2, 6.7, 3.15], [0.757, 4.6, 7.3]], 'compress_to_fp16': True},
'params_ref': {'scale_values': "[0.5,1.3,0.67],[4.2,6.7,3.15],[0.757,4.6,7.3]"}},
{'params_test': {
'source_layout': {'Input1': Layout("nchw"), 'Input2': "nchw", 'Input3': "nc??"}, 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
'source_layout': {'Input1': Layout("nchw"), 'Input2': "nchw", 'Input3': "nc??"}, 'compress_to_fp16': True},
'params_ref': {'source_layout': "Input1(nchw),Input2(nchw),Input3(nc??)"}},
{'params_test': {
'target_layout': {'Input1': Layout("nhwc"), 'Input2': "nhwc", 'Input3': "n??c"}, 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
'target_layout': {'Input1': Layout("nhwc"), 'Input2': "nhwc", 'Input3': "n??c"}, 'compress_to_fp16': True},
'params_ref': {'target_layout': "Input1(nhwc),Input2(nhwc),Input3(n??c)"}},
{'params_test': {
'layout': {'Input1': LayoutMap(source_layout=Layout("nchw"), target_layout="nhwc"),
'Input2': LayoutMap(source_layout="nc??", target_layout=Layout("n??c")),
'Input3': LayoutMap(source_layout="abcd", target_layout="acdb")}, 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
'Input3': LayoutMap(source_layout="abcd", target_layout="acdb")}, 'compress_to_fp16': True},
'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'}},
@@ -198,6 +192,7 @@ class TestComplexParams(CommonMOConvertTest):
test_params = params['params_test']
ref_params = params['params_ref']
test_params.update({'use_convert_model_from_mo': True})
test_params.update({'input_model': tf_net_path})
ref_params.update({'input_model': tf_net_path})
self._test(temp_dir, test_params, ref_params)
@@ -241,16 +236,13 @@ class TestComplexParams(CommonMOConvertTest):
# By default compress_to_fp16 in Python API is False but for mo cli tool (used for params_ref) it's True.
# compress_to_fp16 should be specified explicitly either in 'param_test' or 'params_ref' (or in both)
# Check all args combinations.
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'compress_to_fp16': True},
'params_ref': {'input_shape': "[2,3,4]"}},
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'use_convert_model_from_mo': True},
{'params_test': {'input_shape': PartialShape([2, 3, 4])},
'params_ref': {'input_shape': "[2,3,4]", 'compress_to_fp16': False}},
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'compress_to_fp16': True},
'params_ref': {'input_shape': "[2,3,4]", 'compress_to_fp16': True}},
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'use_convert_model_from_mo': True,
'compress_to_fp16': False},
{'params_test': {'input_shape': PartialShape([2, 3, 4]), 'compress_to_fp16': False},
'params_ref': {'input_shape': "[2,3,4]", 'compress_to_fp16': False}},
# ovc.convert_model with save_model are used, by default save_model compresses to fp16 same as cli tool.
@@ -266,8 +258,7 @@ class TestComplexParams(CommonMOConvertTest):
{'params_test': {'input': InputCutInfo("Relu", [3, 2], Type(np.int32), [1, 2, 3, 4, 5, 6]), 'compress_to_fp16': False},
'params_ref': {'input': "Relu[3 2]{i32}->[1 2 3 4 5 6]", 'compress_to_fp16': False}},
{'params_test': {'input_shape': [Dimension(), Dimension(1, 3), 4, Dimension(-1, 5)], 'use_convert_model_from_mo': True,
'compress_to_fp16': True},
{'params_test': {'input_shape': [Dimension(), Dimension(1, 3), 4, Dimension(-1, 5)], 'compress_to_fp16': True},
'params_ref': {'input_shape': "[?,1..3,4,..5]"}},
{'params_test': {'input': InputCutInfo("Relu", [3, 2], Type(np.int32), [1, 2, 3, 4, 5, 6])},
'params_ref': {'input': "Relu[3 2]{i32}->[1 2 3 4 5 6]"}},
@@ -279,18 +270,17 @@ class TestComplexParams(CommonMOConvertTest):
'params_ref': {'input': "Relu[3 2]"}},
{'params_test': {'input': ("Relu")},
'params_ref': {'input': "Relu"}},
{'params_test': {'mean_values': [0.5, 1.3, 0.67], 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'mean_values': [0.5, 1.3, 0.67], 'compress_to_fp16': True},
'params_ref': {'mean_values': "[0.5,1.3,0.67]"}},
{'params_test': {'scale_values': [0.5, 1.3, 0.67], 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'scale_values': [0.5, 1.3, 0.67], 'compress_to_fp16': True},
'params_ref': {'scale_values': "[0.5,1.3,0.67]"}},
{'params_test': {'source_layout': Layout("nchw"), 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'source_layout': Layout("nchw"), 'compress_to_fp16': True},
'params_ref': {'source_layout': "nchw"}},
{'params_test': {'target_layout': Layout("nchw"), 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'target_layout': Layout("nchw"), 'compress_to_fp16': True},
'params_ref': {'target_layout': "nchw"}},
{'params_test': {'layout': LayoutMap(source_layout=Layout("nchw"), target_layout="nhwc"),
'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'layout': LayoutMap(source_layout=Layout("nchw"), target_layout="nhwc"), 'compress_to_fp16': True},
'params_ref': {'layout': "nchw->nhwc"}},
{'params_test': {'layout': Layout("nchw"), 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'layout': Layout("nchw"), 'compress_to_fp16': True},
'params_ref': {'layout': "nchw"}},
{'params_test': {'input': [3, 2]},
'params_ref': {'input': "Input[3 2]"}},
@@ -306,13 +296,13 @@ class TestComplexParams(CommonMOConvertTest):
'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], 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'input_shape': [Dimension(3, 10), 10, -1], 'compress_to_fp16': True},
'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], 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'input': PartialShape([1, 100, 100, 3]), 'mean_values': [0.5, 1.3, 0.67], 'compress_to_fp16': True},
'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], 'use_convert_model_from_mo': True, 'compress_to_fp16': True},
{'params_test': {'input': [1, 100, 100, 3], 'scale_values': [0.5, 1.3, 0.67], 'compress_to_fp16': True},
'params_ref': {'input': "Input[1,100,100,3]", 'scale_values': "[0.5,1.3,0.67]"}},
]
@@ -325,6 +315,7 @@ class TestComplexParams(CommonMOConvertTest):
test_params = params['params_test']
ref_params = params['params_ref']
test_params.update({'use_convert_model_from_mo': True})
test_params.update({'input_model': tf_net_path})
ref_params.update({'input_model': tf_net_path})
self._test(temp_dir, test_params, ref_params)
@@ -102,9 +102,9 @@ class TestExtensions(CommonMOConvertTest):
return Model([sigmoid], [param], "test")
test_data = [
{'params_test': {'extension': create_custom_extension_leaky_relu_to_relu()},
{'params_test': {'extensions': create_custom_extension_leaky_relu_to_relu()},
'ref_graph': create_ref_graph1()},
{'params_test': {'extension': [create_custom_extension_leaky_relu_to_relu(),
{'params_test': {'extensions': [create_custom_extension_leaky_relu_to_relu(),
create_custom_extension_elu_to_sigmoid()]},
'ref_graph': create_ref_graph2()}
]
@@ -118,4 +118,5 @@ class TestExtensions(CommonMOConvertTest):
test_params = params['params_test']
test_params.update({'input_model': onnx_net_path})
test_params.update({'use_convert_model_from_mo': True})
self._test_by_ref_graph(temp_dir, test_params, params['ref_graph'])
@@ -49,9 +49,8 @@ def make_graph_proto_model():
def create_ref_model(shape):
param1 = ov.opset8.parameter(shape, dtype=np.float32)
slope_const = ov.opset8.constant([0.1], dtype=np.float16)
decompress_slope = ov.opset8.convert(slope_const, np.float32)
prelu = ov.opset8.prelu(param1, slope=decompress_slope)
slope_const = ov.opset8.constant([0.1], dtype=np.float32)
prelu = ov.opset8.prelu(param1, slope=slope_const)
relu = ov.opset8.elu(prelu, alpha=np.float32(0.1))
parameter_list = [param1]
return Model([relu], parameter_list, "test")
@@ -79,5 +78,6 @@ class TestMoConvertONNX(CommonMOConvertTest):
test_params = {'input_model': fw_model}
if mo_params is not None:
test_params.update(mo_params)
test_params.update({'use_convert_model_from_mo': True})
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
@@ -100,4 +100,5 @@ class TestMoConvertPaddle(CommonMOConvertTest):
test_params = {'input_model': fw_model, 'use_new_frontend': True}
if mo_params is not None:
test_params.update(mo_params)
test_params.update({'use_convert_model_from_mo': True})
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
@@ -11,7 +11,7 @@ import pytest
import torch
import unittest
from openvino.runtime import PartialShape, Dimension, Model, Type
from openvino.tools.ovc import InputCutInfo
from openvino.tools.mo import InputCutInfo
from common.mo_convert_test_class import CommonMOConvertTest
@@ -176,7 +176,7 @@ def create_pytorch_nn_module_with_scalar_input(tmp_dir):
sample_input2 = torch.zeros(1, 3, 10, 10)
sample_input = sample_input1, sample_input2
return pt_model, ref_model, {'input': ["[]", PartialShape([-1, 3, -1, -1])],
return pt_model, ref_model, {'input_shape': [PartialShape("[]"), PartialShape([-1, 3, -1, -1])],
'example_input': sample_input}
@@ -188,7 +188,7 @@ def create_pytorch_nn_module_case3(tmp_dir):
sample_input2 = torch.zeros(1, 3, 10, 10)
sample_input = tuple([sample_input1, sample_input2])
return pt_model, ref_model, {'input': "[?,3,?,?],[?,3,?,?]",
return pt_model, ref_model, {'input_shape': "[?,3,?,?],[?,3,?,?]",
'example_input': sample_input}
@@ -297,7 +297,8 @@ def create_pytorch_nn_module_layout_list(tmp_dir):
ref_model.inputs[1].node.layout = Layout('nhwc')
return pt_model, ref_model, {
'input': [(shape, np.float32), (shape, np.float32)], 'layout': ['nchw', Layout('nhwc')], 'use_convert_model_from_mo': True
'input': [(shape, np.float32), (shape, np.float32)], 'layout': ['nchw', Layout('nhwc')],
'use_convert_model_from_mo': True
}
@@ -312,7 +313,8 @@ def create_pytorch_nn_module_layout_list_case2(tmp_dir):
ref_model.inputs[1].node.layout = Layout('nhwc')
return pt_model, ref_model, {
'input': [(shape, np.float32), (shape, np.float32)], 'layout': ('nchw', Layout('nhwc')), 'use_convert_model_from_mo': True}
'input': [(shape, np.float32), (shape, np.float32)], 'layout': ('nchw', Layout('nhwc')),
'use_convert_model_from_mo': True}
def create_pytorch_nn_module_mean_list_compression_disabled(tmp_dir):
@@ -333,7 +335,8 @@ def create_pytorch_nn_module_mean_list_compression_disabled(tmp_dir):
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], 'mean_values': [[0, 0, 0], [0, 0, 0]],
return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)],
'mean_values': [[0, 0, 0], [0, 0, 0]],
'compress_to_fp16': False, 'use_convert_model_from_mo': True}
@@ -357,7 +360,8 @@ def create_pytorch_nn_module_mean_list_compression_default(tmp_dir):
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], 'mean_values': [[0, 0, 0], [0, 0, 0]],
return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)],
'mean_values': [[0, 0, 0], [0, 0, 0]],
'use_convert_model_from_mo': True}
@@ -607,7 +611,8 @@ def create_pytorch_nn_module_convert_pytorch_frontend4(tmp_dir):
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return pt_model, ref_model, {
"example_input": {"x": torch.zeros((1, 3, 10, 10), dtype=torch.float32), "y": torch.ones((1, 3, 10, 10), dtype=torch.float32)},
"example_input": {"x": torch.zeros((1, 3, 10, 10), dtype=torch.float32),
"y": torch.ones((1, 3, 10, 10), dtype=torch.float32)},
'input': [InputCutInfo(shape=[-1, -1, -1, -1], type="f32"), InputCutInfo(shape=[-1, -1, -1, -1], type="f32")]
}
@@ -626,7 +631,7 @@ def create_pytorch_jit_script_module_convert_pytorch_frontend(tmp_dir):
sigm = ov.opset10.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return scripted_model, ref_model, {
return scripted_model, ref_model, {
"example_input": [torch.zeros((1, 3, 10, 10)), torch.ones((1, 3, 10, 10))]}
@@ -645,7 +650,7 @@ def create_pytorch_jit_trace_module_convert_pytorch_frontend(tmp_dir):
sigm = ov.opset10.sigmoid(relu)
parameter_list = [param1, param2]
ref_model = Model([sigm], parameter_list, "test")
return scripted_model, ref_model, {"example_input": example_input}
return scripted_model, ref_model, {"example_input": example_input}
def create_pytorch_module_convert_pytorch_frontend_oob(tmp_dir):
@@ -663,9 +668,8 @@ def create_pytorch_module_convert_pytorch_frontend_oob(tmp_dir):
net = ConvModel()
shape = PartialShape([-1, 3, -1, -1])
param1 = ov.opset10.parameter(shape, dtype=np.float32)
weights = ov.opset10.constant(net.weights.numpy(force=True), dtype=np.float16)
decompress_weights = ov.opset10.convert(weights, np.float32)
conv = ov.opset10.convolution(param1, decompress_weights, strides=[1, 1],
weights = ov.opset10.constant(net.weights.numpy(force=True), dtype=np.float32)
conv = ov.opset10.convolution(param1, weights, strides=[1, 1],
pads_begin=[0, 0], pads_end=[0, 0],
dilations=[1, 1])
parameter_list = [param1]
@@ -723,17 +727,15 @@ def create_pytorch_module_with_compressed_int8_constant_compress_to_fp16_default
param1 = ov.opset10.parameter(shape, dtype=np.float32)
weights = ov.opset10.constant(net.weights.numpy(force=True))
cast1 = ov.opset10.convert(weights, np.float32)
sub1_const = np.float16(0.5).reshape(1, 1, 1, 1)
mul1_const = np.float16(0.02).reshape(1, 1, 1, 1)
sub1_const_decompress = ov.opset10.convert(sub1_const, np.float32)
mul1_const_decompress = ov.opset10.convert(mul1_const, np.float32)
sub1 = ov.opset10.subtract(cast1, sub1_const_decompress)
mul1 = ov.opset10.multiply(sub1, mul1_const_decompress)
sub1_const = np.float32(0.5).reshape(1, 1, 1, 1)
mul1_const = np.float32(0.02).reshape(1, 1, 1, 1)
sub1 = ov.opset10.subtract(cast1, sub1_const)
mul1 = ov.opset10.multiply(sub1, mul1_const)
conv = ov.opset10.convolution(param1, mul1, strides=[1, 1],
pads_begin=[0, 0], pads_end=[0, 0],
dilations=[1, 1])
ref_model = Model([conv], [param1], "test")
return traced_model, ref_model, {"example_input": example_input}
return traced_model, ref_model, {"example_input": example_input}
def create_pytorch_module_with_compressed_int8_constant(tmp_dir):
@@ -766,17 +768,17 @@ def create_pytorch_module_with_compressed_int8_constant(tmp_dir):
pads_begin=[0, 0], pads_end=[0, 0],
dilations=[1, 1])
ref_model = Model([conv], [param1], "test")
return traced_model, ref_model, {"example_input": example_input, "compress_to_fp16": False}
return traced_model, ref_model, {"example_input": example_input, "compress_to_fp16": False}
def create_pytorch_module_with_nested_inputs(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, z:Tuple[torch.Tensor, torch.Tensor]):
def forward(self, z: Tuple[torch.Tensor, torch.Tensor]):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
return torch.cat([z1, zeros1], 1), torch.cat([z2, zeros2], 2)
return torch.cat([z1, zeros1], 1), torch.cat([z2, zeros2], 2)
net = PTModel()
constant_zeros1 = ov.opset10.constant(np.zeros((1, 1), dtype=np.float32), dtype=np.float32)
@@ -795,7 +797,7 @@ def create_pytorch_module_with_nested_inputs(tmp_dir):
def create_pytorch_module_with_nested_inputs_compress_to_fp16_default(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, z:Tuple[torch.Tensor, torch.Tensor]):
def forward(self, z: Tuple[torch.Tensor, torch.Tensor]):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
@@ -818,12 +820,12 @@ def create_pytorch_module_with_nested_inputs_compress_to_fp16_default(tmp_dir):
def create_pytorch_module_with_nested_inputs2(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, x:torch.Tensor, z:Tuple[torch.Tensor, torch.Tensor]):
def forward(self, x: torch.Tensor, z: Tuple[torch.Tensor, torch.Tensor]):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2)
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2)
net = PTModel()
constant_zeros1 = ov.opset10.constant(np.zeros((1, 1), dtype=np.float32), dtype=np.float32)
@@ -837,18 +839,19 @@ def create_pytorch_module_with_nested_inputs2(tmp_dir):
concat2 = ov.opset10.concat([param2, constant_zeros2], 2)
add = ov.opset10.add(concat1, param0)
ref_model = Model([concat2, add], [param0, param1, param2], "test")
return net, ref_model, {"example_input": {"x": torch.ones((1, 10)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 5)))},
"compress_to_fp16": False}
return net, ref_model, {
"example_input": {"x": torch.ones((1, 10)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 5)))},
"compress_to_fp16": False}
def create_pytorch_module_with_nested_inputs3(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, z:Tuple[torch.Tensor, torch.Tensor], x:torch.Tensor):
def forward(self, z: Tuple[torch.Tensor, torch.Tensor], x: torch.Tensor):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2)
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2)
net = PTModel()
shape1 = PartialShape([1, -1])
@@ -862,18 +865,19 @@ def create_pytorch_module_with_nested_inputs3(tmp_dir):
concat2 = ov.opset10.concat([param2, constant_zeros2], 2)
add = ov.opset10.add(concat1, param3)
ref_model = Model([concat2, add], [param1, param2, param3], "test")
return net, ref_model, {"example_input": {"x": torch.ones((1, 10)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 3)))},
"compress_to_fp16": False}
return net, ref_model, {
"example_input": {"x": torch.ones((1, 10)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 3)))},
"compress_to_fp16": False}
def create_pytorch_module_with_nested_inputs4(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, x:torch.Tensor, z:Tuple[torch.Tensor, torch.Tensor], y:torch.Tensor):
def forward(self, x: torch.Tensor, z: Tuple[torch.Tensor, torch.Tensor], y: torch.Tensor):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2) * y
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2) * y
net = PTModel()
constant_zeros1 = ov.opset10.constant(np.zeros((1, 1), dtype=np.float32), dtype=np.float32)
@@ -889,18 +893,20 @@ def create_pytorch_module_with_nested_inputs4(tmp_dir):
add = ov.opset10.add(concat1, param3)
mul = ov.opset10.multiply(concat2, param4)
ref_model = Model([mul, add], [param3, param1, param2, param4], "test")
return net, ref_model, {"example_input": {"x": torch.ones((1, 10)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 10))), "y": torch.ones((1,))},
"compress_to_fp16": False}
return net, ref_model, {
"example_input": {"x": torch.ones((1, 10)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 10))),
"y": torch.ones((1,))},
"compress_to_fp16": False}
def create_pytorch_module_with_nested_inputs5(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, x:torch.Tensor, z:Tuple[torch.Tensor, torch.Tensor], y:torch.Tensor):
def forward(self, x: torch.Tensor, z: Tuple[torch.Tensor, torch.Tensor], y: torch.Tensor):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2) * y
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2) * y
net = PTModel()
constant_zeros1 = ov.opset10.constant(np.zeros((1, 1), dtype=np.float32), dtype=np.float32)
@@ -916,19 +922,20 @@ def create_pytorch_module_with_nested_inputs5(tmp_dir):
add = ov.opset10.add(concat1, param0)
mul = ov.opset10.multiply(concat2, param4)
ref_model = Model([mul, add], [param0, param1, param2, param4], "test")
return net, ref_model, {"example_input": [torch.ones((1, 10)), (torch.zeros((1, 10)), torch.ones((1, 5, 10))), torch.ones((1,))],
"compress_to_fp16": False}
return net, ref_model, {
"example_input": [torch.ones((1, 10)), (torch.zeros((1, 10)), torch.ones((1, 5, 10))), torch.ones((1,))],
"compress_to_fp16": False}
def create_pytorch_module_with_nested_inputs6(tmp_dir):
class PTModel(torch.nn.Module):
def forward(self, x:torch.Tensor, y:torch.Tensor=None, z:Tuple[torch.Tensor, torch.Tensor]=None):
def forward(self, x: torch.Tensor, y: torch.Tensor = None, z: Tuple[torch.Tensor, torch.Tensor] = None):
z1, z2 = z
zeros1 = torch.zeros((1, 1))
zeros2 = torch.zeros((1, 5, 1))
if y is not None:
return torch.cat([z1, zeros1], 1) * y, torch.cat([z2, zeros2], 2) * y
return torch.cat([z1, zeros1], 1) * y, torch.cat([z2, zeros2], 2) * y
return torch.cat([z1, zeros1], 1) + x, torch.cat([z2, zeros2], 2)
net = PTModel()
@@ -943,8 +950,9 @@ def create_pytorch_module_with_nested_inputs6(tmp_dir):
concat2 = ov.opset10.concat([param2, constant_zeros2], 2)
add1 = ov.opset10.add(concat1, param0)
ref_model = Model([concat2, add1], [param0, param1, param2], "test")
return net, ref_model, {"example_input": {"x": torch.ones((1, 11)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 10)))},
"compress_to_fp16": False}
return net, ref_model, {
"example_input": {"x": torch.ones((1, 11)), "z": (torch.zeros((1, 10)), torch.ones((1, 5, 10)))},
"compress_to_fp16": False}
class TestMoConvertPyTorch(CommonMOConvertTest):
@@ -998,14 +1006,15 @@ class TestMoConvertPyTorch(CommonMOConvertTest):
create_pytorch_module_with_nested_inputs6
]
@ pytest.mark.parametrize("create_model", test_data)
@ pytest.mark.nightly
@ pytest.mark.precommit
@pytest.mark.parametrize("create_model", test_data)
@pytest.mark.nightly
@pytest.mark.precommit
def test_mo_import_from_memory(self, create_model, ie_device, precision, ir_version,
temp_dir, use_new_frontend, use_old_api):
fw_model, graph_ref, mo_params = create_model(temp_dir)
test_params = {'input_model': fw_model}
test_params.update({'use_convert_model_from_mo': True})
if mo_params is not None:
test_params.update(mo_params)
self._test_by_ref_graph(temp_dir, test_params,
@@ -1089,11 +1098,11 @@ def create_pt_model_with_custom_op():
class ConvertRaises(unittest.TestCase):
def test_example_inputs(self):
from openvino.tools.ovc import convert_model
from openvino.tools.mo import convert_model
pytorch_model = create_pt_model_with_custom_op()
# Check that mo raises error message of wrong argument.
with self.assertRaisesRegex(TypeError, ".*got an unexpected keyword argument 'example_inputs'.*"):
with self.assertRaisesRegex(AssertionError, ".*'example_inputs' argument is not recognized.*"):
convert_model(pytorch_model, example_inputs=(torch.tensor(1),))
def test_failed_extension(self):
@@ -1109,7 +1118,7 @@ class ConvertRaises(unittest.TestCase):
# Check that mo raises error message of wrong argument.
with self.assertRaisesRegex(Exception, ".*Conversion is failed for: aten::relu.*"):
convert_model(pt_model, input=(inp_shapes, np.float32), extensions=[
ConversionExtension("aten::relu", relu_bad)])
ConversionExtension("aten::relu", relu_bad)])
def test_failed_extension(self):
import tempfile
@@ -377,8 +377,8 @@ def create_tf_stateful_partioned_call_net(temp_dir):
param1 = ov.opset8.parameter(data_shape, dtype=np.float32)
param2 = ov.opset8.parameter(filters_shape, dtype=np.float32)
reshape = ov.opset8.reshape(param2, np.array([1, 1, 3, 3], dtype=np.int64), True)
conv = ov.opset11.convolution(param1, reshape, strides, pads_begin, pads_end, dilations, auto_pad="same_upper")
transpose2 = ov.opset8.transpose(param2, np.array([3, 2, 0, 1], dtype=np.int64))
conv = ov.opset11.convolution(param1, transpose2, strides, pads_begin, pads_end, dilations, auto_pad="same_upper")
parameter_list = [param1, param2]
model_ref = Model([conv], parameter_list, "test")
@@ -577,7 +577,7 @@ def create_keras_layer_with_tf_function_call_default_compressed_to_fp16(tmp_dir)
sigm = tf.nn.sigmoid(input1) + input2
return sigm * self.var1
model = LayerModel()
model_ref = two_params_function_reference_fp16_compressed([[1, 2], [1, 2]], [[5.0]])
model_ref = two_params_function_reference([[1, 2], [1, 2]], [[5.0]])
return model, model_ref, {}
@@ -656,9 +656,10 @@ def shape_of_const_fold_test(temp_dir):
# Ref model
param1 = ov.opset8.parameter(PartialShape([1, 4, 10, 10]))
mul_const = ov.opset8.constant([[[[4]]]], dtype=np.float16)
cast = ov.opset8.convert(mul_const, np.float32)
mul = ov.opset8.multiply(cast, param1)
shape_const = ov.opset8.constant([1, 4, 10, 10], dtype=np.int32)
reshape = ov.opset8.reshape(param1, shape_const, False)
mul_const = ov.opset8.constant([[[[4]]]], dtype=np.float32)
mul = ov.opset8.multiply(mul_const, reshape)
parameter_list = [param1]
model_ref = Model([mul], parameter_list, "test")
@@ -781,6 +782,7 @@ class TestMoConvertTF(CommonMOConvertTest):
fw_model, graph_ref, mo_params = create_model(temp_dir)
test_params = {'input_model': fw_model}
test_params.update({'use_convert_model_from_mo': True})
if mo_params is not None:
test_params.update(mo_params)
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
@@ -791,6 +793,7 @@ class TestMoConvertTF(CommonMOConvertTest):
saved_model_dir, graph_ref = create_tf_saved_model_dir(temp_dir)
test_params = {'input_model': saved_model_dir}
test_params.update({'use_convert_model_from_mo': True})
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
test_params = {'input_model': saved_model_dir}
@@ -798,7 +801,7 @@ class TestMoConvertTF(CommonMOConvertTest):
def test_zero_copy(self, ie_device, precision, ir_version, temp_dir):
import tensorflow as tf
from openvino.tools.ovc import convert_model
from openvino.tools.mo import convert_model
from openvino.runtime import compile_model
class LayerModel(tf.Module):
def __init__(self):
@@ -845,62 +848,13 @@ class TestMoConvertTF(CommonMOConvertTest):
assert np.array_equal(ov_infer2['Identity:0'], fw_infer2)
assert np.array_equal(ov_infer2['Identity:0'], [ 0., 8., 16.])
def test_turn_off_sharing(self, ie_device, precision, ir_version, temp_dir):
import tensorflow as tf
from openvino.tools.ovc import convert_model
from openvino.runtime import compile_model
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable([7., 5., 6.], name='var1')
self.var2 = tf.Variable([5., 7., 3.], name='var2')
@tf.function
def sub_function(self, input):
return input * self.var1 + self.var2
@tf.function()
def __call__(self, input):
return self.sub_function(input)
# Create TF model with variables
keras_model = LayerModel()
test_input = np.array(7.).astype(np.float32)
# Convert model to OV
ov_model = convert_model(keras_model, input=[1], share_weights=False)
cmp_model = compile_model(ov_model)
# Check model inference
ov_infer1 = cmp_model(test_input, ie_device)
fw_infer1 = keras_model(test_input).numpy()
assert np.array_equal(ov_infer1['Identity:0'], fw_infer1)
assert np.array_equal(ov_infer1['Identity:0'], [54., 42., 45.])
# Change value of variables in original model
for val in keras_model.variables:
arr = val.value().__array__()
arr[0] = 0
arr[1] = 1
arr[2] = 2
# Check model inference
ov_infer2 = cmp_model(test_input)
fw_infer2 = keras_model(test_input).numpy()
# Check model inference calculated with old constant values
assert not np.array_equal(ov_infer2['Identity:0'], fw_infer2)
assert np.array_equal(ov_infer2['Identity:0'], [54., 42., 45.])
def test_memory_loss(self, ie_device, precision, ir_version, temp_dir):
# This test checks that the memory allocated for constants
# is not lost after returning the model from convert_model() method.
import tensorflow as tf
tf.compat.v1.reset_default_graph()
from openvino.tools.ovc import convert_model
from openvino.tools.mo import convert_model
from openvino.runtime import compile_model
import gc
@@ -955,7 +909,7 @@ class TFConvertTest(unittest.TestCase):
@pytest.mark.precommit
def test_tf_function_no_signature(self):
import tensorflow as tf
from openvino.tools.ovc import convert_model
from openvino.tools.mo import convert_model
@tf.function()
def function(x1, x2):
@@ -5,9 +5,8 @@
import os
import sys
import unittest
from openvino.tools.ovc import ovc
from openvino.tools.ovc.cli_parser import get_mo_convert_params
from openvino.tools.mo.utils.cli_parser import get_mo_convert_params as legacy_mo_params
from openvino.tools.mo import mo
from openvino.tools.mo.utils.cli_parser import get_mo_convert_params
from pathlib import Path
from common.utils.common_utils import shell
@@ -17,8 +16,8 @@ class TestSubprocessMoConvert(unittest.TestCase):
def test_mo_convert(self):
mo_convert_params = get_mo_convert_params()
# Test ovc tool help
mo_path = Path(ovc.__file__).parent
# Test mo tool help
mo_path = Path(mo.__file__).parent
mo_runner = mo_path.joinpath('main.py').as_posix()
params = [sys.executable, mo_runner, "--help"]
_, mo_output, _ = shell(params)
@@ -35,7 +34,7 @@ class TestSubprocessMoConvert(unittest.TestCase):
params = [sys.executable, mo_help_file]
_, mo_output, _ = shell(params)
legacy_params = legacy_mo_params()
legacy_params = get_mo_convert_params()
for group in legacy_params:
for param_name in group:
assert param_name in mo_output
@@ -0,0 +1,13 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import inspect
from common.layer_test_class import get_params
def pytest_generate_tests(metafunc):
test_gen_attrs_names = list(inspect.signature(get_params).parameters)
params = get_params()
metafunc.parametrize(test_gen_attrs_names, params, scope="function")
@@ -0,0 +1,167 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import numpy as np
import openvino.runtime as ov
import os
import pytest
import tempfile
import unittest
from openvino.runtime import Model, Layout, PartialShape, Shape, layout_helpers, Type, Dimension
from common.mo_convert_test_class import CommonMOConvertTest
from common.tf_layer_test_class import save_to_pb
class TestComplexParams(CommonMOConvertTest):
@staticmethod
def create_tf_model(tmp_dir):
#
# Create Tensorflow model with multiple inputs/outputs
#
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.float32, [1, 3, 2, 2], 'Input3')
relu1 = tf.nn.relu(inp1, name='Relu1')
relu2 = tf.nn.relu(inp2, name='Relu2')
relu3 = tf.nn.relu(inp3, name='Relu3')
concat = tf.concat([relu1, relu2, relu3], axis=0, name='Concat')
outputs = tf.split(concat, 3)
outputs_list = []
for i, output in enumerate(outputs):
outputs_list.append(tf.nn.sigmoid(output, name='Sigmoid_{}'.format(i)))
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)
@staticmethod
def create_tf_model_single_input_output(tmp_dir):
#
# Create Tensorflow model with single input/output
#
import tensorflow as tf
tf.compat.v1.reset_default_graph()
with tf.compat.v1.Session() as sess:
inp = tf.compat.v1.placeholder(tf.float32, [1, 3, 2, 2], 'Input')
relu = tf.nn.relu(inp, name='Relu')
output = tf.nn.sigmoid(relu, name='Sigmoid')
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)
test_data = [
{'params_test': {'output': ["Sigmoid_0", "Sigmoid_2"]},
'params_ref': {'output': "Sigmoid_0,Sigmoid_2"}},
{'params_test': {'output': ["Sigmoid_0"]},
'params_ref': {'output': "Sigmoid_0"}},
{'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': [PartialShape([1, 3, -1, -1]), [1, 3, -1, -1]]},
'params_ref': {'input_shape': "[1,3,?,?],[1,3,?,?]", 'input': 'Input1,Input2'}},
{'params_test': {'input': [(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': {"Input1": PartialShape([2, 3, 4]), "Input2": [2, 3, 4],
"Input3": [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': {"Input2": [1, -1, -1, -1],
"Input3": [Dimension(1), Dimension(-1), Dimension(-1), Dimension(-1)]}},
'params_ref': {'input_shape': "[1,?,?,?],[1,?,?,?]", 'input': 'Input2,Input3'}},
{'params_test': {'input': [np.int32, Type(np.int32), np.int32]},
'params_ref': {'input': 'Input1{i32},Input2{i32},Input3{i32}'}},
{'params_test': {'input': [ov.Type.f32, ov.Type.f32]},
'params_ref': {'input': 'Input1{f32},Input2{f32}'}},
{'params_test': {'input': [([1, 3, -1, -1], ov.Type.i32), ov.Type.i32, ov.Type.i32]},
'params_ref': {'input': 'Input1[1,3,?,?]{i32},Input2{i32},Input3{i32}'}}
]
@pytest.mark.parametrize("params", test_data)
@pytest.mark.nightly
def test_mo_convert_tf_model(self, params, ie_device, precision, ir_version,
temp_dir, use_new_frontend, use_old_api):
tf_net_path = self.create_tf_model(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': {"Input": ([3, 2], ov.Type.i32)}},
'params_ref': {'input': "Input[3,2]{i32}"}},
{'params_test': {'input': {"Input": ov.Type.i32}},
'params_ref': {'input': "Input{i32}"}},
{'params_test': {'input': {"Input": [3, 2]}},
'params_ref': {'input': "Input[3,2]"}},
{'params_test': {'input': (3, 2)},
'params_ref': {'input': "Input[3,2]"}},
{'params_test': {'input': (3, Dimension(2))},
'params_ref': {'input': "Input[3,2]"}},
{'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': (np.int32, [1, 2, 3])},
'params_ref': {'input': "Input[1,2,3]{i32}"}},
{'params_test': {'input': [Dimension(3, 10), 10, -1]},
'params_ref': {'input': 'Input[3..10,10,?]'}},
]
@pytest.mark.parametrize("params", test_data)
@pytest.mark.nightly
@pytest.mark.precommit
def test_mo_convert_tf_model_single_input_output(self, params, ie_device, precision, ir_version,
temp_dir, use_new_frontend, use_old_api):
tf_net_path = self.create_tf_model_single_input_output(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)
class NegativeCases(unittest.TestCase):
test_directory = os.path.dirname(os.path.realpath(__file__))
def test_input_output_cut_exceptions(self):
from openvino.tools.ovc import convert_model
with tempfile.TemporaryDirectory(dir=self.test_directory) as temp_dir:
tf_net_path = TestComplexParams.create_tf_model_single_input_output(temp_dir)
with self.assertRaisesRegex(Exception, ".*Name Relu is not found among model inputs.*"):
convert_model(tf_net_path, input='Relu')
with self.assertRaisesRegex(Exception, ".*Name Relu is not found among model outputs.*"):
convert_model(tf_net_path, output='Relu')
tf_net_path = TestComplexParams.create_tf_model(temp_dir)
with self.assertRaisesRegex(Exception, ".*Name Relu2 is not found among model inputs.*"):
convert_model(tf_net_path, input='Relu2')
with self.assertRaisesRegex(Exception, ".*Name Relu2 is not found among model outputs.*"):
convert_model(tf_net_path, output='Relu2')
@@ -0,0 +1,121 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import pytest
import numpy as np
from common.mo_convert_test_class import CommonMOConvertTest
from common.onnx_layer_test_class import save_to_onnx
import openvino.runtime as ov
from openvino.runtime import PartialShape, Model
class TestExtensions(CommonMOConvertTest):
def create_onnx_model(self, tmp_dir):
#
# Create ONNX model
#
import onnx
from onnx import helper
from onnx import TensorProto
shape = [2, 3, 4]
input = helper.make_tensor_value_info('input', TensorProto.FLOAT, shape)
output = helper.make_tensor_value_info('output', TensorProto.FLOAT, shape)
node_def = onnx.helper.make_node(
'LeakyRelu',
inputs=['input'],
outputs=['LeakyRelu_data'],
alpha=0.1
)
node_def2 = onnx.helper.make_node(
'Elu',
inputs=['LeakyRelu_data'],
outputs=['output'],
alpha=0.1
)
# Create the graph (GraphProto)
graph_def = helper.make_graph(
[node_def, node_def2],
'test_model',
[input],
[output],
)
# Create the model (ModelProto)
onnx_net = helper.make_model(graph_def, producer_name='test_model')
# save model to .onnx and return path to the model
return save_to_onnx(onnx_net, tmp_dir)
def create_custom_extension_leaky_relu_to_relu():
# replaces LeakyRelu with Relu
from openvino.frontend import ConversionExtension
from openvino.frontend import NodeContext
import openvino.runtime.opset8 as ops
def custom_converter(node: NodeContext):
input = node.get_input(0)
relu = ops.relu(input)
return [relu.output(0)]
return ConversionExtension("LeakyRelu", custom_converter)
def create_custom_extension_elu_to_sigmoid():
# replaces Elu with Sigmoid
from openvino.frontend import ConversionExtension
from openvino.frontend import NodeContext
import openvino.runtime.opset8 as ops
def custom_converter(node: NodeContext):
input = node.get_input(0)
sigm = ops.sigmoid(input)
return [sigm.output(0)]
return ConversionExtension("Elu", custom_converter)
def create_ref_graph1():
shape = PartialShape([2, 3, 4])
param = ov.opset8.parameter(shape, dtype=np.float32)
param.get_output_tensor(0).set_names({"input"})
relu = ov.opset8.relu(param)
relu.get_output_tensor(0).set_names({"LeakyRelu_data"})
elu = ov.opset8.elu(relu, alpha=0.1)
elu.get_output_tensor(0).set_names({"output"})
return Model([elu], [param], "test")
def create_ref_graph2():
shape = PartialShape([2, 3, 4])
param = ov.opset8.parameter(shape, dtype=np.float32)
param.get_output_tensor(0).set_names({"input"})
relu = ov.opset8.relu(param)
relu.get_output_tensor(0).set_names({"LeakyRelu_data"})
sigmoid = ov.opset8.sigmoid(relu)
sigmoid.get_output_tensor(0).set_names({"output"})
return Model([sigmoid], [param], "test")
test_data = [
{'params_test': {'extension': create_custom_extension_leaky_relu_to_relu()},
'ref_graph': create_ref_graph1()},
{'params_test': {'extension': [create_custom_extension_leaky_relu_to_relu(),
create_custom_extension_elu_to_sigmoid()]},
'ref_graph': create_ref_graph2()}
]
@pytest.mark.parametrize("params", test_data)
@pytest.mark.nightly
@pytest.mark.precommit
def test_mo_convert_extensions(self, params, ie_device, precision, ir_version,
temp_dir, use_new_frontend, use_old_api):
onnx_net_path = self.create_onnx_model(temp_dir)
test_params = params['params_test']
test_params.update({'input_model': onnx_net_path})
self._test_by_ref_graph(temp_dir, test_params, params['ref_graph'])
@@ -0,0 +1,83 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import io
import numpy as np
import openvino.runtime as ov
import pytest
from openvino.runtime import Model
from common.mo_convert_test_class import CommonMOConvertTest
def make_graph_proto_model():
import onnx
from onnx import helper
from onnx import TensorProto
shape = [2, 3, 4]
input = helper.make_tensor_value_info('input', TensorProto.FLOAT, shape)
output = helper.make_tensor_value_info('output', TensorProto.FLOAT, shape)
node_def = onnx.helper.make_node(
'LeakyRelu',
inputs=['input'],
outputs=['LeakyRelu_data'],
alpha=0.1
)
node_def2 = onnx.helper.make_node(
'Elu',
inputs=['LeakyRelu_data'],
outputs=['output'],
alpha=0.1
)
# Create the graph (GraphProto)
graph_def = helper.make_graph(
[node_def, node_def2],
'test_model',
[input],
[output],
)
# Create the model (ModelProto)
onnx_net = helper.make_model(graph_def, producer_name='test_model')
return onnx_net
def create_ref_model(shape):
param1 = ov.opset8.parameter(shape, dtype=np.float32)
slope_const = ov.opset8.constant([0.1], dtype=np.float16)
decompress_slope = ov.opset8.convert(slope_const, np.float32)
prelu = ov.opset8.prelu(param1, slope=decompress_slope)
relu = ov.opset8.elu(prelu, alpha=np.float32(0.1))
parameter_list = [param1]
return Model([relu], parameter_list, "test")
def create_bytes_io():
import onnx
onnx_model = make_graph_proto_model()
file_like_object = io.BytesIO()
onnx.save(onnx_model, file_like_object)
ref_model = create_ref_model([2,3,4])
return file_like_object, ref_model, {}
class TestMoConvertONNX(CommonMOConvertTest):
test_data = [create_bytes_io]
@pytest.mark.parametrize("create_model", test_data)
@pytest.mark.nightly
@pytest.mark.precommit
def test_mo_convert_onnx(self, create_model, ie_device, precision, ir_version,
temp_dir):
fw_model, graph_ref, mo_params = create_model()
test_params = {'input_model': fw_model}
if mo_params is not None:
test_params.update(mo_params)
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
@@ -89,3 +89,18 @@ class TestOVCTool(CommonMOConvertTest):
ov_model = core.read_model(os.path.join(temp_dir, "model.xml"))
flag, msg = compare_functions(ov_model, create_ref_graph(), False)
assert flag, msg
def test_ovc_tool_output_dir(self, ie_device, precision, ir_version, temp_dir, use_new_frontend, use_old_api):
from openvino.runtime import Core
model_path = self.create_tf_model(temp_dir)
core = Core()
# tests for MO cli tool
exit_code, stderr = generate_ir_ovc(coverage=False, **{"input_model": model_path, "output_model": temp_dir})
assert not exit_code
ov_model = core.read_model(os.path.join(temp_dir, "model.xml"))
flag, msg = compare_functions(ov_model, create_ref_graph(), False)
assert flag, msg
@@ -0,0 +1,30 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import sys
import unittest
from openvino.tools.ovc import ovc
from openvino.tools.ovc.cli_parser import get_mo_convert_params
from pathlib import Path
from common.utils.common_utils import shell
class TestSubprocessMoConvert(unittest.TestCase):
def test_mo_convert(self):
mo_convert_params = get_mo_convert_params()
# Test ovc tool help
mo_path = Path(ovc.__file__).parent
mo_runner = mo_path.joinpath('main.py').as_posix()
params = [sys.executable, mo_runner, "--help"]
_, mo_output, _ = shell(params)
# We don't expect PyTorch specific parameters to be in help message of the MO tool.
for group in mo_convert_params:
if group == 'Pytorch-specific parameters:' or group == 'PaddlePaddle-specific parameters:':
continue
for param_name in group:
assert param_name in mo_output
@@ -0,0 +1,103 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import numpy as np
import pytest
from common.mo_convert_test_class import CommonMOConvertTest
import openvino.runtime as ov
from openvino.runtime import PartialShape, Model
def make_pd_dynamic_graph_model():
import paddle
paddle.disable_static()
class NeuralNetwork(paddle.nn.Layer):
def __init__(self):
super(NeuralNetwork, self).__init__()
self.relu_sigmoid_stack = paddle.nn.Sequential(
paddle.nn.ReLU(),
paddle.nn.Sigmoid())
def forward(self, input):
return self.relu_sigmoid_stack(input)
return NeuralNetwork()
def make_pd_static_graph_model(shape):
import paddle
import paddle.nn
paddle.enable_static()
x = paddle.static.data(name="x", shape=shape)
y = paddle.static.data(name="y", shape=shape)
relu = paddle.nn.ReLU()
sigmoid = paddle.nn.Sigmoid()
y = sigmoid(relu(x))
exe = paddle.static.Executor(paddle.CPUPlace())
exe.run(paddle.static.default_startup_program())
return exe, x, y
def make_pd_hapi_graph_model(shape):
import paddle
paddle.disable_static()
from paddle.static import InputSpec
net = paddle.nn.Sequential(
paddle.nn.ReLU(),
paddle.nn.Sigmoid())
input = InputSpec(shape, 'float32', 'x')
label = InputSpec(shape, 'float32', 'label')
model = paddle.Model(net, input, label)
optim = paddle.optimizer.SGD(learning_rate=1e-3,
parameters=model.parameters())
model.prepare(optim, paddle.nn.CrossEntropyLoss(), paddle.metric.Accuracy())
return model
def make_ref_graph_model(shape, dtype=np.float32):
shape = PartialShape(shape)
param = ov.opset8.parameter(shape, name="x", dtype=dtype)
relu = ov.opset8.relu(param)
sigm = ov.opset8.sigmoid(relu)
model = Model([sigm], [param], "test")
return model
def create_paddle_dynamic_module(tmp_dir):
import paddle
shape = [2,3,4]
pd_model = make_pd_dynamic_graph_model()
ref_model = make_ref_graph_model(shape)
x = paddle.static.InputSpec(shape=shape, dtype='float32', name='x')
return pd_model, ref_model, {"example_input": [x]}
def create_paddle_static_module(tmp_dir):
shape = [2,3,4]
pd_model, x, y = make_pd_static_graph_model(shape)
ref_model = make_ref_graph_model(shape)
return pd_model, ref_model, {"example_input": [x], "example_output": [y]}
def create_paddle_hapi_module(tmp_dir):
shape = [2,3,4]
pd_model = make_pd_hapi_graph_model(shape)
ref_model = make_ref_graph_model(shape)
return pd_model, ref_model, {}
class TestMoConvertPaddle(CommonMOConvertTest):
test_data = [
create_paddle_dynamic_module,
create_paddle_static_module,
create_paddle_hapi_module
]
@pytest.mark.skip(reason="Paddlepaddle has incompatible protobuf. Ticket: 95904")
@pytest.mark.parametrize("create_model", test_data)
def test_mo_import_from_memory_paddle_fe(self, create_model, ie_device, precision, ir_version,
temp_dir):
fw_model, graph_ref, mo_params = create_model(temp_dir)
test_params = {'input_model': fw_model, 'use_new_frontend': True}
if mo_params is not None:
test_params.update(mo_params)
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,859 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import unittest
import numpy as np
import openvino.runtime as ov
import pytest
from openvino.runtime import PartialShape, Model, Dimension
from common.mo_convert_test_class import CommonMOConvertTest
from common.layer_test_class import CommonLayerTest
def create_tf_graph_def(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, 2, 3], 'Input')
inp2 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input')
relu = tf.nn.relu(inp1 + inp2, name='Relu')
output = tf.nn.sigmoid(relu, name='Sigmoid')
tf.compat.v1.global_variables_initializer()
tf_net = sess.graph_def
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return tf_net, model_ref, None
def create_keras_model(temp_dir):
import tensorflow as tf
tf.keras.backend.clear_session()
tf.compat.v1.reset_default_graph()
input_names = ["Input1", "Input2"]
input_shape = [1, 2, 3]
x1 = tf.keras.Input(shape=input_shape, name=input_names[0])
x2 = tf.keras.Input(shape=input_shape, name=input_names[1])
y = tf.nn.sigmoid(tf.nn.relu(x1 + x2))
keras_net = tf.keras.Model(inputs=[x1, x2], outputs=[y])
shape = PartialShape([-1, 1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
tf.keras.backend.clear_session()
return keras_net, model_ref, None
def create_tf1_wrap_function(tmp_dir):
import tensorflow as tf
def f(x, y):
return tf.nn.sigmoid(tf.nn.relu(x + y))
func = tf.compat.v1.wrap_function(f, [tf.TensorSpec((1, 2, 3), tf.float32),
tf.TensorSpec((1, 2, 3), tf.float32)])
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return func, model_ref, None
def create_tf_session(tmp_dir):
import tensorflow as tf
from tensorflow.python.eager.context import graph_mode
with graph_mode():
tf.compat.v1.reset_default_graph()
sess = tf.compat.v1.Session()
inp1 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input1')
inp2 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input2')
relu = tf.nn.relu(inp1 + inp2, name='Relu')
output = tf.nn.sigmoid(relu, name='Sigmoid')
tf.compat.v1.global_variables_initializer()
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return sess, model_ref, None
def create_tf_module(tmp_dir):
import tensorflow as tf
class Net(tf.Module):
def __init__(self, name=None):
super(Net, self).__init__(name=name)
def __call__(self, x, y):
return tf.nn.sigmoid(tf.nn.relu(x + y))
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
net = Net()
return net, model_ref, {'input': [PartialShape([1, 2, 3]), PartialShape([1, 2, 3])]}
def create_tf_module_dynamic(tmp_dir):
import tensorflow as tf
class Net(tf.Module):
def __init__(self, name=None):
super(Net, self).__init__(name=name)
def __call__(self, x, y):
return tf.nn.sigmoid(tf.nn.relu(x + y))
input_shapes = [PartialShape([-1, Dimension(3, -1), Dimension(4)]),
PartialShape([-1, Dimension(3), Dimension(4, -1)])]
param1 = ov.opset8.parameter(input_shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(input_shapes[1], dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
net = Net()
return net, model_ref, {'input': input_shapes}
def create_keras_layer(tmp_dir):
import tensorflow as tf
class LayerModel(tf.keras.layers.Layer):
def __init__(self):
super(LayerModel, self).__init__()
def call(self, x, y):
return tf.sigmoid(tf.nn.relu(x + y))
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
net = LayerModel()
return net, model_ref, {'input': [PartialShape([1, 2, 3]), PartialShape([1, 2, 3])]}
def create_keras_layer_dynamic(tmp_dir):
import tensorflow as tf
class LayerModel(tf.keras.layers.Layer):
def __init__(self):
super(LayerModel, self).__init__()
def call(self, x, y):
return tf.sigmoid(tf.nn.relu(x + y))
input_shapes = [PartialShape([-1, Dimension(3, -1), Dimension(4)]),
PartialShape([-1, Dimension(3), Dimension(4, -1)])]
param1 = ov.opset8.parameter(input_shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(input_shapes[1], dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
net = LayerModel()
return net, model_ref, {'input': input_shapes}
def create_tf_checkpoint(tmp_dir):
import tensorflow as tf
input_names = ["Input1", "Input2"]
input_shape = [1, 2, 3]
x1 = tf.keras.Input(shape=input_shape, name=input_names[0])
x2 = tf.keras.Input(shape=input_shape, name=input_names[1])
y = tf.nn.sigmoid(tf.nn.relu(x1 + x2))
model = tf.keras.Model(inputs=[x1, x2], outputs=[y])
checkpoint = tf.train.Checkpoint(model)
shape = PartialShape([-1, 1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return checkpoint, model_ref, None
def create_tf_function(temp_dir):
import tensorflow as tf
@tf.function(
input_signature=[tf.TensorSpec(shape=[1, 2, 3], dtype=tf.float32),
tf.TensorSpec(shape=[1, 2, 3], dtype=tf.float32)])
def f(x1, x2):
y = tf.nn.sigmoid(tf.nn.relu(x1 + x2))
return y
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return f, model_ref, None
def create_tf_graph(temp_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, 2, 3], 'Input')
inp2 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input')
relu = tf.nn.relu(inp1 + inp2, name='Relu')
output = tf.nn.sigmoid(relu, name='Sigmoid')
tf.compat.v1.global_variables_initializer()
tf_net = sess.graph
shape = PartialShape([1, 2, 3])
param1 = ov.opset8.parameter(shape, dtype=np.float32)
param2 = ov.opset8.parameter(shape, dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return tf_net, model_ref, None
def create_tf_saved_model_dir(temp_dir):
import tensorflow as tf
input_names = ["Input1", "Input2"]
input_shape = [1, 2, 3]
x1 = tf.keras.Input(shape=input_shape, name=input_names[0])
x2 = tf.keras.Input(shape=input_shape, name=input_names[1])
y = tf.nn.sigmoid(tf.nn.relu(x1 + x2))
keras_net = tf.keras.Model(inputs=[x1, x2], outputs=[y])
tf.saved_model.save(keras_net, temp_dir + "/model")
shape = PartialShape([-1, 1, 2, 3])
param1 = ov.opset8.parameter(shape, name="Input1:0", dtype=np.float32)
param2 = ov.opset8.parameter(shape, name="Input2:0", dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu = ov.opset8.relu(add)
sigm = ov.opset8.sigmoid(relu)
parameter_list = [param1, param2]
model_ref = Model([sigm], parameter_list, "test")
return temp_dir + "/model", model_ref
def create_tf_stateful_partioned_call_net(temp_dir):
import tensorflow as tf
tf.compat.v1.reset_default_graph()
data_shape = [1, 1, 10, 10]
filters_shape = [3, 3, 1, 1]
strides = [1, 1]
pads_begin = [0, 0]
pads_end = [0, 0]
dilations = [1, 1]
@tf.function
def second_func(input, filter):
conv = tf.raw_ops.Conv2D(input=input, filter=filter, strides=[1, 1, 1, 1], padding='SAME', data_format='NCHW')
return conv
@tf.function(
input_signature=[tf.TensorSpec(shape=data_shape, dtype=tf.float32),
tf.TensorSpec(shape=filters_shape, dtype=tf.float32)])
def first_func(input, filter):
conv = second_func(input, filter)
return conv
tf_model = first_func
param1 = ov.opset8.parameter(data_shape, dtype=np.float32)
param2 = ov.opset8.parameter(filters_shape, dtype=np.float32)
reshape = ov.opset8.reshape(param2, np.array([1, 1, 3, 3], dtype=np.int64), True)
conv = ov.opset11.convolution(param1, reshape, strides, pads_begin, pads_end, dilations, auto_pad="same_upper")
parameter_list = [param1, param2]
model_ref = Model([conv], parameter_list, "test")
return tf_model, model_ref, {}
def create_keras_layer_input_list():
import tensorflow as tf
class LayerModel(tf.keras.layers.Layer):
def __init__(self):
super(LayerModel, self).__init__()
def call(self, x, y):
res_list = [tf.sigmoid(tf.nn.relu(x + y)), tf.nn.relu(x), tf.sigmoid(y)]
return res_list
input_shapes = [PartialShape([1, 2, 3]),
PartialShape([1, 2, 3])]
param1 = ov.opset8.parameter(input_shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(input_shapes[1], dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu1 = ov.opset8.relu(add)
sigm1 = ov.opset8.sigmoid(relu1)
relu2 = ov.opset8.relu(param1)
sigm2 = ov.opset8.sigmoid(param2)
parameter_list = [param1, param2]
model_ref = Model([sigm1, relu2, sigm2], parameter_list, "test")
return LayerModel(), model_ref
def create_keras_layer_input_list_one_inp():
import tensorflow as tf
class LayerModel(tf.keras.layers.Layer):
def __init__(self):
super(LayerModel, self).__init__()
def call(self, x):
res_list = [tf.sigmoid(tf.nn.relu(x)), tf.nn.relu(x)]
return res_list
input_shapes = [PartialShape([1,2,3])]
param1 = ov.opset8.parameter(input_shapes[0], dtype=np.float32)
relu1 = ov.opset8.relu(param1)
sigm1 = ov.opset8.sigmoid(relu1)
parameter_list = [param1]
model_ref = Model([sigm1, relu1], parameter_list, "test")
return LayerModel(), model_ref
def create_keras_layer_input_dict():
import tensorflow as tf
class LayerModel(tf.keras.layers.Layer):
def __init__(self):
super(LayerModel, self).__init__()
def call(self, args):
res = {}
res['result'] = tf.sigmoid(tf.nn.relu(args['a'] + args['b']))
return res
input_shapes = [PartialShape([1, 2, 3]),
PartialShape([1, 2, 3])]
param1 = ov.opset8.parameter(input_shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(input_shapes[1], dtype=np.float32)
add = ov.opset8.add(param1, param2)
relu1 = ov.opset8.relu(add)
sigm1 = ov.opset8.sigmoid(relu1)
parameter_list = [param1, param2]
model_ref = Model([sigm1], parameter_list, "test")
return LayerModel(), model_ref
def create_keras_layer_input_dict_one_inp():
import tensorflow as tf
class LayerModel(tf.keras.layers.Layer):
def __init__(self):
super(LayerModel, self).__init__()
def call(self, args):
res = {}
res['result'] = tf.sigmoid(tf.nn.relu(args['args']))
return res
input_shapes = [PartialShape([1, 2, 3]),
PartialShape([1, 2, 3])]
param1 = ov.opset8.parameter(input_shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(input_shapes[1], dtype=np.float32)
relu1 = ov.opset8.relu(param1)
sigm1 = ov.opset8.sigmoid(relu1)
parameter_list = [param1, param2]
model_ref = Model([sigm1], parameter_list, "test")
return LayerModel(), model_ref
def single_param_function_reference(shape, const_value):
param1 = ov.opset8.parameter(shape, dtype=np.float32)
const = ov.opset8.constant(const_value, dtype=np.float32)
sigm = ov.opset8.sigmoid(param1)
mul = ov.opset8.multiply(sigm, const)
parameter_list = [param1]
return Model([mul], parameter_list, "test")
def two_params_function_reference(shapes, const_value):
param1 = ov.opset8.parameter(shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(shapes[1], dtype=np.float32)
const = ov.opset8.constant(const_value, dtype=np.float32)
sigm = ov.opset8.sigmoid(param1)
add = ov.opset8.add(sigm, param2)
mul = ov.opset8.multiply(add, const)
parameter_list = [param1, param2]
return Model([mul], parameter_list, "test")
def two_params_function_reference_fp16_compressed(shapes, const_value):
param1 = ov.opset8.parameter(shapes[0], dtype=np.float32)
param2 = ov.opset8.parameter(shapes[1], dtype=np.float32)
const_value = ov.opset8.constant(const_value, dtype=np.float16)
const_decompress = ov.opset8.convert(const_value, np.float32)
sigm = ov.opset8.sigmoid(param1)
add = ov.opset8.add(sigm, param2)
mul = ov.opset8.multiply(add, const_decompress)
parameter_list = [param1, param2]
return Model([mul], parameter_list, "test")
def create_keras_layer_with_example_input_1(tmp_dir):
model, model_ref = create_keras_layer_input_list()
example_input = (np.random.rand(1,2,3).astype(np.float32), np.random.rand(1,2,3).astype(np.float32))
return model, model_ref, {'example_input': example_input}
def create_keras_layer_with_example_input_2(tmp_dir):
model, model_ref = create_keras_layer_input_dict()
example_input = {'a': np.random.rand(1,2,3).astype(np.float32), 'b': np.random.rand(1,2,3).astype(np.float32)}
return model, model_ref, {'example_input': example_input}
def create_keras_layer_with_input_shapes_case1(tmp_dir):
model, model_ref = create_keras_layer_input_list()
return model, model_ref, {'input': [[1, 2, 3], [1, 2, 3]]}
def create_keras_layer_with_input_shapes_case2(tmp_dir):
model, model_ref = create_keras_layer_input_list()
return model, model_ref, {'input': [([1, 2, 3], np.float32), ([1, 2, 3], np.float32)]}
def create_keras_layer_with_input_shapes_case3(tmp_dir):
model, model_ref = create_keras_layer_input_dict_one_inp()
return model, model_ref, {'input': [('args', [1, 2, 3])]}
def create_keras_layer_with_input_shapes_case4(tmp_dir):
model, model_ref = create_keras_layer_input_list_one_inp()
return model, model_ref, {'input': [1, 2, 3]}
def create_keras_layer_with_tf_function_call(tmp_dir):
import tensorflow as tf
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable(5.0)
@tf.function(input_signature=[tf.TensorSpec([1, 2], tf.float32), tf.TensorSpec([1, 2], tf.float32)])
def __call__(self, input1, input2):
sigm = tf.nn.sigmoid(input1) + input2
return sigm * self.var1
model = LayerModel()
model_ref = two_params_function_reference([[1, 2], [1, 2]], [[5.0]])
return model, model_ref, {'compress_to_fp16': False}
def create_keras_layer_with_tf_function_call_default_compressed_to_fp16(tmp_dir):
import tensorflow as tf
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable(5.0)
@tf.function(input_signature=[tf.TensorSpec([1, 2], tf.float32), tf.TensorSpec([1, 2], tf.float32)])
def __call__(self, input1, input2):
sigm = tf.nn.sigmoid(input1) + input2
return sigm * self.var1
model = LayerModel()
model_ref = two_params_function_reference_fp16_compressed([[1, 2], [1, 2]], [[5.0]])
return model, model_ref, {}
def create_keras_layer_with_tf_function_call_no_signature(tmp_dir):
import tensorflow as tf
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable(5.0)
@tf.function()
def __call__(self, input1, input2):
sigm = tf.nn.sigmoid(input1) + input2
return sigm * self.var1
model = LayerModel()
example_input = [np.random.rand(2, 3).astype(np.float32), np.random.rand(2, 3).astype(np.float32)]
model_ref = two_params_function_reference([[2, 3], [2, 3]], [[5.0]])
return model, model_ref, {'example_input': example_input, 'compress_to_fp16': False}
def create_keras_layer_with_tf_function_call_no_signature_single_input(tmp_dir):
import tensorflow as tf
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable(5.0)
@tf.function()
def __call__(self, input1):
sigm = tf.nn.sigmoid(input1)
return sigm * self.var1
model = LayerModel()
example_input = np.random.rand(2, 3).astype(np.float32)
model_ref = single_param_function_reference([2, 3], [[5.0]])
return model, model_ref, {'example_input': example_input, 'compress_to_fp16': False}
def create_keras_layer_with_string_tensor(tmp_dir):
import tensorflow as tf
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var = tf.Variable("Text_1", dtype=tf.string)
self.const = tf.constant("Text_2", dtype=tf.string)
@tf.function(input_signature=[tf.TensorSpec([1], tf.float32), tf.TensorSpec([1], tf.float32)])
def __call__(self, input1, input2):
return input1 + input2, self.var, self.const
model = LayerModel()
param1 = ov.opset8.parameter([1], dtype=np.float32)
param2 = ov.opset8.parameter([1], dtype=np.float32)
add = ov.opset8.add(param1, param2)
parameter_list = [param1, param2]
model_ref = Model([add], parameter_list, "test")
return model, model_ref, {}
class TestMoConvertTF(CommonMOConvertTest):
test_data = [
# TF2
create_keras_model,
create_keras_layer,
create_tf_function,
create_tf_module,
create_tf_checkpoint,
create_keras_layer_dynamic,
create_tf_module_dynamic,
create_tf_stateful_partioned_call_net,
create_keras_layer_with_example_input_1,
create_keras_layer_with_example_input_2,
create_keras_layer_with_input_shapes_case1,
create_keras_layer_with_input_shapes_case2,
create_keras_layer_with_input_shapes_case3,
create_keras_layer_with_input_shapes_case4,
create_keras_layer_with_tf_function_call,
create_keras_layer_with_tf_function_call_default_compressed_to_fp16,
create_keras_layer_with_tf_function_call_no_signature,
create_keras_layer_with_tf_function_call_no_signature_single_input,
create_keras_layer_with_string_tensor,
# TF1
create_tf_graph,
create_tf_graph_def,
create_tf1_wrap_function,
create_tf_session,
]
@pytest.mark.parametrize("create_model", test_data)
@pytest.mark.nightly
@pytest.mark.precommit_tf_fe
@pytest.mark.precommit
def test_mo_import_from_memory_tf_fe(self, create_model, ie_device, precision, ir_version,
temp_dir):
fw_model, graph_ref, mo_params = create_model(temp_dir)
test_params = {'input_model': fw_model}
if mo_params is not None:
test_params.update(mo_params)
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
@pytest.mark.nightly
@pytest.mark.precommit
def test_unnamed_saved_model_dir(self, ie_device, precision, ir_version, temp_dir):
saved_model_dir, graph_ref = create_tf_saved_model_dir(temp_dir)
test_params = {'input_model': saved_model_dir}
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
test_params = {'input_model': saved_model_dir}
self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False)
def test_zero_copy(self, ie_device, precision, ir_version, temp_dir):
import tensorflow as tf
from openvino.tools.ovc import convert_model
from openvino.runtime import compile_model
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable([7., 5., 6.], name='var1')
self.var2 = tf.Variable([5., 7., 3.], name='var2')
@tf.function
def sub_function(self, input):
return input * self.var1 + self.var2
@tf.function()
def __call__(self, input):
return self.sub_function(input)
# Create TF model with variables
keras_model = LayerModel()
test_input = np.array(7.).astype(np.float32)
# Convert model to OV
ov_model = convert_model(keras_model, input=[1], share_weights=True)
cmp_model = compile_model(ov_model)
# Check model inference
ov_infer1 = cmp_model(test_input, ie_device)
fw_infer1 = keras_model(test_input).numpy()
assert np.array_equal(ov_infer1['Identity:0'], fw_infer1)
assert np.array_equal(ov_infer1['Identity:0'], [54., 42., 45.])
# Change value of variables in original model
for val in keras_model.variables:
arr = val.value().__array__()
arr[0] = 0
arr[1] = 1
arr[2] = 2
# Check model inference
cmp_model = compile_model(ov_model)
ov_infer2 = cmp_model(test_input)
fw_infer2 = keras_model(test_input).numpy()
assert np.array_equal(ov_infer2['Identity:0'], fw_infer2)
assert np.array_equal(ov_infer2['Identity:0'], [ 0., 8., 16.])
def test_turn_off_sharing(self, ie_device, precision, ir_version, temp_dir):
import tensorflow as tf
from openvino.tools.ovc import convert_model
from openvino.runtime import compile_model
class LayerModel(tf.Module):
def __init__(self):
super(LayerModel, self).__init__()
self.var1 = tf.Variable([7., 5., 6.], name='var1')
self.var2 = tf.Variable([5., 7., 3.], name='var2')
@tf.function
def sub_function(self, input):
return input * self.var1 + self.var2
@tf.function()
def __call__(self, input):
return self.sub_function(input)
# Create TF model with variables
keras_model = LayerModel()
test_input = np.array(7.).astype(np.float32)
# Convert model to OV
ov_model = convert_model(keras_model, input=[1], share_weights=False)
cmp_model = compile_model(ov_model)
# Check model inference
ov_infer1 = cmp_model(test_input, ie_device)
fw_infer1 = keras_model(test_input).numpy()
assert np.array_equal(ov_infer1['Identity:0'], fw_infer1)
assert np.array_equal(ov_infer1['Identity:0'], [54., 42., 45.])
# Change value of variables in original model
for val in keras_model.variables:
arr = val.value().__array__()
arr[0] = 0
arr[1] = 1
arr[2] = 2
# Check model inference
ov_infer2 = cmp_model(test_input)
fw_infer2 = keras_model(test_input).numpy()
# Check model inference calculated with old constant values
assert not np.array_equal(ov_infer2['Identity:0'], fw_infer2)
assert np.array_equal(ov_infer2['Identity:0'], [54., 42., 45.])
def test_memory_loss(self, ie_device, precision, ir_version, temp_dir):
# This test checks that the memory allocated for constants
# is not lost after returning the model from convert_model() method.
import tensorflow as tf
tf.compat.v1.reset_default_graph()
from openvino.tools.ovc import convert_model
from openvino.runtime import compile_model
import gc
with tf.compat.v1.Session() as sess:
inp1 = tf.compat.v1.placeholder(tf.float32, [3], 'Input')
const = tf.constant([0.5, 2.3, 7.8], dtype=tf.float32)
res = inp1 + const
tf.compat.v1.global_variables_initializer()
tf_graph = sess.graph # tf.Graph
if precision == 'FP32':
eps = 1e-4
else:
eps = 5e-2
test_input = np.array([2.1, 7.3, 4.6]).astype(np.float32)
# Convert model to OV
ov_model = convert_model(tf_graph)
cmp_model = compile_model(ov_model)
# Check model inference
ov_infer1 = cmp_model(test_input, ie_device)
feed_dict = {"Input:0": test_input}
with tf.compat.v1.Session(graph=tf_graph) as sess:
fw_infer1 = sess.run('add:0', feed_dict=feed_dict)
assert CommonLayerTest().compare_ie_results_with_framework(ov_infer1, {"add:0": fw_infer1}, eps)
assert CommonLayerTest().compare_ie_results_with_framework(ov_infer1, {"add:0": [2.6, 9.6, 12.4]}, eps)
# run Garbage collector to ensure, that values from tf.constant are copied to ov.Const and
# we do not lose allocated memory.
gc.collect()
# Check model inference
cmp_model = compile_model(ov_model)
ov_infer2 = cmp_model(test_input, ie_device)
feed_dict = {"Input:0": test_input}
with tf.compat.v1.Session(graph=tf_graph) as sess:
fw_infer2 = sess.run('add:0', feed_dict=feed_dict)
assert CommonLayerTest().compare_ie_results_with_framework(ov_infer2, {"add:0": fw_infer2}, eps)
assert CommonLayerTest().compare_ie_results_with_framework(ov_infer1, {"add:0": [2.6, 9.6, 12.4]}, eps)
class TFConvertTest(unittest.TestCase):
@pytest.mark.nightly
@pytest.mark.precommit
def test_tf_function_no_signature(self):
import tensorflow as tf
from openvino.tools.ovc import convert_model
@tf.function()
def function(x1, x2):
y = tf.nn.sigmoid(tf.nn.relu(x1 + x2))
return y
with self.assertRaisesRegex(Exception, ".*Please provide 'example_input'.*"):
convert_model(function)
class TestTFLoadByModel(unittest.TestCase):
def test_load_by_model_tf_graph_iterator(self):
def simple_tf_model():
import tensorflow as tf
tf.compat.v1.reset_default_graph()
with tf.compat.v1.Session() as sess:
inp = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], "Input")
_ = tf.nn.sigmoid(inp, name="Sigmoid")
tf.compat.v1.global_variables_initializer()
tf_net = sess.graph
return tf_net
from openvino.frontend.tensorflow.graph_iterator import GraphIteratorTFGraph
from openvino.frontend import FrontEndManager
model = GraphIteratorTFGraph(simple_tf_model(), True)
fem = FrontEndManager()
fe = fem.load_by_model(model)
assert fe is not None
assert fe.get_name() == "tf"
+1 -1
View File
@@ -57,6 +57,6 @@ except ImportError:
# Tools
try:
# Model Conversion API - ovc should reside in the main namespace
from openvino.tools.ovc import convert_model, InputCutInfo
from openvino.tools.ovc import convert_model
except ImportError:
pass
+1 -1
View File
@@ -57,6 +57,6 @@ except ImportError:
# Tools
try:
# Model Conversion API - ovc should reside in the main namespace
from openvino.tools.ovc import convert_model, InputCutInfo
from openvino.tools.ovc import convert_model
except ImportError:
pass
+1 -1
View File
@@ -57,6 +57,6 @@ except ImportError:
# Tools
try:
# Model Conversion API - ovc should reside in the main namespace
from openvino.tools.ovc import convert_model, InputCutInfo
from openvino.tools.ovc import convert_model
except ImportError:
pass
+1 -1
View File
@@ -57,6 +57,6 @@ except ImportError:
# Tools
try:
# Model Conversion API - ovc should reside in the main namespace
from openvino.tools.ovc import convert_model, InputCutInfo
from openvino.tools.ovc import convert_model
except ImportError:
pass
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from openvino.tools.ovc.convert import convert_model, InputCutInfo
from openvino.tools.ovc.convert import convert_model
+72 -148
View File
@@ -3,27 +3,27 @@
import argparse
import ast
import inspect
import logging as log
import os
import pathlib
import re
from collections import OrderedDict, namedtuple
from distutils.util import strtobool
from itertools import zip_longest
from pathlib import Path
from operator import xor
from typing import List, Union
import numbers
import inspect
import numpy as np
from openvino.runtime import Layout, PartialShape, Dimension, Shape, Type # pylint: disable=no-name-in-module,import-error
from openvino.runtime import PartialShape, Dimension, Shape, Type # pylint: disable=no-name-in-module,import-error
import openvino
from openvino.tools.ovc.convert_data_type import destination_type_to_np_data_type
from openvino.tools.ovc.error import Error
from openvino.tools.ovc.utils import get_mo_root_dir
from openvino.tools.ovc.help import get_convert_model_help_specifics
from openvino.tools.ovc.utils import get_mo_root_dir
# Helper class for storing input cut information
_InputCutInfo = namedtuple("InputCutInfo", ["name", "shape", "type", "value"], defaults=[None, None, None, None])
def is_shape_type(value):
if isinstance(value, PartialShape):
@@ -45,20 +45,12 @@ def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type,
"""
if isinstance(input, str):
# Parse params from string
node_name, shape, value, data_type = parse_input_value(input)
node_name, shape, data_type = parse_input_value(input)
# pylint: disable=no-member
return openvino.tools.ovc.InputCutInfo(node_name,
PartialShape(shape) if shape is not None else None,
data_type,
value)
if isinstance(input, openvino.tools.ovc.InputCutInfo): # pylint: disable=no-member
# Wrap input.shape to PartialShape if possible and wrap to InputCutInfo
# pylint: disable=no-member
return openvino.tools.ovc.InputCutInfo(input.name,
PartialShape(input.shape) if input.shape is not None else None,
input.type,
input.value)
if isinstance(input, (tuple, list, PartialShape)):
return _InputCutInfo(node_name,
PartialShape(shape) if shape is not None else None,
data_type)
if isinstance(input, (tuple, list)) or is_shape_type(input):
# 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)):
@@ -85,19 +77,18 @@ def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type,
raise Exception("Incorrect input parameters provided. Expected tuple with input name, "
"input type or input shape. Got unknown object: {}".format(val))
# pylint: disable=no-member
return openvino.tools.ovc.InputCutInfo(name,
PartialShape(shape) if shape is not None else None,
inp_type,
None)
return _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.ovc.InputCutInfo(None, None, input, None) # pylint: disable=no-member
return _InputCutInfo(None, None, input, None) # pylint: disable=no-member
# 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.ovc.InputCutInfo "
"or tuple or str. Got {}".format(type(input)))
raise Exception("Unexpected object provided for input. Expected tuple, Shape, PartialShape, Type or str. Got {}".format(type(input)))
def input_to_input_cut_info(input: [str, tuple, list]):
@@ -114,17 +105,12 @@ def input_to_input_cut_info(input: [str, tuple, list]):
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)
node_name, shape, data_type = parse_input_value(input_value)
# pylint: disable=no-member
inputs.append(openvino.tools.ovc.InputCutInfo(node_name,
PartialShape(shape) if shape is not None else None,
data_type,
value))
inputs.append(_InputCutInfo(node_name,
PartialShape(shape) if shape is not None else None,
data_type))
return inputs
# pylint: disable=no-member
if isinstance(input, openvino.tools.ovc.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)):
@@ -140,6 +126,17 @@ def input_to_input_cut_info(input: [str, tuple, list]):
for inp in input:
inputs.append(single_input_to_input_cut_info(inp))
return inputs
if isinstance(input, dict):
res_list = []
for name, value in input.items():
if not isinstance(name, str):
raise Exception("Incorrect operation name type. Expected string, got {}".format(type(name)))
info = single_input_to_input_cut_info(value)
if info.name is not None and info.name != name:
raise Exception("Incorrect \"input\" dictionary, got different names in key and value. "
"Got operation name {} for key {}".format(info.name, name))
res_list.append(_InputCutInfo(name, info.shape, info.type))
return res_list
# Case when single type or value is set, or unknown object
return [single_input_to_input_cut_info(input)]
@@ -443,7 +440,7 @@ class Formatter(argparse.HelpFormatter):
usage = argparse.HelpFormatter._format_usage(self, usage, actions, groups, prefix)
usage = usage[0:usage.find('INPUT_MODEL')].rstrip() + '\n'
insert_idx = usage.find(self._prog) + len(self._prog)
usage = usage[0: insert_idx] + ' INPUT_MODEL ' + usage[insert_idx + 1:]
usage = usage[0: insert_idx] + ' INPUT_MODEL... ' + usage[insert_idx + 1:]
return usage
def _get_default_metavar_for_optional(self, action):
@@ -473,12 +470,20 @@ def get_common_cli_parser(parser: argparse.ArgumentParser = None):
add_args_by_description(parser, mo_convert_params_common)
return parser
def input_model_details(model):
if isinstance(model, (list, tuple)) and len(model) == 1:
model = model[0]
if isinstance(model, (str, pathlib.Path)):
return model
return type(model)
def get_common_cli_options(model_name):
def get_common_cli_options(argv, is_python_api_used):
d = OrderedDict()
d['input_model'] = '- Path to the Input Model'
d['output_dir'] = ['- Path for generated IR', lambda x: x if x != '.' else os.getcwd()] # TODO: Consider removing
d['output_model'] = ['- IR output name', lambda x: x if x else model_name]
d['input_model'] = ['- Path to the Input Model', input_model_details]
if not is_python_api_used:
model_name = get_model_name_from_args(argv)
d['output_model'] = ['- IR output name', lambda _: model_name]
d['log_level'] = '- Log level'
d['input'] = ['- Input layers', lambda x: x if x else 'Not specified, inherited from the model']
d['output'] = ['- Output layers', lambda x: x if x else 'Not specified, inherited from the model']
@@ -530,7 +535,8 @@ def remove_shape_from_input_value(input_value: str):
:param input_value: string passed as input to the "input" command line parameter
:return: string without shape specification
"""
assert '->' not in input_value, 'The function should not be called for input_value with constant value specified'
if '->' in input_value:
raise Error('Incorrect format of input. Got {}'.format(input_value))
return re.sub(r'[(\[]([0-9\.?, -]*)[)\]]', '', input_value)
@@ -540,8 +546,6 @@ def get_shape_from_input_value(input_value: str):
:param input_value: string passed as input to the "input" command line parameter
:return: the corresponding shape and None if the shape is not specified in the input value
"""
# remove the tensor value from the input_value first
input_value = input_value.split('->')[0]
# parse shape
shape = re.findall(r'[(\[]([0-9\.\?, -]*)[)\]]', input_value)
@@ -556,7 +560,7 @@ def get_shape_from_input_value(input_value: str):
shape = PartialShape([Dimension(dim) for dim in dims])
else:
raise Error("Wrong syntax to specify shape. Use \"input\" "
"\"node_name[shape]->value\"")
"\"node_name[shape]\"")
return shape
@@ -566,33 +570,7 @@ def get_node_name_with_port_from_input_value(input_value: str):
:param input_value: string passed as input to the "input" command line parameter
:return: the corresponding node name with input/output port
"""
return remove_shape_from_input_value(remove_data_type_from_input_value(input_value.split('->')[0]))
def get_value_from_input_value(input_value: str):
"""
Returns the value from the input value string
:param input_value: string passed as input to the "input" command line parameter
:return: the corresponding value or None if it is not specified
"""
parts = input_value.split('->')
value = None
if len(parts) == 2:
value = parts[1]
if value[0] == '[' and value[-1] != ']' or value[0] != '[' and value[-1] == ']':
raise Error("Wrong syntax to specify value. Use \"input\"=\"node_name[shape]->value\"")
if '[' in value.strip(' '):
value = value.replace('[', '').replace(']', '')
if ',' in value:
value = value.replace(' ', '')
value = value.split(',')
else:
value = value.split(' ')
if not isinstance(value, list):
value = ast.literal_eval(value)
elif len(parts) > 2:
raise Error("Wrong syntax to specify value. Use \"input\"=\"node_name[shape]->value\"")
return value
return remove_shape_from_input_value(remove_data_type_from_input_value(input_value))
def partial_shape_prod(shape: [PartialShape, tuple]):
@@ -614,7 +592,7 @@ def parse_input_value(input_value: str):
----------
input_value
string with a specified node name, shape, value and data_type.
E.g. 'node_name:0[4]{fp32}->[1.0 2.0 3.0 4.0]'
E.g. 'node_name:0[4]{fp32}'
Returns
-------
@@ -623,19 +601,9 @@ def parse_input_value(input_value: str):
"""
data_type = get_data_type_from_input_value(input_value)
node_name = get_node_name_with_port_from_input_value(input_value)
value = get_value_from_input_value(input_value)
shape = get_shape_from_input_value(input_value)
value_size = np.prod(len(value)) if isinstance(value, list) else 1
if value is not None and shape is not None:
for dim in shape:
if isinstance(dim, Dimension) and dim.is_dynamic:
raise Error("Cannot freeze input with dynamic shape: {}".format(shape))
if shape is not None and value is not None and partial_shape_prod(shape) != value_size:
raise Error("The shape '{}' of the input node '{}' does not correspond to the number of elements '{}' in the "
"value: {}".format(shape, node_name, value_size, value))
return node_name if node_name else None, shape, value, data_type
return node_name if node_name else None, shape, data_type
def split_str_avoiding_square_brackets(s: str) -> list:
@@ -818,65 +786,6 @@ def get_layout_values(argv_layout: str = '', argv_source_layout: str = '', argv_
return res_list
#TODO: Should be removed?
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):
"""
Parses values for placeholder freezing and input node names
Parameters
----------
argv_input
string with a list of input layers: either an empty string, or strings separated with comma.
'node_name1[shape1]->value1,node_name2[shape2]->value2,...'
Returns
-------
parsed placeholders with values for freezing
input nodes cleaned from shape info
"""
placeholder_values = {}
input_node_names = None
if argv_input is not None:
input_node_names = ''
# walkthrough all input values and save values for freezing
for input_value in split_inputs(argv_input):
node_name, _, value, _ = parse_input_value(input_value)
input_node_names = input_node_names + ',' + node_name if input_node_names != '' else node_name
if value is None: # no value is specified for freezing
continue
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))
placeholder_values[node_name] = value
return placeholder_values, input_node_names
def split_inputs(input_str):
brakets_count = 0
inputs = []
@@ -942,13 +851,28 @@ def get_model_name(path_input_model: str) -> str:
def get_model_name_from_args(argv: argparse.Namespace):
output_dir = os.getcwd()
if hasattr(argv, 'output_model') and argv.output_model:
model_name = argv.output_model
else:
model_name = argv.input_model
if isinstance(model_name, (tuple, list)) and len(model_name) > 0:
model_name = model_name[0]
return model_name
if not os.path.isdir(argv.output_model):
if not model_name.endswith('.xml'):
model_name += '.xml'
return model_name
else:
if not os.access(argv.output_model, os.W_OK):
raise Error('The directory "{}" is not writable'.format(argv.output_model))
output_dir = argv.output_model
input_model = argv.input_model
if isinstance(input_model, (tuple, list)) and len(input_model) > 0:
input_model = input_model[0]
if not isinstance(input_model, (str, pathlib.Path)):
return output_dir
input_model_name = os.path.splitext(os.path.split(input_model)[1])[0]
return os.path.join(output_dir, input_model_name + ".xml")
def get_absolute_path(path_to_file: str) -> str:
@@ -1033,7 +957,7 @@ def check_bool(value):
def depersonalize(value: str, key: str):
dir_keys = [
'output_dir', 'extension', 'saved_model_dir', 'tensorboard_logdir', 'caffe_parser_path'
'extension'
]
if isinstance(value, list):
updated_value = []
+16 -32
View File
@@ -1,26 +1,21 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import pathlib
from collections import namedtuple
from typing import Any
from openvino.runtime import PartialShape, Shape, Model # pylint: disable=no-name-in-module,import-error
from openvino.runtime import Model # pylint: disable=no-name-in-module,import-error
from openvino.tools.ovc.cli_parser import get_all_cli_parser
from openvino.tools.ovc.convert_impl import _convert
from openvino.tools.ovc.logger import get_logger_state, restore_logger_state
from openvino.tools.ovc.cli_parser import get_all_cli_parser
#TODO: Why names InputCutInfo and InputInfo are different
InputCutInfo = namedtuple("InputInfo", ["name", "shape", "type", "value"], defaults=[None, None, None, None])
def convert_model(
input_model: [str, pathlib.Path, Any, list], # TODO: Instead of list just accept arbitrary number of positional arguments
# Framework-agnostic parameters
input: [str, list, tuple, InputCutInfo] = None,
input: [list, dict] = None,
output: [str, list] = None,
example_input: Any = None,
extension: [str, pathlib.Path, list, Any] = None,
@@ -63,27 +58,18 @@ def convert_model(
paddle.fluid.executor.Executor
:param input:
Input can be set by passing a list of InputCutInfo objects or by a list
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.
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,
if input node is not a parameter, data type is set to f32. Example, to set
`input_1` with shape [1,100], and Parameter node `sequence_len` with
scalar input with value `150`, and boolean input `is_training` with
`False` value use the following format: "input_1[1,100],sequence_len->150,is_training->False".
Another example, use the following format to set input port 0 of the node
`node_name1` with the shape [3,4] as an input node and freeze output
port 1 of the node `node_name2` with the value [20,15] of the int32 type
and shape [2]: "0:node_name1[3,4],node_name2:1[2]{i32}->[20,15]".
Information of model input required for model conversion.
Input can be set by a list of tuples or a dictionary. Each tuple can contain optionally input name (string),
input type (ov.Type, numpy.dtype) or input shape (ov.Shape, ov.PartialShape, list, tuple).
Example: input=("op_name", PartialShape([-1, 3, 100, 100]), ov.Type.f32).
Alternatively input can be set by a dictionary, where key - input name,
value - tuple with input parameters (shape or type).
Example 1: input={"op_name_1": ([1, 2, 3], ov.Type.f32), "op_name_2": ov.Type.i32}
Example 2: input=[("op_name_1", [1, 2, 3], ov.Type.f32), ("op_name_2", ov.Type.i32)]
Example 3: input=[([1, 2, 3], ov.Type.f32), ov.Type.i32]
The order of inputs in converted model will match the order of specified inputs.
If data type is not specified explicitly data type is taken from the original node data type.
:param output:
The name of the output operation of the model or list of names. For TensorFlow*,
do not add :0 to this name.The order of outputs in converted model is the
@@ -96,9 +82,7 @@ def convert_model(
:param extension:
Paths to libraries (.so or .dll) with extensions, comma-separated
list of paths, objects derived from BaseExtension class or lists of
objects. For the legacy MO path (if "use_legacy_frontend" is used),
a directory or a comma-separated list of directories with extensions
are supported. To disable all extensions including those that are placed
objects. To disable all extensions including those that are placed
at the default location, pass an empty string.
:param verbose:
Print detailed information about conversion.
+8 -28
View File
@@ -21,9 +21,8 @@ from openvino.tools.ovc.moc_frontend.check_config import new_extensions_used
from openvino.tools.ovc.moc_frontend.pipeline import moc_pipeline
from openvino.tools.ovc.moc_frontend.moc_emit_ir import moc_emit_ir
from openvino.tools.ovc.convert_data_type import destination_type_to_np_data_type
from openvino.tools.ovc.cli_parser import get_available_front_ends, \
get_common_cli_options, get_model_name_from_args, depersonalize, get_mo_convert_params, \
input_to_input_cut_info, freeze_placeholder_to_input_cut_info
from openvino.tools.ovc.cli_parser import get_available_front_ends, get_common_cli_options, depersonalize, \
get_mo_convert_params, input_to_input_cut_info
from openvino.tools.ovc.help import get_convert_model_help_specifics
from openvino.tools.ovc.error import Error, FrameworkError
@@ -57,10 +56,10 @@ def replace_ext(name: str, old: str, new: str):
return base + new
def print_argv(argv: argparse.Namespace, model_name: str):
def print_argv(argv: argparse.Namespace):
print('Model Conversion arguments:')
props = OrderedDict()
props['common_args'] = get_common_cli_options(model_name)
props['common_args'] = get_common_cli_options(argv, argv.is_python_api_used)
framework_specifics_map = {
'common_args': 'Common parameters:'
@@ -80,10 +79,11 @@ def print_argv(argv: argparse.Namespace, model_name: str):
def arguments_post_parsing(argv: argparse.Namespace):
# TODO: This function looks similar to another one. Check for code duplicates.
log.debug("Model Conversion API started")
log.debug('Output model name would be {}{{.xml, .bin}}'.format(argv.output_model))
if not argv.is_python_api_used:
log.debug('Output model name would be {}{{.xml, .bin}}'.format(argv.output_model))
if argv.verbose:
print_argv(argv, argv.output_model)
print_argv(argv)
params_parsing(argv)
argv.output = argv.output.split(',') if isinstance(argv.output, (str, pathlib.Path)) else argv.output
@@ -287,10 +287,6 @@ def params_parsing(argv: argparse.Namespace):
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
@@ -308,13 +304,6 @@ def params_parsing(argv: argparse.Namespace):
argv.inputs_list = input_names_list
argv.input = ','.join(input_names_list)
# 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(inputs)
if len(input_names_list) > 0:
# Named inputs case
shape_dict = {}
@@ -401,10 +390,6 @@ def is_verbose(argv: argparse.Namespace):
def _convert(cli_parser: argparse.ArgumentParser, args, python_api_used):
# FIXME: It doesn't work when -h is passed
if 'help' in args and args['help']:
show_mo_convert_help()
return None, None
simplified_ie_version = VersionChecker().get_ie_simplified_version()
telemetry = init_mo_telemetry()
telemetry.start_session('ovc')
@@ -460,11 +445,6 @@ def _convert(cli_parser: argparse.ArgumentParser, args, python_api_used):
non_default_params = get_non_default_params(argv, cli_parser)
argv.is_python_api_used = python_api_used
if inp_model_is_object:
argv.output_model = "model" # TODO: Consider removing
if not hasattr(argv, "output_model") or argv.output_model is None:
argv.output_model = get_model_name_from_args(argv)
argv.framework = model_framework
ov_model = driver(argv, {"conversion_parameters": non_default_params})
@@ -494,7 +474,7 @@ def _convert(cli_parser: argparse.ArgumentParser, args, python_api_used):
if isinstance(e, (FileNotFoundError, NotADirectoryError)):
log.error('File {} was not found'.format(str(e).split('No such file or directory:')[1]))
log.debug(traceback.format_exc())
elif isinstance(e, Error):
elif isinstance(e, (Error, OpConversionFailure)):
log.error(e)
log.debug(traceback.format_exc())
elif isinstance(e, FrameworkError):
+12 -61
View File
@@ -8,77 +8,28 @@ def get_convert_model_help_specifics():
'input_model':
{'description':
'Input model file(s) from TensorFlow, ONNX, PaddlePaddle. '
'Use openvino.convert_model in Python to convert models from Pytorch.'
'Use openvino.convert_model in Python to convert models from PyTorch.'
'',
'action': CanonicalizePathCheckExistenceAction,
'type': readable_dirs_or_files_or_empty,
'aliases': {}},
'input_shape':
{'description':
'Input shape(s) that should be fed to an input node(s) '
'of the model. Shape is defined as a comma-separated '
'list of integer numbers enclosed in parentheses or '
'square brackets, for example [1,3,227,227] or '
'(1,227,227,3), where the order of dimensions depends '
'on the framework input layout of the model. For '
'example, [N,C,H,W] is used for ONNX* models and '
'[N,H,W,C] for TensorFlow* models. The shape can '
'contain undefined dimensions (? or -1) and should fit '
'the dimensions defined in the input operation of the '
'graph. Boundaries of undefined dimension can be '
'specified with ellipsis, for example '
'[1,1..10,128,128]. One boundary can be undefined, for '
'example [1,..100] or [1,3,1..,1..]. If there are '
'multiple inputs in the model, --input_shape should '
'contain definition of shape for each input separated '
'by a comma, for example: [1,3,227,227],[2,4] for a '
'model with two inputs with 4D and 2D shapes. '
'Alternatively, specify shapes with the --input option.'},
'input':
{'description':
'Information for model input required for model conversion. '
'Information of model input required for model conversion. '
'This is a comma separated list with optional '
'input names, shapes, data types, and values for freezing. '
'The order of inputs in converted model will match the order of '
'specified inputs. 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, if input node is not a parameter, '
'data type is set to f32. Example, to set `input_1` '
'with shape [1,100], and Parameter node `sequence_len` '
'with scalar input with value `150`, and boolean input '
'`is_training` with `False` value use the following '
'format: \n '
'\"input_1[1,100],sequence_len->150,is_training->False\". '
'Another example, use the following format to set input '
'port 0 of the node `node_name1` with the shape [3,4] '
'as an input node and freeze output port 1 of the node '
'\"node_name2\" with the value [20,15] of the int32 type '
'and shape [2]: \n '
'\"0:node_name1[3,4],node_name2:1[2]{i32}->[20,15]\".'},
'transform':
{'description':
'Apply additional transformations. Usage: \"--transform '
'transformation_name1[args],transformation_name2...\" '
'where [args] is key=value pairs separated by '
'semicolon. Examples: \"--transform LowLatency2\" or \"--'
'transform Pruning" or "--transform '
'LowLatency2[use_const_initializer=False]" or "--'
'transform "MakeStateful[param_res_names= {\'input_name_1\':'
'\'output_name_1\',\'input_name_2\':\'output_name_2\'}]\" \n'
'Available transformations: "LowLatency2", "MakeStateful", "Pruning"'},
'input names, shapes and data types. The order of inputs '
'in converted model will match the order of '
'specified inputs. The shape is specified as comma-separated list. '
'The data type of input node is specified in braces and can have one of '
'the values: f64, f32, f16, i64, i32, u8, boolean. If data type is not '
'specified explicitly then data type is taken from the '
'original node data type. Example, to set `input_1` input '
'with shape [1,100] and float32 type, and `sequence_len` input '
'with int32 type \"input_1[1,100]{f32},sequence_len{i32}\".'},
'extension':
{'description':
'Paths or a comma-separated list of paths to libraries '
'(.so or .dll) with extensions. For the legacy MO path '
'(if `--use_legacy_frontend` is used), a directory or a '
'comma-separated list of directories with extensions '
'are supported. To disable all extensions including '
'(.so or .dll) with extensions. To disable all extensions including '
'those that are placed at the default location, pass an empty string.',
'action': CanonicalizePathCheckExistenceAction,
'type': readable_files_or_empty},
+2 -4
View File
@@ -10,7 +10,7 @@ try:
except ImportError:
import openvino.tools.ovc.telemetry_stub as tm
from openvino.tools.ovc.convert_impl import _convert
from openvino.tools.ovc.utils import get_ir_version
from openvino.tools.ovc.cli_parser import get_model_name_from_args
# pylint: disable=no-name-in-module,import-error
from openvino.runtime import serialize
@@ -22,9 +22,7 @@ def main():
if ngraph_function is None:
return 1
output_dir = os.getcwd()
model_path_no_ext = os.path.normpath(os.path.join(output_dir, argv.output_model))
model_path = model_path_no_ext + '.xml'
model_path = get_model_name_from_args(argv)
# TODO: replace compress_model + serialize with save_model
if argv.compress_to_fp16:
@@ -97,8 +97,3 @@ def legacy_transformations_config_used(argv: argparse.Namespace):
def tensorflow_custom_operations_config_update_used(argv: argparse.Namespace):
return hasattr(argv, 'tensorflow_custom_operations_config_update') and \
argv.tensorflow_custom_operations_config_update is not None
def input_freezig_used(argv):
return hasattr(argv, 'freeze_placeholder_with_value') and argv.freeze_placeholder_with_value is not None \
and len(argv.freeze_placeholder_with_value) > 0
@@ -336,16 +336,15 @@ def fe_output_user_data_repack(input_model: InputModel, outputs: list, framework
node = decode_name_with_port(input_model, output, framework, IOType.Output)
if node is None:
raise Error("Cannot find location {} in the graph".format(output))
_outputs.append({"node": node})
_outputs.append({"node": node, "output_name": output})
return _outputs
def find_first_unused_input(model_inputs: list, freeze_placeholder: dict, param_dict: dict, param_name: str):
def find_first_unused_input(model_inputs: list, 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.
@@ -355,7 +354,7 @@ def find_first_unused_input(model_inputs: list, freeze_placeholder: dict, param_
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:
if input_name in param_dict:
name_found = True
break
if name_found:
@@ -366,17 +365,13 @@ def find_first_unused_input(model_inputs: list, freeze_placeholder: dict, param_
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):
input_user_data_types: [list, dict]):
"""
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;
@@ -395,7 +390,7 @@ def convert_params_lists_to_dicts(input_model,
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")
inp_name = find_first_unused_input(model_inputs, input_user_shapes_dict, "shape")
input_user_shapes_dict[inp_name] = shape
else:
input_user_shapes_dict = input_user_shapes
@@ -413,7 +408,7 @@ def convert_params_lists_to_dicts(input_model,
"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")
inp_name = find_first_unused_input(model_inputs, 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.
@@ -422,15 +417,8 @@ def convert_params_lists_to_dicts(input_model,
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
return input_user_shapes_dict, input_user_data_types_dict
def fe_user_data_repack(
@@ -38,6 +38,17 @@ def get_enabled_and_disabled_transforms():
return enabled_transforms, disabled_transforms
def raise_exception_for_input_output_cut(model_inputs_or_outputs: List[Place], new_nodes: List[dict], is_input: bool):
for new_node in new_nodes:
node = new_node['node']
if not any([item.is_equal(node) for item in model_inputs_or_outputs]):
if is_input:
raise Exception("Name {} is not found among model inputs.".format(new_node['input_name']))
else:
raise Exception("Name {} is not found among model outputs.".format(new_node['output_name']))
def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
"""
Load input model and convert it to nGraph function
@@ -62,13 +73,12 @@ def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
outputs = fe_output_user_data_repack(input_model, argv.output, moc_front_end.get_name())
input_model.override_all_outputs([x['node'] for x in outputs])
'''
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)
argv.placeholder_shapes, argv.placeholder_data_types = convert_params_lists_to_dicts(
input_model, argv.placeholder_shapes, argv.placeholder_data_types)
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())
argv.output, {}, moc_front_end.get_name())
def check_places_are_same(places_original: List[Place], places_new: List[Place]):
"""
@@ -109,10 +119,17 @@ def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
model_inputs = input_model.get_inputs()
inputs_equal = True
if user_shapes:
# TODO: Remove this line when new 'cut' helper is introduced
raise_exception_for_input_output_cut(model_inputs, user_shapes, True)
inputs_equal = check_places_are_same(model_inputs, user_shapes)
outputs_equal = True
if outputs:
# TODO: Remove this line when new 'cut' helper is introduced
raise_exception_for_input_output_cut(input_model.get_outputs(), outputs, False)
outputs_equal = check_places_are_same(input_model.get_outputs(), outputs)
log.debug('Inputs are same: {}, outputs are same: {}'.format(
inputs_equal, outputs_equal))
@@ -138,7 +155,7 @@ def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
user_shapes, outputs, _ = fe_user_data_repack(
input_model, placeholder_shapes, argv.placeholder_data_types,
new_output_places_name, argv.freeze_placeholder_with_value, moc_front_end.get_name())
new_output_places_name, {}, moc_front_end.get_name())
elif not inputs_equal:
log.debug('Using override_all_inputs')
add_names_to_tensors(input_model, user_shapes)
@@ -150,7 +167,7 @@ def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
user_shapes, outputs, _ = fe_user_data_repack(
input_model, placeholder_shapes, argv.placeholder_data_types,
argv.output, argv.freeze_placeholder_with_value, moc_front_end.get_name())
argv.output, {}, moc_front_end.get_name())
elif not outputs_equal:
log.debug('Using override_all_outputs')
add_names_to_tensors(input_model, user_shapes)
@@ -226,11 +243,6 @@ def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
def shape_to_array(shape: PartialShape):
return [shape.get_dimension(i) for i in range(shape.rank.get_length())]
# obtain layout for all inputs
layout_values = {}
if 'layout_values' in argv and argv.layout_values:
layout_values = update_layout_to_dict(model_inputs, argv.layout_values,
lambda input_place: input_place.get_names())
ov_model = moc_front_end.convert(input_model)
@@ -29,7 +29,6 @@ def arg_parse_helper(input_model,
transform=[],
output=None,
input=None,
output_dir='.',
compress_to_fp16=compress_to_fp16,
extension=None
)
@@ -35,132 +35,23 @@ class TestMoFreezePlaceholderTFFE(unittest.TestCase):
assert np.allclose(values, expected)
@generate(
*[
(
"in1[1 4]->[1.0 2.0 3.0 4.0],in2[1 4]{f32}->[1.0 2.0 3.0 4.0]",
{},
np.array([2.0, 4.0, 6.0, 8.0]),
np.float32,
),
(
"in2{f32}->[0.0 0.0 0.0 0.0]",
{"in1": np.array([[1.0, 2.0], [3.0, 4.0]])},
np.array([[1.0, 2.0], [3.0, 4.0]]),
np.float32,
),
(
"in2->[1.0 15.0 15.5 1.0]",
{"in1": np.array([[2.0, 4.0], [12.0, 8.0]])},
np.array([[3.0, 19.0], [27.5, 9.0]]),
np.float32,
),
(
"in1[1 4]{i32}->[1 2 3 4],in2[1 4]{i32}->[1 2 3 4]",
{},
np.array([2.0, 4.0, 6.0, 8.0]),
np.int32,
),
],
)
def test_fp32(self, input_freezing_value, inputs, expected,
dtype):
self.basic("model_fp32.pbtxt", input_freezing_value, inputs, dtype, expected)
@generate(
*[
(
"in1[1 4]->[1 2 3 4],in2[1 4]{i32}->[1 2 3 4]",
{},
np.array([1, 4, 9, 16]),
np.int32,
),
(
"in2->[2 5 6 7 3 2]",
{"in1": np.array([[2, 4, 1], [1, 2, 8]])},
np.array([[4, 20, 6], [7, 6, 16]]),
np.int32,
),
],
)
def test_int32(self, input_freezing_value, inputs, expected,
dtype=None):
self.basic("model_int32.pbtxt", input_freezing_value, inputs, dtype, expected)
@generate(
*[
(
"in1[2]->[True False],in2[2]->[True True]",
{},
np.array([True, False], dtype=bool),
bool,
),
(
"in2[2,3]->[True,True,False,True,True,False]",
{"in1": np.array([[False, True, True], [False, True, True]], dtype=bool)},
np.array([[False, True, False], [False, True, False]], dtype=bool),
bool,
),
(
"in2[]->True",
{"in1": np.array([[False, True, True], [False, True, True]], dtype=bool)},
np.array([[False, True, True], [False, True, True]], dtype=bool),
bool,
),
],
)
def test_bool(self, input_freezing_value, inputs, expected,
dtype=None):
self.basic("model_bool.pbtxt", input_freezing_value, inputs, dtype, expected)
@generate(
*[
(
"in1[3]->[1 2 3],in2[3]->[4 5 6],cond->False",
{},
np.array([4, 5, 6], dtype=np.float32),
np.float32,
None
),
(
"in1,in2,cond->False",
{"in1": np.array([2.0, 4.0, 6.0], dtype=np.float32),
"in2": np.array([1.0, 3.0, 5.0], dtype=np.float32)},
np.array([2, 4, 6], dtype=np.float32),
np.float32,
True # fill a bug to investigate why compilation of this model is hang on
),
# case: input_shape + freeze_placeholder_with_value
(
"in2,in1->[2.0 4.0 6.0],cond->True",
{"in2": np.array([1.0, 3.0, 5.0], dtype=np.float32)},
np.array([2, 4, 6], dtype=np.float32),
np.float32,
False
),
],
)
def test_bool2(self, input_freezing_value, inputs, expected,
dtype=None, only_conversion=False):
self.basic("model_bool2.pbtxt", input_freezing_value, inputs, dtype, expected,
only_conversion)
@generate(
*[
(
"add:0[3],z",
{"add:0": np.array([4, 5, 6], dtype=np.float32), "z": np.array([1, 2, 3], dtype=np.float32)},
np.array([4, 10, 18], dtype=np.float32),
np.float32,
None
),
(
"add:0{i32}[3],z{i32}",
{"add:0": np.array([4, 5, 6], dtype=np.int32), "z": np.array([1, 2, 3], dtype=np.int32)},
np.array([4, 10, 18], dtype=np.int32),
np.int32,
None
),
],
# TODO: Return this test when new 'cut' helper is introduced
# *[
# (
# "add:0[3],z",
# {"add:0": np.array([4, 5, 6], dtype=np.float32), "z": np.array([1, 2, 3], dtype=np.float32)},
# np.array([4, 10, 18], dtype=np.float32),
# np.float32,
# None
# ),
# (
# "add:0{i32}[3],z{i32}",
# {"add:0": np.array([4, 5, 6], dtype=np.int32), "z": np.array([1, 2, 3], dtype=np.int32)},
# np.array([4, 10, 18], dtype=np.int32),
# np.int32,
# None
# ),
# ],
)
def test_cutting_fp32(self, input_freezing_value, inputs, expected,
dtype=None, only_conversion=False):
@@ -169,20 +60,21 @@ class TestMoFreezePlaceholderTFFE(unittest.TestCase):
@generate(
*[
(
"x[1,4],y[4]",
{"x": np.array([[3, 2, 1, 5]], dtype=np.int32), "y": np.array([0, -1, -7, 8], dtype=np.int32)},
np.array([[3, 1, -6, 13]], dtype=np.int32),
np.int32,
None
),
(
"x,y",
{"x": np.array([[-3, 20, 1]], dtype=np.int32), "y": np.array([[10, -11, -17]], dtype=np.int32)},
np.array([[7, 9, -16]], dtype=np.int32),
np.int32,
None
),
# TODO: Return this test when new 'cut' helper is introduced
# (
# "x[1,4],y[4]",
# {"x": np.array([[3, 2, 1, 5]], dtype=np.int32), "y": np.array([0, -1, -7, 8], dtype=np.int32)},
# np.array([[3, 1, -6, 13]], dtype=np.int32),
# np.int32,
# None
# ),
# (
# "x,y",
# {"x": np.array([[-3, 20, 1]], dtype=np.int32), "y": np.array([[10, -11, -17]], dtype=np.int32)},
# np.array([[7, 9, -16]], dtype=np.int32),
# np.int32,
# None
# ),
(
"x",
{"x": np.array([[-3, 20, 1]], dtype=np.int32)},
@@ -197,28 +89,6 @@ class TestMoFreezePlaceholderTFFE(unittest.TestCase):
self.basic("placeholder_with_default.pbtxt", inputs, inputs_data, dtype, expected,
only_conversion)
@generate(
*[
(
"x[4],y->2.0",
{"x": np.array([3, 2, 1, 5], dtype=np.float32)},
np.array([6, 4, 2, 10], dtype=np.float32),
np.float32,
None
),
(
"x[1],y->[2.0,3.0]",
{"x": np.array([3], dtype=np.float32)},
np.array([6, 9], dtype=np.float32),
np.float32,
None
),
],
)
def test_freeze_placeholder_with_unknown_rank(self, inputs, inputs_data, expected,
dtype=None, only_conversion=False):
self.basic("mul_with_unknown_rank_y.pbtxt", inputs, inputs_data, dtype, expected,
only_conversion)
def test_conversion_model_oneshot_iterator_default(self):
self.basic("model_oneshot_iterator.pbtxt", None, None, None, None, True)
@@ -7,7 +7,6 @@ from pathlib import Path
from generator import generator, generate
from openvino.runtime import serialize
from openvino.tools.ovc import InputCutInfo
from unit_tests.ovc.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
from unit_tests.ovc.convert.utils import create_onnx_model, save_to_onnx
@@ -56,8 +55,7 @@ class ConvertImportMOTest(UnitTestWithMockedTelemetry):
return onnx_net
@generate(*[
({}),
({'input': InputCutInfo(name='LeakyRelu_out', shape=None, type=None, value=None)}),
({})
])
# Checks convert import from openvino.tools.mo
def test_import(self, params):
@@ -71,7 +71,7 @@ class MetaDataTest(UnitTestWithMockedTelemetry):
if key == 'conversion_parameters':
for param_name, param_value in value.items():
val = ov_model.get_rt_info([key, param_name]).astype(str)
if param_name in ['extension', 'caffe_parser_path', 'input_model', 'k', 'output_dir']:
if param_name in ['extension', 'input_model']:
val = Path(val)
assert val == param_value, \
"Runtime info attribute with name {} does not match. Expected: {}, " \
@@ -21,7 +21,7 @@ class MetaDataTestTF(unittest.TestCase):
if key == 'conversion_parameters':
for param_name, param_value in value.items():
val = ov_model.get_rt_info([key, param_name]).astype(str)
if param_name in ['extension', 'caffe_parser_path', 'input_model', 'k', 'output_dir']:
if param_name in ['extension', 'input_model']:
val = Path(val)
assert val == param_value, \
"Runtime info attribute with name {} does not match. Expected: {}, " \
+111 -191
View File
@@ -12,15 +12,14 @@ from unittest.mock import patch
import numpy as np
from openvino.tools.ovc.cli_parser import input_to_input_cut_info, \
check_positive, writable_dir, \
readable_file_or_object, get_freeze_placeholder_values, get_all_cli_parser, \
get_mo_convert_params
from openvino.tools.ovc.cli_parser import input_to_input_cut_info, check_positive, writable_dir, \
readable_file_or_object, get_all_cli_parser, get_mo_convert_params
from openvino.tools.ovc.convert_impl import pack_params_to_args_namespace
from openvino.tools.ovc.error import Error
from unit_tests.ovc.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
from openvino.runtime import PartialShape, Dimension, Layout
from openvino.tools.ovc import InputCutInfo
from openvino.tools.ovc.cli_parser import _InputCutInfo
import openvino.runtime as ov
class TestShapesParsing(UnitTestWithMockedTelemetry):
@@ -28,152 +27,119 @@ class TestShapesParsing(UnitTestWithMockedTelemetry):
# shapes specified using --input command line parameter and no values
argv_input = "inp1[1,22,333,123],inp2[-1,45,7,1]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([1,22,333,123])),
InputCutInfo(name='inp2', shape=PartialShape([-1,45,7,1]))]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([1,22,333,123])),
_InputCutInfo(name='inp2', shape=PartialShape([-1,45,7,1]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_and_freezing_with_scalar_and_without_shapes_in_input(self):
# shapes and value for freezing specified using --input command line parameter
argv_input = "inp1,inp2->157"
argv_input = "inp1,inp2"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1'),
InputCutInfo(name='inp2', value=157)]
inputs_ref = [_InputCutInfo(name='inp1'),
_InputCutInfo(name='inp2')]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp2': 157}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
self.assertEqual(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_and_freezing_with_scalar(self):
# shapes and value for freezing specified using --input command line parameter
argv_input = "inp1,inp2[]->157"
argv_input = "inp1,inp2[]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1'),
InputCutInfo(name='inp2', shape=PartialShape([]), value=157)]
inputs_ref = [_InputCutInfo(name='inp1'),
_InputCutInfo(name='inp2', shape=PartialShape([]))]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_several_inputs_several_shapes3(self):
# shapes and value for freezing specified using --input command line parameter
argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3,2,3],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1[3 1],inp2[3,2,3],inp3[5]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
InputCutInfo(name='inp3', shape=PartialShape([5]), value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
_InputCutInfo(name='inp3', shape=PartialShape([5]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_shapes3_comma_sep(self):
# shapes and value for freezing specified using --input command line parameter
argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[5]->[1.0, 1.0, 2.0, 3.0,5.0]"
argv_input = "inp1[3 1],inp2[3 2 3],inp3[5]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
InputCutInfo(name='inp3', shape=PartialShape([5]), value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
_InputCutInfo(name='inp3', shape=PartialShape([5]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_shapes6(self):
# 0D value for freezing specified using --input command line parameter without shape
argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3,2,3],inp3->False"
argv_input = "inp1[3,1],inp2[3,2,3],inp3"
inputs_list, result, _ = input_to_input_cut_info(argv_input)
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
InputCutInfo(name='inp3', value=False)]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
_InputCutInfo(name='inp3')]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': False}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_shapes7(self):
# 0D shape and value for freezing specified using --input command line parameter
argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3,2,3],inp3[]->True"
argv_input = "inp1[3,1],inp2[3,2,3],inp3[]"
inputs_list, result, _ = input_to_input_cut_info(argv_input)
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
InputCutInfo(name='inp3', shape=PartialShape([]), value=True)]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3])),
_InputCutInfo(name='inp3', shape=PartialShape([]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': True}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_and_data_types1(self):
argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{i32},inp3[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1[3 1],inp2[3 2 3]{i32},inp3[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
InputCutInfo(name='inp3', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
_InputCutInfo(name='inp3', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_with_input_ports(self):
argv_input = "1:inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{i32},0:inp3[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "1:inp1[3 1],inp2[3 2 3]{i32},0:inp3[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='1:inp1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
InputCutInfo(name='0:inp3', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='1:inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
_InputCutInfo(name='0:inp3', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_with_output_ports(self):
argv_input = "inp1:1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1:1[3 1],inp2[3 2 3]{i32},inp3:4[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1:1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1:1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
_InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_with_output_ports_comma_sep(self):
argv_input = "inp1:1[3,1]->[1.0,2.0 ,3.0],inp2[3,2, 3]{i32},inp3:4[5]{f32}->[1.0, 1.0,2.0, 3.0,5.0]"
argv_input = "inp1:1[3,1],inp2[3,2, 3]{i32},inp3:4[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1:1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1:1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape([3,2,3]), type=np.int32),
_InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_shape_only(self):
argv_input = "placeholder1[3 1],placeholder2,placeholder3"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='placeholder1', shape=PartialShape([3,1])),
InputCutInfo(name='placeholder2'),
InputCutInfo(name='placeholder3')]
inputs_ref = [_InputCutInfo(name='placeholder1', shape=PartialShape([3,1])),
_InputCutInfo(name='placeholder2'),
_InputCutInfo(name='placeholder3')]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_shape_with_ports_only(self):
argv_input = "placeholder1:4[3 1],placeholder2,2:placeholder3"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='placeholder1:4', shape=PartialShape([3,1])),
InputCutInfo(name='placeholder2'),
InputCutInfo(name='2:placeholder3')]
inputs_ref = [_InputCutInfo(name='placeholder1:4', shape=PartialShape([3,1])),
_InputCutInfo(name='placeholder2'),
_InputCutInfo(name='2:placeholder3')]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_when_no_freeze_value(self):
argv_input = "placeholder1{i32}[3 1],placeholder2,placeholder3{i32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='placeholder1', shape=PartialShape([3,1]), type=np.int32),
InputCutInfo(name='placeholder2'),
InputCutInfo(name='placeholder3', type=np.int32)]
inputs_ref = [_InputCutInfo(name='placeholder1', shape=PartialShape([3,1]), type=np.int32),
_InputCutInfo(name='placeholder2'),
_InputCutInfo(name='placeholder3', type=np.int32)]
self.assertEqual(inputs, inputs_ref)
def test_wrong_data_types(self):
@@ -185,13 +151,6 @@ class TestShapesParsing(UnitTestWithMockedTelemetry):
argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[5 3]->[2.0 3.0 5.0]"
self.assertRaises(Error, input_to_input_cut_info, argv_input)
def test_wrong_data_for_input_cmd_param(self):
# test that wrongly formatted data specified in --input is handled properly
argv_input = "abc->[1.0"
self.assertRaises(Error, get_freeze_placeholder_values, argv_input)
argv_input = "def[2 2]->[1.0 2.0 3.0 4.0],abc->1.0 34]"
self.assertRaises(Error, get_freeze_placeholder_values, argv_input)
def test_get_shapes_no_input_no_shape(self):
argv_input = ""
inputs = input_to_input_cut_info(argv_input)
@@ -202,106 +161,84 @@ class TestShapesParsing(UnitTestWithMockedTelemetry):
def test_get_shapes_no_input_one_shape2(self):
argv_input = "[12,4,1]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(shape=PartialShape([12,4,1]))]
inputs_ref = [_InputCutInfo(shape=PartialShape([12,4,1]))]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_for_scalar_inputs(self):
argv_input = "[]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(shape=PartialShape([]))]
inputs_ref = [_InputCutInfo(shape=PartialShape([]))]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_two_input_shapes_with_scalar(self):
argv_input = "[12,4,1],[]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(shape=PartialShape([12,4,1])),
InputCutInfo(shape=PartialShape([]))]
inputs_ref = [_InputCutInfo(shape=PartialShape([12,4,1])),
_InputCutInfo(shape=PartialShape([]))]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_two_input_shapes(self):
argv_input = "[12,4,1],[10]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(shape=PartialShape([12,4,1])),
InputCutInfo(shape=PartialShape([10])),]
inputs_ref = [_InputCutInfo(shape=PartialShape([12,4,1])),
_InputCutInfo(shape=PartialShape([10])),]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_one_input_no_shape(self):
argv_input = "inp1"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1')]
inputs_ref = [_InputCutInfo(name='inp1')]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_several_inputs_several_partial_shapes2(self):
# shapes specified using --input command line parameter and no values
argv_input = "inp1[1,?,50..100,123],inp2[-1,45..,..7,1]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape("[1,?,50..100,123]")),
InputCutInfo(name='inp2', shape=PartialShape("[-1,45..,..7,1]"))]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape("[1,?,50..100,123]")),
_InputCutInfo(name='inp2', shape=PartialShape("[-1,45..,..7,1]"))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_partial_shapes3(self):
# shapes and value for freezing specified using --input command line parameter
argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3..,..2,5..10,?,-1],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1[3,1],inp2[3..,..2,5..10,?,-1],inp3[5]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=["1.0", "2.0", "3.0"]),
InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
InputCutInfo(name='inp3', shape=PartialShape([5]), value=["1.0", "1.0", "2.0", "3.0", "5.0"])]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
_InputCutInfo(name='inp3', shape=PartialShape([5]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
input_node_names_ref = "inp1,inp2,inp3"
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_partial_shapes6(self):
# 0D value for freezing specified using --input command line parameter without shape
argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3.. ..2 5..10 ? -1],inp3->False"
argv_input = "inp1[3 1],inp2[3.. ..2 5..10 ? -1],inp3"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=["1.0", "2.0", "3.0"]),
InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
InputCutInfo(name='inp3', value=False)]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
_InputCutInfo(name='inp3')]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': False}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_partial_shapes7(self):
# 0D shape and value for freezing specified using --input command line parameter
argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3.. ..2 5..10 ? -1],inp3[]->True"
argv_input = "inp1[3 1],inp2[3.. ..2 5..10 ? -1],inp3[]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=["1.0", "2.0", "3.0"]),
InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
InputCutInfo(name='inp3', shape=PartialShape([]), value=True)]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
_InputCutInfo(name='inp3', shape=PartialShape([]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': True}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_and_data_types_partial_shape_with_input_port(self):
argv_input = "inp1:1[3 1]->[1.0 2.0 3.0],0:inp2[3.. ..2 5..10 ? -1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1:1[3 1],0:inp2[3.. ..2 5..10 ? -1]{i32},inp3:4[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1:1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='0:inp2', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1:1', shape=PartialShape([3,1])),
_InputCutInfo(name='0:inp2', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
_InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_partial_shape_with_output_port(self):
argv_input = "inp1:1[3 1]->[1.0 2.0 3.0],inp2:3[3.. ..2 5..10 ? -1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1:1[3 1],inp2:3[3.. ..2 5..10 ? -1]{i32},inp3:4[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1:1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2:3', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1:1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2:3', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
_InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_partial_shapes_freeze_dynamic_negative_case1(self):
@@ -316,73 +253,51 @@ class TestShapesParsing(UnitTestWithMockedTelemetry):
# shapes specified using --input command line parameter and no values
argv_input = "inp1[1,?,50..100,123],inp2[-1,45..,..7,1]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape("[1,?,50..100,123]")),
InputCutInfo(name='inp2', shape=PartialShape("[-1,45..,..7,1]"))]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape("[1,?,50..100,123]")),
_InputCutInfo(name='inp2', shape=PartialShape("[-1,45..,..7,1]"))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_partial_shapes3_comma_separator(self):
# shapes and value for freezing specified using --input command line parameter
argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3..,..2,5..10,?,-1],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1[3,1],inp2[3..,..2,5..10,?,-1],inp3[5]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=["1.0", "2.0", "3.0"]),
InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
InputCutInfo(name='inp3', shape=PartialShape([5]), value=["1.0", "1.0", "2.0", "3.0", "5.0"])]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
_InputCutInfo(name='inp3', shape=PartialShape([5]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_partial_shapes6_comma_separator(self):
# 0D value for freezing specified using --input command line parameter without shape
argv_input = "inp1[3, 1]->[1.0 2.0 3.0],inp2[3.., ..2, 5..10, ?,-1],inp3->False"
argv_input = "inp1[3, 1],inp2[3.., ..2, 5..10, ?,-1],inp3"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=["1.0", "2.0", "3.0"]),
InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
InputCutInfo(name='inp3', value=False)]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
_InputCutInfo(name='inp3')]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': False}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_several_inputs_several_partial_shapes7_comma_separator(self):
# 0D shape and value for freezing specified using --input command line parameter
argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3.., ..2,5..10, ?,-1],inp3[]->True"
argv_input = "inp1[3,1],inp2[3.., ..2,5..10, ?,-1],inp3[]"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1', shape=PartialShape([3,1]), value=["1.0", "2.0", "3.0"]),
InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
InputCutInfo(name='inp3', shape=PartialShape([]), value=True)]
inputs_ref = [_InputCutInfo(name='inp1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2', shape=PartialShape("[3..,..2,5..10,?,-1]")),
_InputCutInfo(name='inp3', shape=PartialShape([]))]
self.assertEqual(inputs, inputs_ref)
placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input)
placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': True}
self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
for i in placeholder_values_ref.keys():
assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
def test_get_shapes_and_data_types_partial_shape_with_input_port_comma_separator(self):
argv_input = "inp1:1[3,1]->[1.0 2.0 3.0],0:inp2[ 3.. ,..2, 5..10, ?,-1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1:1[3,1],0:inp2[ 3.. ,..2, 5..10, ?,-1]{i32},inp3:4[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1:1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='0:inp2', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1:1', shape=PartialShape([3,1])),
_InputCutInfo(name='0:inp2', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
_InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_get_shapes_and_data_types_partial_shape_with_output_port_comma_separator(self):
argv_input = "inp1:1[3,1]->[1.0 2.0 3.0],inp2:3[3..,..2,5..10,?,-1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
argv_input = "inp1:1[3,1],inp2:3[3..,..2,5..10,?,-1]{i32},inp3:4[5]{f32}"
inputs = input_to_input_cut_info(argv_input)
inputs_ref = [InputCutInfo(name='inp1:1', shape=PartialShape([3,1]), value=['1.0', '2.0', '3.0']),
InputCutInfo(name='inp2:3', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32, value=['1.0', '1.0', '2.0', '3.0', '5.0'])]
inputs_ref = [_InputCutInfo(name='inp1:1', shape=PartialShape([3,1])),
_InputCutInfo(name='inp2:3', shape=PartialShape("[3..,..2,5..10,?,-1]"), type=np.int32),
_InputCutInfo(name='inp3:4', shape=PartialShape([5]), type=np.float32)]
self.assertEqual(inputs, inputs_ref)
def test_partial_shapes_freeze_dynamic_negative_case1_comma_separator(self):
@@ -401,6 +316,11 @@ class TestShapesParsing(UnitTestWithMockedTelemetry):
argv_input = "inp1:1[1, 2, -1]->[1.0 2.0 3.0]"
self.assertRaises(Error, input_to_input_cut_info, argv_input)
def test_not_supported_arrow(self):
with self.assertRaisesRegex(Exception,
"Incorrect format of input."):
input_to_input_cut_info("inp1->[1.0]")
class PositiveChecker(unittest.TestCase):
def test_positive_checker_batch(self):
@@ -485,7 +405,7 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
from openvino.frontend import ConversionExtension
args = {'input_model': os.path.dirname(__file__),
'extension': ConversionExtension("Ext", lambda x: x),
'input': ['name', InputCutInfo("a", [1,2,3], numpy.float32, [5, 6, 7])],
'input': ['name', ("a", [1,2,3], ov.Type.f32)],
'output': ["a", "b", "c"]}
cli_parser = get_all_cli_parser()
@@ -493,7 +413,7 @@ class TestPackParamsToArgsNamespace(unittest.TestCase):
assert argv.input_model == args['input_model']
assert argv.extension == args['extension']
assert argv.input == ['name', InputCutInfo("a", [1,2,3], numpy.float32, [5, 6, 7])]
assert argv.input == ['name', ("a", [1,2,3], ov.Type.f32)]
assert argv.output == ["a","b","c"]
for arg, value in vars(argv).items():
+1 -1
View File
@@ -57,6 +57,6 @@ except ImportError:
# Tools
try:
# Model Conversion API - ovc should reside in the main namespace
from openvino.tools.ovc import convert_model, InputCutInfo
from openvino.tools.ovc import convert_model
except ImportError:
pass