[MO] fix IR graph comparator (#17411)
* fix graph compare (legacy python MO) * fix failing unit-tests * fix failing unit-tests: check that shape is defined * added explanation comment * Apply suggestions from code review Co-authored-by: Roman Kazantsev <roman.kazantsev@intel.com> * minor corrections * add unit-tests --------- Co-authored-by: Roman Kazantsev <roman.kazantsev@intel.com>
This commit is contained in:
1 parent
f2e71cbd0a
commit
1b24e15e1e
3 files changed
+149
-1
No files matched your search
@@ -60,7 +60,7 @@ class StridedSlice(Op):
|
||||
# StridedSliceNormalizer inserts nodes that change original begin, end, and strides data nodes
|
||||
# and since input permutations are stored in data nodes we end up having permutations
|
||||
# in the wrong place of the graph.
|
||||
# Therefore PermuteInputs will be set after StridedSliceNormalizer.
|
||||
# Therefore, PermuteInputs will be set after StridedSliceNormalizer.
|
||||
|
||||
@staticmethod
|
||||
def get_slices(node: Node, data_shape: Tuple) -> List:
|
||||
|
||||
@@ -116,6 +116,27 @@ def compare_graphs(graph: Graph, graph_ref: Graph, last_node: str, last_node_ref
|
||||
''.format(node.id, cur_node_type, attr))
|
||||
continue
|
||||
|
||||
def align_strided_slice_masks(curr_node: Node, rank: int):
|
||||
from openvino.tools.mo.ops.strided_slice import StridedSlice
|
||||
for mask_name in StridedSlice.get_mask_names():
|
||||
if isinstance(curr_node[mask_name], int):
|
||||
curr_node[mask_name] = [curr_node[mask_name]]
|
||||
elif isinstance(curr_node[mask_name], str): # if mask is an empty string ''
|
||||
assert len(curr_node[mask_name]) == 0
|
||||
curr_node[mask_name] = []
|
||||
|
||||
num_insertions = rank - len(curr_node[mask_name])
|
||||
curr_node[mask_name] = np.append(curr_node[mask_name], [0] * num_insertions).astype(int)
|
||||
|
||||
# Need to align StridedSlice masks since such masks as [] and [0]; [] and [0,0]; [] and [0,0,0]
|
||||
# or [1] and [1,0]; [1] and [1,0,0] and so on for the input with rank 4 do exactly the same slicing and
|
||||
# should be treated as equal. Therefore, before attr comparison we align all masks to the input rank
|
||||
if cur_node_type == 'StridedSlice' and node.in_node(1).has('shape') \
|
||||
and node.in_node(1).shape is not None:
|
||||
slice_rank = node.in_node(1).shape.item()
|
||||
align_strided_slice_masks(node, slice_rank)
|
||||
align_strided_slice_masks(node_ref, slice_rank)
|
||||
|
||||
if attr == 'value':
|
||||
if not values_are_equal(node.value, node_ref.value):
|
||||
stderr.append('Current node "{}" with type {} and reference node "{}" with type "{}" have '
|
||||
|
||||
@@ -1762,6 +1762,7 @@ class TestStridedSlicePermute(unittest.TestCase):
|
||||
begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
|
||||
|
||||
# with ellipsis
|
||||
|
||||
def test_strided_slice_permute_15(
|
||||
self, # inp[..., np.newaxis]
|
||||
inp=(1, 35, 35), ref_res=(1, 35, 35, 1),
|
||||
@@ -1943,3 +1944,129 @@ class TestStridedSlicePermute(unittest.TestCase):
|
||||
begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
|
||||
)
|
||||
|
||||
|
||||
class TestStridedSliceMaskAlignment(unittest.TestCase):
|
||||
def run_align_test(self, inp, begin, end, strides,
|
||||
begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask,
|
||||
begin_mask_ref, end_mask_ref, shrink_axis_mask_ref, new_axis_mask_ref, ellipsis_mask_ref):
|
||||
nodes = {
|
||||
**regular_op_with_shaped_data('input', int64_array(inp), {'op': 'Parameter', 'type': 'Parameter',
|
||||
# need to specify shape in 2 places
|
||||
'shape': int64_array(inp),
|
||||
'infer': Parameter.infer}),
|
||||
**valued_const_with_data('begin', int64_array(begin)),
|
||||
**valued_const_with_data('end', int64_array(end)),
|
||||
**valued_const_with_data('strides', int64_array(strides)),
|
||||
**regular_op_with_empty_data('strided_slice',
|
||||
{'op': 'StridedSlice', 'type': 'StridedSlice', # need for permute
|
||||
'begin_mask': begin_mask, 'end_mask': end_mask,
|
||||
'shrink_axis_mask': shrink_axis_mask,
|
||||
'new_axis_mask': new_axis_mask,
|
||||
'ellipsis_mask': ellipsis_mask}),
|
||||
**regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
|
||||
}
|
||||
|
||||
graph = build_graph(nodes, edges, nodes_with_edges_only=True)
|
||||
graph.stage = 'middle'
|
||||
graph.graph['layout'] = 'NHWC'
|
||||
|
||||
nodes_ref = nodes.copy()
|
||||
nodes_ref.update({
|
||||
**regular_op_with_empty_data('strided_slice',
|
||||
{'op': 'StridedSlice', 'type': 'StridedSlice', # need for permute
|
||||
'begin_mask': begin_mask_ref, 'end_mask': end_mask_ref,
|
||||
'shrink_axis_mask': shrink_axis_mask_ref,
|
||||
'new_axis_mask': new_axis_mask_ref,
|
||||
'ellipsis_mask': ellipsis_mask_ref}),
|
||||
})
|
||||
|
||||
graph_ref = build_graph(nodes_ref, edges, nodes_with_edges_only=True)
|
||||
res, msg = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
|
||||
assert res, msg
|
||||
|
||||
def test_mask_align_compare_graphs_1(self):
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref=(0, 0), end_mask_ref=(0, 0),
|
||||
shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
|
||||
|
||||
)
|
||||
|
||||
def test_mask_align_compare_graphs_2(self):
|
||||
# begin_masks have different values, but they alight to the same mask
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref=(0), end_mask_ref=(0, 0),
|
||||
shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
|
||||
|
||||
)
|
||||
|
||||
def test_mask_align_compare_graphs_3(self):
|
||||
# begin_masks have different values, but they alight to the same mask
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref=(0, 0), end_mask_ref=(0),
|
||||
shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0), ellipsis_mask_ref=(0),
|
||||
)
|
||||
|
||||
def test_mask_align_compare_graphs_4(self):
|
||||
# begin_masks have different values, but they alight to the same mask
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref=(0, 0), end_mask_ref=(0),
|
||||
shrink_axis_mask_ref=(1), new_axis_mask_ref=(0), ellipsis_mask_ref=(0),
|
||||
)
|
||||
|
||||
# corner case with and empty slice
|
||||
def test_mask_align_compare_graphs_5(self):
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=[], end=[], strides=[],
|
||||
begin_mask=[], end_mask=[],
|
||||
shrink_axis_mask=[], new_axis_mask=[], ellipsis_mask=[],
|
||||
begin_mask_ref=[], end_mask_ref=[],
|
||||
shrink_axis_mask_ref=[], new_axis_mask_ref=[], ellipsis_mask_ref=[]
|
||||
)
|
||||
|
||||
# emppty mask [] should be aligned into the length of begin
|
||||
def test_mask_align_compare_graphs_6(self):
|
||||
# begin_masks have different values, but they alight to the same mask
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref=[], end_mask_ref=(0, 0),
|
||||
shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
|
||||
|
||||
)
|
||||
|
||||
# empty mask "" should be transformed into [] and then aligned into the length of begin
|
||||
def test_mask_align_compare_graphs_7(self):
|
||||
# begin_masks have different values, but they alight to the same mask
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref="", end_mask_ref=(0, 0),
|
||||
shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
|
||||
|
||||
)
|
||||
|
||||
# negative test
|
||||
def test_negative_mask_align_compare_graphs(self):
|
||||
with self.assertRaisesRegex(AssertionError, 'have different attr "begin_mask"'):
|
||||
self.run_align_test(
|
||||
inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
|
||||
begin_mask=(0, 0), end_mask=(0, 0),
|
||||
shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
|
||||
begin_mask_ref=(0, 1), end_mask_ref=(0, 0),
|
||||
shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
|
||||
)
|
||||
Reference in new issue
Block a user