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:
1 parent
5f71679fb9
commit
59872ee072
39 files changed
+2883
-836
No files matched your search
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+15
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,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
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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: {}, " \
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user