[PyOV] Extend Python API with opset12, Pad-12, ScatterElementsUpdate-12 and GroupNormalization-12 (#18481)

This commit is contained in:
Przemyslaw Wysocki
2023-07-14 17:59:13 +02:00
committed by GitHub
parent ce8f164fea
commit 7bceba1523
17 changed files with 419 additions and 42 deletions

View File

@@ -58,6 +58,7 @@ from openvino.runtime import opset8
from openvino.runtime import opset9
from openvino.runtime import opset10
from openvino.runtime import opset11
from openvino.runtime import opset12
# Import properties API
from openvino.runtime import properties
@@ -75,19 +76,19 @@ except ImportError:
# Extend Node class to support binary operators
Node.__add__ = opset11.add
Node.__sub__ = opset11.subtract
Node.__mul__ = opset11.multiply
Node.__div__ = opset11.divide
Node.__truediv__ = opset11.divide
Node.__radd__ = lambda left, right: opset11.add(right, left)
Node.__rsub__ = lambda left, right: opset11.subtract(right, left)
Node.__rmul__ = lambda left, right: opset11.multiply(right, left)
Node.__rdiv__ = lambda left, right: opset11.divide(right, left)
Node.__rtruediv__ = lambda left, right: opset11.divide(right, left)
Node.__eq__ = opset11.equal
Node.__ne__ = opset11.not_equal
Node.__lt__ = opset11.less
Node.__le__ = opset11.less_equal
Node.__gt__ = opset11.greater
Node.__ge__ = opset11.greater_equal
Node.__add__ = opset12.add
Node.__sub__ = opset12.subtract
Node.__mul__ = opset12.multiply
Node.__div__ = opset12.divide
Node.__truediv__ = opset12.divide
Node.__radd__ = lambda left, right: opset12.add(right, left)
Node.__rsub__ = lambda left, right: opset12.subtract(right, left)
Node.__rmul__ = lambda left, right: opset12.multiply(right, left)
Node.__rdiv__ = lambda left, right: opset12.divide(right, left)
Node.__rtruediv__ = lambda left, right: opset12.divide(right, left)
Node.__eq__ = opset12.equal
Node.__ne__ = opset12.not_equal
Node.__lt__ = opset12.less
Node.__le__ = opset12.less_equal
Node.__gt__ = opset12.greater
Node.__ge__ = opset12.greater_equal

View File

@@ -0,0 +1,179 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from openvino.runtime.opset1.ops import absolute
from openvino.runtime.opset1.ops import absolute as abs
from openvino.runtime.opset1.ops import acos
from openvino.runtime.opset4.ops import acosh
from openvino.runtime.opset8.ops import adaptive_avg_pool
from openvino.runtime.opset8.ops import adaptive_max_pool
from openvino.runtime.opset1.ops import add
from openvino.runtime.opset1.ops import asin
from openvino.runtime.opset4.ops import asinh
from openvino.runtime.opset6.ops import assign
from openvino.runtime.opset1.ops import atan
from openvino.runtime.opset4.ops import atanh
from openvino.runtime.opset1.ops import avg_pool
from openvino.runtime.opset5.ops import batch_norm_inference
from openvino.runtime.opset2.ops import batch_to_space
from openvino.runtime.opset1.ops import binary_convolution
from openvino.runtime.opset3.ops import broadcast
from openvino.runtime.opset3.ops import bucketize
from openvino.runtime.opset1.ops import ceiling
from openvino.runtime.opset1.ops import ceiling as ceil
from openvino.runtime.opset1.ops import clamp
from openvino.runtime.opset1.ops import concat
from openvino.runtime.opset1.ops import constant
from openvino.runtime.opset1.ops import convert
from openvino.runtime.opset1.ops import convert_like
from openvino.runtime.opset1.ops import convolution
from openvino.runtime.opset1.ops import convolution_backprop_data
from openvino.runtime.opset1.ops import cos
from openvino.runtime.opset1.ops import cosh
from openvino.runtime.opset1.ops import ctc_greedy_decoder
from openvino.runtime.opset6.ops import ctc_greedy_decoder_seq_len
from openvino.runtime.opset4.ops import ctc_loss
from openvino.runtime.opset3.ops import cum_sum
from openvino.runtime.opset3.ops import cum_sum as cumsum
from openvino.runtime.opset8.ops import deformable_convolution
from openvino.runtime.opset1.ops import deformable_psroi_pooling
from openvino.runtime.opset1.ops import depth_to_space
from openvino.runtime.opset8.ops import detection_output
from openvino.runtime.opset7.ops import dft
from openvino.runtime.opset1.ops import divide
from openvino.runtime.opset7.ops import einsum
from openvino.runtime.opset1.ops import elu
from openvino.runtime.opset3.ops import embedding_bag_offsets_sum
from openvino.runtime.opset3.ops import embedding_bag_packed_sum
from openvino.runtime.opset3.ops import embedding_segments_sum
from openvino.runtime.opset3.ops import extract_image_patches
from openvino.runtime.opset1.ops import equal
from openvino.runtime.opset1.ops import erf
from openvino.runtime.opset1.ops import exp
from openvino.runtime.opset9.ops import eye
from openvino.runtime.opset1.ops import fake_quantize
from openvino.runtime.opset1.ops import floor
from openvino.runtime.opset1.ops import floor_mod
from openvino.runtime.opset8.ops import gather
from openvino.runtime.opset6.ops import gather_elements
from openvino.runtime.opset8.ops import gather_nd
from openvino.runtime.opset1.ops import gather_tree
from openvino.runtime.opset7.ops import gelu
from openvino.runtime.opset9.ops import generate_proposals
from openvino.runtime.opset1.ops import greater
from openvino.runtime.opset1.ops import greater_equal
from openvino.runtime.opset9.ops import grid_sample
from openvino.runtime.opset1.ops import grn
from openvino.runtime.opset1.ops import group_convolution
from openvino.runtime.opset1.ops import group_convolution_backprop_data
from openvino.runtime.opset12.ops import group_normalization
from openvino.runtime.opset3.ops import gru_cell
from openvino.runtime.opset5.ops import gru_sequence
from openvino.runtime.opset1.ops import hard_sigmoid
from openvino.runtime.opset5.ops import hsigmoid
from openvino.runtime.opset4.ops import hswish
from openvino.runtime.opset7.ops import idft
from openvino.runtime.opset8.ops import if_op
from openvino.runtime.opset11.ops import interpolate
from openvino.runtime.opset9.ops import irdft
from openvino.runtime.opset10.ops import is_finite
from openvino.runtime.opset10.ops import is_inf
from openvino.runtime.opset10.ops import is_nan
from openvino.runtime.opset8.ops import i420_to_bgr
from openvino.runtime.opset8.ops import i420_to_rgb
from openvino.runtime.opset1.ops import less
from openvino.runtime.opset1.ops import less_equal
from openvino.runtime.opset1.ops import log
from openvino.runtime.opset1.ops import logical_and
from openvino.runtime.opset1.ops import logical_not
from openvino.runtime.opset1.ops import logical_or
from openvino.runtime.opset1.ops import logical_xor
from openvino.runtime.opset5.ops import log_softmax
from openvino.runtime.opset5.ops import loop
from openvino.runtime.opset1.ops import lrn
from openvino.runtime.opset4.ops import lstm_cell
from openvino.runtime.opset5.ops import lstm_sequence
from openvino.runtime.opset1.ops import matmul
from openvino.runtime.opset8.ops import matrix_nms
from openvino.runtime.opset8.ops import max_pool
from openvino.runtime.opset1.ops import maximum
from openvino.runtime.opset1.ops import minimum
from openvino.runtime.opset4.ops import mish
from openvino.runtime.opset1.ops import mod
from openvino.runtime.opset9.ops import multiclass_nms
from openvino.runtime.opset1.ops import multiply
from openvino.runtime.opset6.ops import mvn
from openvino.runtime.opset1.ops import negative
from openvino.runtime.opset9.ops import non_max_suppression
from openvino.runtime.opset3.ops import non_zero
from openvino.runtime.opset1.ops import normalize_l2
from openvino.runtime.opset1.ops import not_equal
from openvino.runtime.opset8.ops import nv12_to_bgr
from openvino.runtime.opset8.ops import nv12_to_rgb
from openvino.runtime.opset1.ops import one_hot
from openvino.runtime.opset12.ops import pad
from openvino.runtime.opset1.ops import parameter
from openvino.runtime.opset1.ops import power
from openvino.runtime.opset1.ops import prelu
from openvino.runtime.opset8.ops import prior_box
from openvino.runtime.opset1.ops import prior_box_clustered
from openvino.runtime.opset1.ops import psroi_pooling
from openvino.runtime.opset4.ops import proposal
from openvino.runtime.opset1.ops import range
from openvino.runtime.opset8.ops import random_uniform
from openvino.runtime.opset9.ops import rdft
from openvino.runtime.opset3.ops import read_value
from openvino.runtime.opset4.ops import reduce_l1
from openvino.runtime.opset4.ops import reduce_l2
from openvino.runtime.opset1.ops import reduce_logical_and
from openvino.runtime.opset1.ops import reduce_logical_or
from openvino.runtime.opset1.ops import reduce_max
from openvino.runtime.opset1.ops import reduce_mean
from openvino.runtime.opset1.ops import reduce_min
from openvino.runtime.opset1.ops import reduce_prod
from openvino.runtime.opset1.ops import reduce_sum
from openvino.runtime.opset1.ops import region_yolo
from openvino.runtime.opset2.ops import reorg_yolo
from openvino.runtime.opset1.ops import relu
from openvino.runtime.opset1.ops import reshape
from openvino.runtime.opset1.ops import result
from openvino.runtime.opset1.ops import reverse_sequence
from openvino.runtime.opset3.ops import rnn_cell
from openvino.runtime.opset5.ops import rnn_sequence
from openvino.runtime.opset9.ops import roi_align
from openvino.runtime.opset2.ops import roi_pooling
from openvino.runtime.opset7.ops import roll
from openvino.runtime.opset5.ops import round
from openvino.runtime.opset12.ops import scatter_elements_update
from openvino.runtime.opset3.ops import scatter_update
from openvino.runtime.opset1.ops import select
from openvino.runtime.opset1.ops import selu
from openvino.runtime.opset3.ops import shape_of
from openvino.runtime.opset3.ops import shuffle_channels
from openvino.runtime.opset1.ops import sigmoid
from openvino.runtime.opset1.ops import sign
from openvino.runtime.opset1.ops import sin
from openvino.runtime.opset1.ops import sinh
from openvino.runtime.opset8.ops import slice
from openvino.runtime.opset8.ops import softmax
from openvino.runtime.opset4.ops import softplus
from openvino.runtime.opset9.ops import softsign
from openvino.runtime.opset2.ops import space_to_batch
from openvino.runtime.opset1.ops import space_to_depth
from openvino.runtime.opset1.ops import split
from openvino.runtime.opset1.ops import sqrt
from openvino.runtime.opset1.ops import squared_difference
from openvino.runtime.opset1.ops import squeeze
from openvino.runtime.opset1.ops import strided_slice
from openvino.runtime.opset1.ops import subtract
from openvino.runtime.opset4.ops import swish
from openvino.runtime.opset1.ops import tan
from openvino.runtime.opset1.ops import tanh
from openvino.runtime.opset1.ops import tensor_iterator
from openvino.runtime.opset1.ops import tile
from openvino.runtime.opset11.ops import topk
from openvino.runtime.opset1.ops import transpose
from openvino.runtime.opset10.ops import unique
from openvino.runtime.opset1.ops import unsqueeze
from openvino.runtime.opset1.ops import variadic_split

View File

@@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
"""Factory functions for all ngraph ops."""
from functools import partial
from typing import Optional
from openvino.runtime import Node
from openvino.runtime.opset_utils import _get_node_factory
from openvino.runtime.utils.decorators import nameable_op
from openvino.runtime.utils.types import (
NodeInput,
as_nodes,
as_node,
)
_get_node_factory_opset12 = partial(_get_node_factory, "opset12")
# -------------------------------------------- ops ------------------------------------------------
@nameable_op
def pad(
arg: NodeInput,
pads_begin: NodeInput,
pads_end: NodeInput,
pad_mode: str,
arg_pad_value: Optional[NodeInput] = None,
name: Optional[str] = None,
) -> Node:
"""Return a generic padding operation.
:param arg: The node producing input tensor to be padded.
:param pads_begin: Number of padding elements to be added before position 0
on each axis of arg. Negative values are supported.
:param pads_end: Number of padding elements to be added after the last element.
Negative values are supported.
:param pad_mode: "constant", "edge", "reflect" or "symmetric"
:param arg_pad_value: value used for padding if pad_mode is "constant"
:return: Pad operation node.
"""
input_nodes = as_nodes(arg, pads_begin, pads_end)
if arg_pad_value:
input_nodes.append(as_node(arg_pad_value))
pad_mode = pad_mode.upper()
return _get_node_factory_opset12().create("Pad", input_nodes, {"pad_mode": pad_mode})
@nameable_op
def scatter_elements_update(
data: NodeInput,
indices: NodeInput,
updates: NodeInput,
axis: NodeInput,
reduction: Optional[str] = "None",
use_init_val: Optional[bool] = True,
name: Optional[str] = None,
) -> Node:
"""Return a node which produces a ScatterElementsUpdate operation.
:param data: The input tensor to be updated.
:param indices: The tensor with indexes which will be updated. Negative indices are supported.
:param updates: The tensor with update values.
:param axis: The axis for scatter.
:param reduction: The type of operation to perform on the inputs. One of "none", "sum",
"prod", "min", "max", "mean".
:param: use_init_val: Controls whether the elements in the data input tensor are used as
initial value for reduce operations.
:return: ScatterElementsUpdate node
ScatterElementsUpdate creates a copy of the first input tensor with updated elements
specified with second and third input tensors.
For each entry in `updates`, the target index in `data` is obtained by combining
the corresponding entry in `indices` with the index of the entry itself: the
index-value for dimension equal to `axis` is obtained from the value of the
corresponding entry in `indices` and the index-value for dimension not equal
to `axis` is obtained from the index of the entry itself.
"""
input_nodes = as_nodes(data, indices, updates, axis)
return _get_node_factory_opset12().create(
"ScatterElementsUpdate",
input_nodes,
{
"reduction": reduction,
"use_init_val": use_init_val,
},
)
@nameable_op
def group_normalization(
data: NodeInput,
scale: NodeInput,
bias: NodeInput,
num_groups: int,
epsilon: float,
name: Optional[str] = None,
) -> Node:
"""Return a node which produces a GroupNormalization operation.
:param data: The input tensor to be normalized.
:param scale: The tensor containing the scale values for each channel.
:param bias: The tensor containing the bias values for each channel.
:param num_groups: Specifies the number of groups that the channel dimension will be divided into.
:param epsilon: A very small value added to the variance for numerical stability.
Ensures that division by zero does not occur for any normalized element.
:return: GroupNormalization node
"""
input_nodes = as_nodes(data, scale, bias)
return _get_node_factory_opset12().create(
"GroupNormalization",
input_nodes,
{
"num_groups": num_groups,
"epsilon": epsilon,
},
)

View File

@@ -13,7 +13,7 @@ from openvino.runtime import Node, Output
from openvino.runtime.exceptions import UserInputError
DEFAULT_OPSET = "opset11"
DEFAULT_OPSET = "opset12"
class NodeFactory(object):

View File

@@ -80,7 +80,7 @@ private:
return it->second();
}
const ov::OpSet& m_opset = ov::get_opset11();
const ov::OpSet& m_opset = ov::get_opset12();
std::unordered_map<std::string, std::shared_ptr<ov::op::util::Variable>> m_variables;
};
} // namespace

View File

@@ -24,19 +24,6 @@ def test_reverse_sequence():
assert model.get_output_element_type(0) == Type.i32
def test_pad_edge():
pads_begin = np.array([0, 1], dtype=np.int32)
pads_end = np.array([2, 3], dtype=np.int32)
input_param = ov.parameter((3, 4), name="input", dtype=np.int32)
model = ov.pad(input_param, pads_begin, pads_end, "edge")
assert model.get_type_name() == "Pad"
assert model.get_output_size() == 1
assert list(model.get_output_shape(0)) == [5, 8]
assert model.get_output_element_type(0) == Type.i32
def test_select():
cond = np.array([[False, False], [True, False], [True, True]])
then_node = np.array([[-1, 0], [1, 2], [3, 4]], dtype=np.int32)

View File

@@ -5,7 +5,7 @@
import numpy as np
from openvino.runtime import Type
import openvino.runtime.opset8 as ov
import openvino.runtime.opset12 as ov
def test_lrn():
@@ -84,3 +84,18 @@ def test_mvn():
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == [1, 3, 3, 3]
assert node.get_output_element_type(0) == Type.f32
def test_group_normalization():
data = ov.parameter((1, 3, 3, 3), name="data", dtype=np.float32)
scale = np.array((1, 1, 1), dtype=np.float32)
bias = np.array((1, 1, 1), dtype=np.float32)
num_groups = 1
epsilon = 1e-6
node = ov.group_normalization(data, scale, bias, num_groups, epsilon)
assert node.get_type_name() == "GroupNormalization"
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == [1, 3, 3, 3]
assert node.get_output_element_type(0) == Type.f32

View File

@@ -3,8 +3,9 @@
# SPDX-License-Identifier: Apache-2.0
import numpy as np
import pytest
import openvino.runtime.opset8 as ov
import openvino.runtime.opset12 as ov
from openvino.runtime import Type
@@ -22,7 +23,7 @@ def test_scatter_update_props():
assert node.get_output_element_type(0) == Type.i8
def test_scatter_update_elements_props():
def test_scatter_update_elements_default_values():
dtype = np.int8
parameter_r = ov.parameter([2, 4, 5, 7], dtype=dtype, name="data")
parameter_i = ov.parameter([2, 2, 2, 2], dtype=dtype, name="indices")
@@ -34,3 +35,28 @@ def test_scatter_update_elements_props():
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == [2, 4, 5, 7]
assert node.get_output_element_type(0) == Type.i8
@pytest.mark.parametrize(
"reduction",
[
"none",
"sum",
"prod",
"min",
"max",
"mean",
],
)
def test_scatter_update_elements_props(reduction):
dtype = np.int8
parameter_r = ov.parameter([2, 4, 5, 7], dtype=dtype, name="data")
parameter_i = ov.parameter([2, 2, 2, 2], dtype=dtype, name="indices")
parameter_u = ov.parameter([2, 2, 2, 2], dtype=dtype, name="updates")
axis = np.array([1], dtype=np.int8)
node = ov.scatter_elements_update(parameter_r, parameter_i, parameter_u, axis, reduction, False)
assert node.get_type_name() == "ScatterElementsUpdate"
assert node.get_output_size() == 1
assert list(node.get_output_shape(0)) == [2, 4, 5, 7]
assert node.get_output_element_type(0) == Type.i8

View File

@@ -0,0 +1,49 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import numpy as np
import pytest
import openvino.runtime.opset12 as ov
from openvino.runtime import Type
@pytest.mark.parametrize(
"pad_mode",
[
"constant",
"edge",
"reflect",
"symmetric",
]
)
def test_pad_mode(pad_mode):
pads_begin = np.array([0, 1], dtype=np.int32)
pads_end = np.array([2, 3], dtype=np.int32)
input_param = ov.parameter((3, 4), name="input", dtype=np.int32)
model = ov.pad(input_param, pads_begin, pads_end, pad_mode)
assert model.get_type_name() == "Pad"
assert model.get_output_size() == 1
assert list(model.get_output_shape(0)) == [5, 8]
assert model.get_output_element_type(0) == Type.i32
@pytest.mark.parametrize(
("pads_begin", "pads_end", "output_shape"),
[
([-1, -1], [-1, -1], [1, 2]),
([2, -1], [-1, 3], [4, 6]),
]
)
def test_pad_being_and_end(pads_begin, pads_end, output_shape):
input_param = ov.parameter((3, 4), name="input", dtype=np.int32)
model = ov.pad(input_param, pads_begin, pads_end, "constant")
assert model.get_type_name() == "Pad"
assert model.get_output_size() == 1
assert list(model.get_output_shape(0)) == output_shape
assert model.get_output_element_type(0) == Type.i32

View File

@@ -10,7 +10,7 @@ import pytest
import datetime
import time
import openvino.runtime.opset8 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import Core, AsyncInferQueue, Tensor, ProfilingInfo, Model, InferRequest, CompiledModel
from openvino.runtime import Type, PartialShape, Shape, Layout
from openvino.preprocess import PrePostProcessor

View File

@@ -7,7 +7,7 @@ import os
from ..conftest import model_path
from openvino.runtime import Input, Shape, PartialShape, Type, RTMap
from openvino._pyopenvino import DescriptorTensor
import openvino.runtime.opset8 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import Core, OVAny

View File

@@ -7,7 +7,7 @@ import numpy as np
import pytest
import math
import openvino.runtime.opset11 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import (
Core,
Model,

View File

@@ -9,7 +9,7 @@ import io
import threading
import numpy as np
from openvino.runtime import Core, Model, AsyncInferQueue, PartialShape, Layout, opset8 as ops, serialize
from openvino.runtime import Core, Model, AsyncInferQueue, PartialShape, Layout, opset12 as ops, serialize
from openvino.preprocess import PrePostProcessor
from tests import skip_devtest

View File

@@ -6,7 +6,7 @@ import os
from copy import copy, deepcopy
from ..conftest import model_path
import openvino.runtime.opset8 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import (
ConstOutput,
Shape,

View File

@@ -5,7 +5,7 @@
import os
from ..conftest import model_path
import openvino.runtime.opset8 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import Type

View File

@@ -6,7 +6,7 @@ from collections.abc import Mapping
import numpy as np
import pytest
import openvino.runtime.opset10 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import Core, ConstOutput, CompiledModel, InferRequest, Model
from openvino.runtime.ie_api import OVDict

View File

@@ -12,7 +12,7 @@ import pytest
from pathlib import Path
import openvino
import openvino.runtime.opset8 as ops
import openvino.runtime.opset12 as ops
from openvino.runtime import Model, Core, Shape
from openvino.utils import deprecated