def find_channels_dimension(shape: PartialShape, num_channels: int, name: str, layout_values): """ Internal function. Finds dimension index matching with expected channels number Raises error if there is no candidates or number of candidates is > 1 :param: shape Parameter's partial shape :param: num_channels Number of channels to find in shape :param: name Parameter's name, used for Error-handling purposes :param: layout_values Existing source/target layout items specified by user :return: updated layout items with guessed layouts """ if shape.rank.is_dynamic: raise Error('Can\'t determine channels dimension for dynamic shape for parameter {}.' .format(name)) dim_idx_found = -1 for dim_idx in range(shape.rank.get_length()): dim = shape.get_dimension(dim_idx) if dim.is_static and dim.get_length() == num_channels: if dim_idx_found >= 0: raise Error('Can\'t determine channels dimension for {}. ' 'Input shape is {}, needed channels {}. ' 'Conflicting dimensions: {} and {}. Please specify layout manually.' .format(name, shape, num_channels, dim_idx_found, dim_idx)) dim_idx_found = dim_idx if dim_idx_found < 0: raise Error('Can\'t determine channels dimension for {}. ' 'Input shape is {}, needed channels {}' .format(name, shape, num_channels)) # Restrict guessed channels index to particular position depending on tensor shape(3d, 4d, 5d) if shape.rank.get_length() == 3: # CHW or HWC, possible channels index is 0 or 2 if dim_idx_found != 0 and dim_idx_found != 2: raise Error('Can\'t determine channels dimension for 3D input {} (CHW or HWC) with shape {}. ' 'Please specify layout containing \'C\' channels manually.'.format(name, shape)) elif shape.rank.get_length() == 4: # NCHW or NHWC, possible channels index is 1 or 3 if dim_idx_found != 1 and dim_idx_found != 3: raise Error('Can\'t determine channels dimension for 4D input {} (NCHW or NHWC) with shape {}. ' 'Please specify layout containing \'C\' channels manually.'.format(name, shape)) elif shape.rank.get_length() == 5: # NCDHW or NDHWC, possible channels index is 1 or 4 if dim_idx_found != 1 and dim_idx_found != 4: raise Error('Can\'t determine channels dimension for 5D input {} (NCDHW or NDHWC) with shape {}. ' 'Please specify layout containing \'C\' channels manually.'.format(name, shape)) else: raise Error('Can\'t determine channels dimension for {}D input {} with shape {}.' 'Please specify layout containing \'C\' channels manually.' .format(shape.rank.get_length(), name, shape)) layout_str = "?" * shape.rank.get_length() layout_str = layout_str[:dim_idx_found] + 'C' + layout_str[dim_idx_found+1:] layout_values[name] = { 'source_layout': layout_str, 'target_layout': None, 'source_guessed': True, 'is_input': True } return layout_values
def shape_to_array(shape: PartialShape): return [shape.get_dimension(i) for i in range(shape.rank.get_length())]
def test_partial_shape(): ps = PartialShape([1, 2, 3, 4]) assert ps.is_static assert not ps.is_dynamic assert ps.rank == 4 assert repr(ps) == "<PartialShape: {1,2,3,4}>" assert ps.get_dimension(0) == Dimension(1) assert ps.get_dimension(1) == Dimension(2) assert ps.get_dimension(2) == Dimension(3) assert ps.get_dimension(3) == Dimension(4) shape = Shape([1, 2, 3]) ps = PartialShape(shape) assert ps.is_static assert not ps.is_dynamic assert ps.all_non_negative assert ps.rank == 3 assert list(ps.get_shape()) == [1, 2, 3] assert list(ps.get_max_shape()) == [1, 2, 3] assert list(ps.get_min_shape()) == [1, 2, 3] assert list(ps.to_shape()) == [1, 2, 3] assert repr(shape) == "<Shape: {1, 2, 3}>" assert repr(ps) == "<PartialShape: {1,2,3}>" ps = PartialShape( [Dimension(1), Dimension(2), Dimension(3), Dimension.dynamic()]) assert not ps.is_static assert ps.is_dynamic assert ps.all_non_negative assert ps.rank == 4 assert list(ps.get_min_shape()) == [1, 2, 3, 0] assert list(ps.get_max_shape())[3] > 1000000000 assert repr(ps) == "<PartialShape: {1,2,3,?}>" assert ps.get_dimension(0) == Dimension(1) assert ps.get_dimension(1) == Dimension(2) assert ps.get_dimension(2) == Dimension(3) assert ps.get_dimension(3) == Dimension.dynamic() ps = PartialShape([1, 2, 3, -1]) assert not ps.is_static assert ps.is_dynamic assert ps.all_non_negative assert ps.rank == 4 assert list(ps.get_min_shape()) == [1, 2, 3, 0] assert list(ps.get_max_shape())[3] > 1000000000 assert repr(ps) == "<PartialShape: {1,2,3,?}>" ps = PartialShape.dynamic() assert not ps.is_static assert ps.is_dynamic assert ps.rank == Dimension.dynamic() assert list(ps.get_min_shape()) == [] assert list(ps.get_max_shape()) == [] assert repr(ps) == "<PartialShape: ...>" ps = PartialShape.dynamic(rank=Dimension(2)) assert not ps.is_static assert ps.is_dynamic assert ps.rank == 2 assert 2 == ps.rank assert list(ps.get_min_shape()) == [0, 0] assert list(ps.get_max_shape())[0] > 1000000000 assert repr(ps) == "<PartialShape: {?,?}>"
def test_partial_shape(): ps = PartialShape([1, 2, 3, 4]) assert ps.is_static assert not ps.is_dynamic assert ps.rank == 4 assert repr(ps) == "<PartialShape: {1,2,3,4}>" assert ps.get_dimension(0) == Dimension(1) assert ps.get_dimension(1) == Dimension(2) assert ps.get_dimension(2) == Dimension(3) assert ps.get_dimension(3) == Dimension(4) shape = Shape([1, 2, 3]) ps = PartialShape(shape) assert ps.is_static assert not ps.is_dynamic assert ps.all_non_negative assert ps.rank == 3 assert list(ps.get_shape()) == [1, 2, 3] assert list(ps.get_max_shape()) == [1, 2, 3] assert list(ps.get_min_shape()) == [1, 2, 3] assert list(ps.to_shape()) == [1, 2, 3] assert repr(shape) == "<Shape: {1, 2, 3}>" assert repr(ps) == "<PartialShape: {1,2,3}>" ps = PartialShape( [Dimension(1), Dimension(2), Dimension(3), Dimension.dynamic()]) assert not ps.is_static assert ps.is_dynamic assert ps.all_non_negative assert ps.rank == 4 assert list(ps.get_min_shape()) == [1, 2, 3, 0] assert list(ps.get_max_shape())[3] > 1000000000 assert repr(ps) == "<PartialShape: {1,2,3,?}>" assert ps.get_dimension(0) == Dimension(1) assert ps.get_dimension(1) == Dimension(2) assert ps.get_dimension(2) == Dimension(3) assert ps.get_dimension(3) == Dimension.dynamic() ps = PartialShape([1, 2, 3, -1]) assert not ps.is_static assert ps.is_dynamic assert ps.all_non_negative assert ps.rank == 4 assert list(ps.get_min_shape()) == [1, 2, 3, 0] assert list(ps.get_max_shape())[3] > 1000000000 assert repr(ps) == "<PartialShape: {1,2,3,?}>" ps = PartialShape.dynamic() assert not ps.is_static assert ps.is_dynamic assert ps.rank == Dimension.dynamic() assert list(ps.get_min_shape()) == [] assert list(ps.get_max_shape()) == [] assert repr(ps) == "<PartialShape: ...>" ps = PartialShape.dynamic(rank=Dimension(2)) assert not ps.is_static assert ps.is_dynamic assert ps.rank == 2 assert 2 == ps.rank assert list(ps.get_min_shape()) == [0, 0] assert list(ps.get_max_shape())[0] > 1000000000 assert repr(ps) == "<PartialShape: {?,?}>" shape_list = [(1, 10), [2, 5], 4, Dimension(2), "..10"] ref_ps = PartialShape([ Dimension(1, 10), Dimension(2, 5), Dimension(4), Dimension(2), Dimension(-1, 10) ]) assert PartialShape(shape_list) == ref_ps assert PartialShape(tuple(shape_list)) == ref_ps with pytest.raises(TypeError) as e: PartialShape([(1, 2, 3)]) assert "Two elements are expected in tuple(lower, upper) " \ "for dynamic dimension, but 3 elements were given." in str(e.value) with pytest.raises(TypeError) as e: PartialShape([("?", "?")]) assert "Incorrect pair of types (<class 'str'>, <class 'str'>) " \ "for dynamic dimension, ints are expected." in str(e.value) with pytest.raises(TypeError) as e: PartialShape([range(10)]) assert "Incorrect type <class 'range'> for dimension. Expected types are: " \ "int, str, openvino.runtime.Dimension, list/tuple with lower " \ "and upper values for dynamic dimension." in str(e.value) ps = PartialShape("...") assert ps == PartialShape.dynamic() ps = PartialShape("?, 3, ..224, 28..224") assert ps == PartialShape( [Dimension(-1), Dimension(3), Dimension(-1, 224), Dimension(28, 224)]) with pytest.raises(RuntimeError) as e: ps = PartialShape("?,,3") assert 'Cannot get vector of dimensions! "?,,3" is incorrect' in str( e.value) shape = Shape() assert len(shape) == 0