diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c25e8b9e24de80..9c3f6f41d9f172 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -20,6 +20,10 @@ on: branches: - master +concurrency: + group: ${{ github.head_ref || github.run_id }}-linux + cancel-in-progress: true + jobs: Build: defaults: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c1cb1bb47f7d82..5fb10bddf8b10f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,24 +1,28 @@ name: Tests on Windows (VS 2022, Python 3.11) on: workflow_dispatch: - pull_request: - paths-ignore: - - '**/docs/**' - - 'docs/**' - - '**/**.md' - - '**.md' - - '**/layer_tests_summary/**' - - '**/conformance/**' - push: - paths-ignore: - - '**/docs/**' - - 'docs/**' - - '**/**.md' - - '**.md' - - '**/layer_tests_summary/**' - - '**/conformance/**' - branches: - - master +# pull_request: +# paths-ignore: +# - '**/docs/**' +# - 'docs/**' +# - '**/**.md' +# - '**.md' +# - '**/layer_tests_summary/**' +# - '**/conformance/**' +# push: +# paths-ignore: +# - '**/docs/**' +# - 'docs/**' +# - '**/**.md' +# - '**.md' +# - '**/layer_tests_summary/**' +# - '**/conformance/**' +# branches: +# - master + +concurrency: + group: ${{ github.head_ref || github.run_id }}-windows + cancel-in-progress: true env: CMAKE_BUILD_TYPE: 'Release' diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index b29bc08c66daf5..f2c0f0774796b0 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -116,10 +116,10 @@ function(ov_download_tbb) elseif(LINUX AND X86_64 AND OV_GLIBC_VERSION VERSION_GREATER_EQUAL 2.17) # build oneTBB 2021.2.1 with gcc 4.8 (glibc 2.17) RESOLVE_DEPENDENCY(TBB - ARCHIVE_LIN "oneapi-tbb-2021.2.1-lin.tgz" + ARCHIVE_LIN "oneapi-tbb-2021.2.1-lin-canary.tgz" TARGET_PATH "${TEMP}/tbb" ENVIRONMENT "TBBROOT" - SHA256 "0a56f73baaa40d72e06949ea6d593ae63a19f7580ce71c08287c1f59d2e5b988" + SHA256 "3a2c2ec79b3cce7e6a2484754ba6f029fa968db2eefc6659540792b7db8fea0c" USE_NEW_LOCATION TRUE) elseif(YOCTO_AARCH64) RESOLVE_DEPENDENCY(TBB @@ -147,10 +147,10 @@ function(ov_download_tbb) elseif(LINUX AND AARCH64 AND OV_GLIBC_VERSION VERSION_GREATER_EQUAL 2.17) # build oneTBB 2021.2.1 with gcc 4.8 (glibc 2.17) RESOLVE_DEPENDENCY(TBB - ARCHIVE_LIN "oneapi-tbb-2021.2.1-lin-arm64.tgz" + ARCHIVE_LIN "oneapi-tbb-2021.2.1-lin-arm64-canary.tgz" TARGET_PATH "${TEMP}/tbb" ENVIRONMENT "TBBROOT" - SHA256 "6b87194a845aa9314f3785d842e250d934e545eccc4636655c7b27c98c302c0c" + SHA256 "042fdac53be65841a970b05d892f4b20b556b06fd3b20d2d0068e49c4fd74f07" USE_NEW_LOCATION TRUE) elseif(APPLE AND AARCH64) # build oneTBB 2021.2.1 with export MACOSX_DEPLOYMENT_TARGET=11.0 diff --git a/cmake/developer_package/compile_flags/sdl.cmake b/cmake/developer_package/compile_flags/sdl.cmake index 49ff54d8326c03..10bfee90aafa93 100644 --- a/cmake/developer_package/compile_flags/sdl.cmake +++ b/cmake/developer_package/compile_flags/sdl.cmake @@ -15,9 +15,8 @@ if(CMAKE_COMPILER_IS_GNUCXX OR OV_COMPILER_IS_CLANG OR set(OV_C_CXX_FLAGS "${OV_C_CXX_FLAGS} -D_FORTIFY_SOURCE=2") endif() endif() - if(NOT APPLE) - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -pie") - endif() + + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -pie") if(CMAKE_COMPILER_IS_GNUCXX) set(OV_C_CXX_FLAGS "${OV_C_CXX_FLAGS} -fno-strict-overflow -fno-delete-null-pointer-checks -fwrapv") diff --git a/samples/cpp/benchmark_app/main.cpp b/samples/cpp/benchmark_app/main.cpp index 0ec8267a7c87e8..2bda41ca8b880c 100644 --- a/samples/cpp/benchmark_app/main.cpp +++ b/samples/cpp/benchmark_app/main.cpp @@ -811,16 +811,18 @@ int main(int argc, char* argv[]) { } } - if (isDynamicNetwork && FLAGS_api == "sync") { + bool allow_inference_only_or_sync = can_measure_as_static(app_inputs_info); + + if (!allow_inference_only_or_sync && FLAGS_api == "sync") { throw std::logic_error("Benchmarking of the model with dynamic shapes is available for async API only. " - "Please use -api async -nstreams 1 -nireq 1 to emulate sync behavior"); + "Please use -api async -hint latency -nireq 1 to emulate sync behavior"); } // Defining of benchmark mode // for static models inference only mode is used as default one bool inferenceOnly = FLAGS_inference_only; if (isDynamicNetwork) { - if (isFlagSetInCommandLine("inference_only") && inferenceOnly && app_inputs_info.size() != 1) { + if (isFlagSetInCommandLine("inference_only") && inferenceOnly && !allow_inference_only_or_sync) { throw std::logic_error( "Dynamic models with different input data shapes must be benchmarked only in full mode."); } diff --git a/samples/cpp/benchmark_app/utils.cpp b/samples/cpp/benchmark_app/utils.cpp index ce13d85ec7838f..9d3b26611565a4 100644 --- a/samples/cpp/benchmark_app/utils.cpp +++ b/samples/cpp/benchmark_app/utils.cpp @@ -108,6 +108,10 @@ std::vector split_float(const std::string& s, char delim) { return result; } +bool can_measure_as_static(const std::vector& app_input_info) { + return app_input_info.size() == 1; +} + static const std::vector meta_plugins{"MULTI", "HETERO", "AUTO"}; bool is_virtual_device(const std::string& device_name) { return std::find(meta_plugins.begin(), meta_plugins.end(), device_name) != meta_plugins.end(); diff --git a/samples/cpp/benchmark_app/utils.hpp b/samples/cpp/benchmark_app/utils.hpp index a15c4501ba35d6..2fa20f040cb1f9 100644 --- a/samples/cpp/benchmark_app/utils.hpp +++ b/samples/cpp/benchmark_app/utils.hpp @@ -58,6 +58,7 @@ using InputsInfo = std::map; using PartialShapes = std::map; } // namespace benchmark_app +bool can_measure_as_static(const std::vector& app_input_info); bool is_virtual_device(const std::string& device_name); bool is_virtual_device_found(const std::vector& device_names); void update_device_properties_setting(const std::string& device_name, diff --git a/src/bindings/python/src/openvino/frontend/tensorflow/node_decoder.py b/src/bindings/python/src/openvino/frontend/tensorflow/node_decoder.py index 9a7429b46c7af8..cc0ff44ea6ec29 100644 --- a/src/bindings/python/src/openvino/frontend/tensorflow/node_decoder.py +++ b/src/bindings/python/src/openvino/frontend/tensorflow/node_decoder.py @@ -14,6 +14,8 @@ def tf_type_to_ov_type(tf_type_int): tf_type = tf.dtypes.as_dtype(tf_type_int) if tf_type.name == "variant": return Type.dynamic + if tf_type.name == "string": + return "DT_STRING" numpy_type = tf_type.as_numpy_dtype try: ret_type = Type(numpy_type) @@ -51,19 +53,30 @@ def __init__(self, operation: tf.Operation, inner_graph: bool): "Expected tf.Operation, got {}".format(type(operation)) self.m_operation = operation self.m_inner_graph = inner_graph + self.m_data_type = None if self.m_operation.type == "Const": - value = self.m_operation.node_def.attr["value"].tensor + data_type = tf.dtypes.DType(self.m_operation.node_def.attr["dtype"].type).name + self.m_data_type = data_type # copies tensor value from node_def - self.m_parsed_content = tf.make_ndarray(value) + value = self.m_operation.node_def.attr["value"].tensor + if data_type == "string": + self.m_parsed_content = [str(val) for val in value.string_val] + else: + self.m_parsed_content = tf.make_ndarray(value) if self.m_operation.type == "Placeholder": - data_type = self.m_operation.node_def.attr["dtype"].type - if tf.dtypes.DType(data_type).name == "resource" and not self.m_inner_graph: + data_type = tf.dtypes.DType(self.m_operation.node_def.attr["dtype"].type).name + self.m_data_type = data_type + if data_type == "resource" and not self.m_inner_graph: variable_value = TFGraphNodeDecoder.get_variable(self.m_operation) if variable_value is not None: # does not copy data self.m_parsed_content = variable_value.value().__array__() + if isinstance(self.m_parsed_content, bytes): + self.m_data_type = "string" + self.m_parsed_content = [str(self.m_parsed_content)] + def get_op_name(self) -> str: return self.m_operation.name @@ -114,6 +127,8 @@ def get_attribute(self, name): return OVAny(tf_type_to_ov_type(type_num)) if name == "value": + if self.m_data_type == 'string': + return OVAny(self.m_parsed_content) if self.m_parsed_content.size == 1: if isinstance(self.m_parsed_content, np.ndarray): return OVAny(Tensor(self.m_parsed_content)) diff --git a/src/bindings/python/src/openvino/runtime/__init__.py b/src/bindings/python/src/openvino/runtime/__init__.py index 869c7922c2d1fd..9bfb5a64d6a05b 100644 --- a/src/bindings/python/src/openvino/runtime/__init__.py +++ b/src/bindings/python/src/openvino/runtime/__init__.py @@ -58,6 +58,7 @@ 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 @@ # 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 diff --git a/src/bindings/python/src/openvino/runtime/opset12/__init__.py b/src/bindings/python/src/openvino/runtime/opset12/__init__.py new file mode 100644 index 00000000000000..3f8b0372bbd7b6 --- /dev/null +++ b/src/bindings/python/src/openvino/runtime/opset12/__init__.py @@ -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 diff --git a/src/bindings/python/src/openvino/runtime/opset12/ops.py b/src/bindings/python/src/openvino/runtime/opset12/ops.py new file mode 100644 index 00000000000000..881c6f0f1466c4 --- /dev/null +++ b/src/bindings/python/src/openvino/runtime/opset12/ops.py @@ -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, + }, + ) diff --git a/src/bindings/python/src/openvino/runtime/utils/node_factory.py b/src/bindings/python/src/openvino/runtime/utils/node_factory.py index f952bcf90fb4dc..4e16545db7513b 100644 --- a/src/bindings/python/src/openvino/runtime/utils/node_factory.py +++ b/src/bindings/python/src/openvino/runtime/utils/node_factory.py @@ -13,7 +13,7 @@ from openvino.runtime.exceptions import UserInputError -DEFAULT_OPSET = "opset11" +DEFAULT_OPSET = "opset12" class NodeFactory(object): diff --git a/src/bindings/python/src/pyopenvino/graph/node_factory.cpp b/src/bindings/python/src/pyopenvino/graph/node_factory.cpp index b117c45bb0993e..4e62ea387f3a96 100644 --- a/src/bindings/python/src/pyopenvino/graph/node_factory.cpp +++ b/src/bindings/python/src/pyopenvino/graph/node_factory.cpp @@ -80,7 +80,7 @@ class NodeFactory { return it->second(); } - const ov::OpSet& m_opset = ov::get_opset11(); + const ov::OpSet& m_opset = ov::get_opset12(); std::unordered_map> m_variables; }; } // namespace diff --git a/src/bindings/python/tests/test_graph/test_data_movement.py b/src/bindings/python/tests/test_graph/test_data_movement.py index edbd2b513729a9..23f426277cce75 100644 --- a/src/bindings/python/tests/test_graph/test_data_movement.py +++ b/src/bindings/python/tests/test_graph/test_data_movement.py @@ -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) diff --git a/src/bindings/python/tests/test_graph/test_normalization.py b/src/bindings/python/tests/test_graph/test_normalization.py index 6af4baa3eb515d..344013f375939f 100644 --- a/src/bindings/python/tests/test_graph/test_normalization.py +++ b/src/bindings/python/tests/test_graph/test_normalization.py @@ -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 diff --git a/src/bindings/python/tests/test_graph/test_ops_scatter.py b/src/bindings/python/tests/test_graph/test_ops_scatter.py index fe571480730e11..db6b7b796ced1e 100644 --- a/src/bindings/python/tests/test_graph/test_ops_scatter.py +++ b/src/bindings/python/tests/test_graph/test_ops_scatter.py @@ -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 diff --git a/src/bindings/python/tests/test_graph/test_pad.py b/src/bindings/python/tests/test_graph/test_pad.py new file mode 100644 index 00000000000000..af573869e61d4b --- /dev/null +++ b/src/bindings/python/tests/test_graph/test_pad.py @@ -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 diff --git a/src/bindings/python/tests/test_runtime/test_infer_request.py b/src/bindings/python/tests/test_runtime/test_infer_request.py index 945f7a95b91d77..1331ce9baf4546 100644 --- a/src/bindings/python/tests/test_runtime/test_infer_request.py +++ b/src/bindings/python/tests/test_runtime/test_infer_request.py @@ -10,7 +10,7 @@ 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 diff --git a/src/bindings/python/tests/test_runtime/test_input_node.py b/src/bindings/python/tests/test_runtime/test_input_node.py index 6c3f224e0575b0..08aab7c37ca261 100644 --- a/src/bindings/python/tests/test_runtime/test_input_node.py +++ b/src/bindings/python/tests/test_runtime/test_input_node.py @@ -7,7 +7,7 @@ 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 diff --git a/src/bindings/python/tests/test_runtime/test_model.py b/src/bindings/python/tests/test_runtime/test_model.py index 062bc66f0bb42c..e8f19e0b89bf65 100644 --- a/src/bindings/python/tests/test_runtime/test_model.py +++ b/src/bindings/python/tests/test_runtime/test_model.py @@ -7,7 +7,7 @@ import pytest import math -import openvino.runtime.opset11 as ops +import openvino.runtime.opset12 as ops from openvino.runtime import ( Core, Model, diff --git a/src/bindings/python/tests/test_runtime/test_nogil.py b/src/bindings/python/tests/test_runtime/test_nogil.py index 1370f656d051f3..542791fc7b099c 100644 --- a/src/bindings/python/tests/test_runtime/test_nogil.py +++ b/src/bindings/python/tests/test_runtime/test_nogil.py @@ -9,7 +9,7 @@ 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 diff --git a/src/bindings/python/tests/test_runtime/test_output_const_node.py b/src/bindings/python/tests/test_runtime/test_output_const_node.py index 1836f8dd07f75b..9d75a8f5d8e31a 100644 --- a/src/bindings/python/tests/test_runtime/test_output_const_node.py +++ b/src/bindings/python/tests/test_runtime/test_output_const_node.py @@ -6,7 +6,7 @@ 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, diff --git a/src/bindings/python/tests/test_runtime/test_output_node.py b/src/bindings/python/tests/test_runtime/test_output_node.py index f18f4f08de6df1..e2ff332a0a2816 100644 --- a/src/bindings/python/tests/test_runtime/test_output_node.py +++ b/src/bindings/python/tests/test_runtime/test_output_node.py @@ -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 diff --git a/src/bindings/python/tests/test_runtime/test_ovdict.py b/src/bindings/python/tests/test_runtime/test_ovdict.py index 0601b18495c7ae..8482431a827ef3 100644 --- a/src/bindings/python/tests/test_runtime/test_ovdict.py +++ b/src/bindings/python/tests/test_runtime/test_ovdict.py @@ -6,7 +6,7 @@ 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 diff --git a/src/bindings/python/tests/test_utils/test_utils.py b/src/bindings/python/tests/test_utils/test_utils.py index f447fc208f2ab5..e7c44340ebca69 100644 --- a/src/bindings/python/tests/test_utils/test_utils.py +++ b/src/bindings/python/tests/test_utils/test_utils.py @@ -12,7 +12,7 @@ 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 diff --git a/src/frontends/pytorch/src/utils.cpp b/src/frontends/pytorch/src/utils.cpp index 1f364895e44024..7a24d9e447c647 100644 --- a/src/frontends/pytorch/src/utils.cpp +++ b/src/frontends/pytorch/src/utils.cpp @@ -380,7 +380,7 @@ void align_eltwise_input_types(const NodeContext& context, Output& lhs, Ou if (otype != lhs_type) { lhs = context.mark_node(std::make_shared(lhs, otype)); } - if (otype != lhs_type) { + if (otype != rhs_type) { rhs = context.mark_node(std::make_shared(rhs, otype)); } return; diff --git a/src/frontends/tensorflow/src/frontend.cpp b/src/frontends/tensorflow/src/frontend.cpp index 6d54a2a56d775a..af25b96641d4bc 100644 --- a/src/frontends/tensorflow/src/frontend.cpp +++ b/src/frontends/tensorflow/src/frontend.cpp @@ -27,6 +27,8 @@ #include "tf_framework_node.hpp" #include "transformations/common_optimizations/remove_concat_zero_dim_input.hpp" #include "transformations/common_optimizations/reverse_shape_and_type_infer.hpp" +#include "transformations/control_flow/unroll_if.hpp" +#include "transformations/switch_merge_resolve.hpp" #include "transformations/transpose_sinking/ts_general.hpp" #include "translate_session.hpp" #include "utils.hpp" @@ -469,6 +471,8 @@ void FrontEnd::normalize(const std::shared_ptr& model) const { manager.register_pass(); manager.register_pass(); manager.register_pass(); + manager.register_pass(); + manager.register_pass(); manager.register_pass(); manager.register_pass(); manager.register_pass(); diff --git a/src/frontends/tensorflow/src/input_model.cpp b/src/frontends/tensorflow/src/input_model.cpp index b71cc880f46e17..90045d4dea5a82 100644 --- a/src/frontends/tensorflow/src/input_model.cpp +++ b/src/frontends/tensorflow/src/input_model.cpp @@ -338,9 +338,12 @@ std::vector> InputModel::InputModelTFImpl::topologicall "', expected input port index: " + std::to_string(producer_output_port_idx) + '\n'); } - // skip conditional edges for all operators if (is_conditional_edge(producer_name)) { - continue; + // exclude "^" mark indicating (execution) conditional dependency + // for example, "^sub_op" means dependency on a producer node with a name "sub_op" + // if a node has dependent operation nodes and has no data consumers, + // this node is not terminating and will not output to the Result node + producer_name = producer_name.substr(1); } // is_input is a flag to leave producer operation node or not. diff --git a/src/frontends/tensorflow/src/op/merge.cpp b/src/frontends/tensorflow/src/op/merge.cpp new file mode 100644 index 00000000000000..3594f93ed08278 --- /dev/null +++ b/src/frontends/tensorflow/src/op/merge.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "helper_ops/merge.hpp" + +#include "common_op_table.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" +#include "openvino/op/constant.hpp" +#include "utils.hpp" + +using namespace std; +using namespace ov; +using namespace ov::op; +using namespace ov::frontend::tensorflow; + +namespace ov { +namespace frontend { +namespace tensorflow { +namespace op { + +OutputVector translate_merge_op(const NodeContext& node) { + // Merge can have multiple inputs, one is minimum + auto node_name = node.get_name(); + default_op_checks(node, 1, {"Merge"}); + int input_size = static_cast(node.get_input_size()); + OutputVector inputs; + for (int input_ind = 0; input_ind < input_size; ++input_ind) { + inputs.push_back(node.get_input(input_ind)); + } + + // if Merge node has just one input, there is nothing to merge + // return the same input and value_index equal to 0 + if (inputs.size() == 1) { + auto value_index = make_shared(element::i32, Shape{}, 0); + value_index->output(0).set_names({node_name + ":1"}); + inputs[0].add_names({node_name + ":0"}); + return OutputVector{inputs[0], value_index}; + } + + auto merge_node = make_shared(inputs, node.get_decoder()); + set_node_name(node.get_name(), merge_node); + + return merge_node->outputs(); +} + +} // namespace op +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow/src/op/switch.cpp b/src/frontends/tensorflow/src/op/switch.cpp new file mode 100644 index 00000000000000..c01bdc89aa1079 --- /dev/null +++ b/src/frontends/tensorflow/src/op/switch.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "helper_ops/switch.hpp" + +#include "common_op_table.hpp" +#include "openvino/frontend/node_context.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" +#include "tf_utils.hpp" +#include "utils.hpp" + +using namespace std; +using namespace ov; +using namespace ov::frontend::tensorflow; + +namespace ov { +namespace frontend { +namespace tensorflow { +namespace op { + +OutputVector translate_switch_op(const NodeContext& node) { + default_op_checks(node, 2, {"Switch"}); + auto switch_name = node.get_name(); + auto data = node.get_input(0); + auto pred = node.get_input(1); + auto data_producer = data.get_node_shared_ptr(); + + // check if the condition goes to another Switch node + // and re-use its conditional flow marker for further grouping multiple Switch and Merge nodes + // walk through all consumers for pred and find Switch nodes + bool generate_new_marker = true; + int32_t switch_marker = 0; + auto pred_node = pred.get_node_shared_ptr(); + auto pred_index = pred.get_index(); + bool to_skip_switch = false; + for (const auto& target_input : pred_node->get_output_target_inputs(pred_index)) { + auto another_producer = target_input.get_node()->shared_from_this(); + if (const auto& another_switch = as_type_ptr(another_producer)) { + if (another_switch->is_cond_flow_marker_set() && cf_marker_exists(another_switch)) { + switch_marker = another_switch->get_cond_flow_marker(); + generate_new_marker = false; + } + + // in case two consecutive Switch nodes with the common predicate + // the successor can be skipped + if (another_switch == data_producer) { + to_skip_switch = true; + generate_new_marker = false; + break; + } + } + } + + if (generate_new_marker) { + // generate marker for new conditioning flow + switch_marker = generate_cf_marker(); + } + auto switch_node = make_shared(data, pred, switch_marker, node.get_decoder()); + + // in case two consecutive Switch nodes with the common predicate + // it skips successive Switch node + if (to_skip_switch) { + auto data_output_index = data.get_index(); + FRONT_END_GENERAL_CHECK(data_output_index == 0 || data_output_index == 1, + "[TensorFlow Frontend] internal error: Switch node must have two outputs"); + size_t other_output_index = 1 - data_output_index; + data.add_names({switch_name + ":" + to_string(data_output_index)}); + auto other_switch_output = switch_node->output(other_output_index); + other_switch_output.add_names({switch_name + ":" + to_string(other_output_index)}); + if (data_output_index == 0) { + return OutputVector{data, other_switch_output}; + } else { + return OutputVector{other_switch_output, data}; + } + } + + // set output tensor names and move the node name + set_node_name(switch_name, switch_node); + return switch_node->outputs(); +} + +} // namespace op +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow/src/op_table.cpp b/src/frontends/tensorflow/src/op_table.cpp index 42202e9a0d210b..7ec883a2f399ea 100644 --- a/src/frontends/tensorflow/src/op_table.cpp +++ b/src/frontends/tensorflow/src/op_table.cpp @@ -28,6 +28,7 @@ TF_OP_CONVERTER(translate_hash_table_op); TF_OP_CONVERTER(translate_if_op); TF_OP_CONVERTER(translate_iterator_get_next_op); TF_OP_CONVERTER(translate_iterator_op); +TF_OP_CONVERTER(translate_merge_op); TF_OP_CONVERTER(translate_mergev2checkpoint_op); TF_OP_CONVERTER(translate_partitioned_call_op); TF_OP_CONVERTER(translate_placeholder_linked_op); @@ -40,6 +41,7 @@ TF_OP_CONVERTER(translate_sparse_reshape_op); TF_OP_CONVERTER(translate_sparse_segment_sum_op); TF_OP_CONVERTER(translate_staticregexfullmatch_op); TF_OP_CONVERTER(translate_stringjoin_op); +TF_OP_CONVERTER(translate_switch_op); TF_OP_CONVERTER(translate_varhandle_op); TF_OP_CONVERTER(translate_variable_op); TF_OP_CONVERTER(translate_varisinitialized_op); @@ -182,6 +184,7 @@ const std::map get_supported_ops() { {"MaxPool", CreatorFunction(translate_max_pool_op)}, {"MaxPoolV2", CreatorFunction(translate_max_pool_op)}, {"MaxPool3D", CreatorFunction(translate_max_pool_op)}, + {"Merge", CreatorFunction(translate_merge_op)}, {"MirrorPad", CreatorFunction(translate_mirror_pad_op)}, {"MutableHashTable", CreatorFunction(translate_hash_table_op)}, {"MutableHashTableV2", CreatorFunction(translate_hash_table_op)}, @@ -247,6 +250,7 @@ const std::map get_supported_ops() { {"StatelessIf", CreatorFunction(translate_if_op)}, {"StatelessWhile", CreatorFunction(translate_while_op)}, {"StridedSlice", CreatorFunction(translate_strided_slice_op)}, + {"Switch", CreatorFunction(translate_switch_op)}, {"TensorListFromTensor", CreatorFunction(translate_tensor_list_from_tensor_op)}, {"TensorListGetItem", CreatorFunction(translate_tensor_list_get_item_op)}, {"TensorListPushBack", CreatorFunction(translate_tensor_list_push_back_op)}, diff --git a/src/frontends/tensorflow/src/tf_utils.cpp b/src/frontends/tensorflow/src/tf_utils.cpp index 7cccb50708858c..52c64f5e43c54c 100644 --- a/src/frontends/tensorflow/src/tf_utils.cpp +++ b/src/frontends/tensorflow/src/tf_utils.cpp @@ -6,16 +6,61 @@ #include +#include + +#include "helper_ops/merge.hpp" +#include "helper_ops/switch.hpp" #include "openvino/core/type/element_type.hpp" #include "openvino/frontend/exception.hpp" #include "openvino/runtime/tensor.hpp" using namespace ov; +using namespace ov::element; +using namespace ov::frontend::tensorflow; +using namespace std; namespace { +void copy_conditional_flow_marker_with_branches(const CfMarkerType& copy_from, + unordered_map& copy_to_braches) { + for (const auto& marker : copy_from.existing_markers_with_branches) { + const auto& switch_marker = marker.first; + const auto& branch_markers = marker.second; + copy_to_braches[switch_marker].insert(branch_markers.begin(), branch_markers.end()); + } +} + +void copy_conditional_flow_marker_with_switches(const CfMarkerType& copy_from, + unordered_map& copy_to_switches) { + for (const auto& marker : copy_from.existing_markers_with_switches) { + const auto& switch_marker = marker.first; + const auto& branch_markers = marker.second; + copy_to_switches[switch_marker].insert(branch_markers.begin(), branch_markers.end()); + } +} + +void copy_conditional_flow_markers_for_producer( + unordered_map& combined_markers_with_braches, + unordered_map& combined_markers_with_switches, + const Output& producer_output) { + // walk through all data producer and collect conditional flow markers + const shared_ptr& producer_node = producer_output.get_node_shared_ptr(); + uint32_t branch_index = static_cast(producer_output.get_index()); + if (!cf_marker_exists(producer_node)) { + return; + } + auto producer_markers = get_cf_marker(producer_node); + copy_conditional_flow_marker_with_branches(producer_markers, combined_markers_with_braches); + copy_conditional_flow_marker_with_switches(producer_markers, combined_markers_with_switches); + // if data goes from Switch node, it needs to create a new marker and branch marker + for (const auto& new_marker : producer_markers.new_markers) { + auto switch_nodes = new_marker.second; + combined_markers_with_braches[new_marker.first].insert(branch_index); + combined_markers_with_switches[new_marker.first].insert(switch_nodes.begin(), switch_nodes.end()); + } +} template -void extract_tensor_content(const std::string& tensor_content, ov::Tensor* values) { +void extract_tensor_content(const string& tensor_content, Tensor* values) { const auto tensor_content_size = tensor_content.size(); FRONT_END_GENERAL_CHECK(tensor_content_size % sizeof(T) == 0, "Size of tensor_content (", @@ -26,7 +71,7 @@ void extract_tensor_content(const std::string& tensor_content, ov::Tensor* value const T* tensor_values = reinterpret_cast(tensor_content.data()); FRONT_END_GENERAL_CHECK(values->get_size() == tensor_content_size / sizeof(T), "Size of tensor is not equal to tensor_content size."); - std::copy(tensor_values, tensor_values + tensor_content_size / sizeof(T), values->data()); + copy(tensor_values, tensor_values + tensor_content_size / sizeof(T), values->data()); } #if defined(_MSC_VER) @@ -37,7 +82,7 @@ void extract_tensor_content(const std::string& tensor_content, ov::Tensor* value template void extract_compressed_tensor_content(const ::tensorflow::TensorProto& tensor_proto, int64_t val_size, - ov::Tensor* values) { + Tensor* values) { auto val_lastsaved = static_cast(0); auto values_data = values->data(); for (size_t i = 0; i < values->get_size(); i++) { @@ -47,22 +92,22 @@ void extract_compressed_tensor_content(const ::tensorflow::TensorProto& tensor_p auto val_i = static_cast(0); switch (values->get_element_type()) { // TODO: there are more element types to support here - case ov::element::boolean: + case boolean: val_i = tensor_proto.bool_val()[i]; break; - case ov::element::i32: + case i32: val_i = tensor_proto.int_val()[i]; break; - case ov::element::i64: + case i64: val_i = tensor_proto.int64_val()[i]; break; - case ov::element::f16: + case f16: val_i = float16::from_bits(tensor_proto.half_val()[i]); break; - case ov::element::f32: + case f32: val_i = tensor_proto.float_val()[i]; break; - case ov::element::f64: + case f64: val_i = tensor_proto.double_val()[i]; break; default: @@ -80,78 +125,98 @@ void extract_compressed_tensor_content(const ::tensorflow::TensorProto& tensor_p #endif } // namespace -ov::element::Type ov::frontend::tensorflow::get_ov_type(const ::tensorflow::DataType& type) { - static const std::map<::tensorflow::DataType, ov::element::Type> type_map{ - {::tensorflow::DataType::DT_BOOL, ov::element::boolean}, - {::tensorflow::DataType::DT_INT16, ov::element::i16}, - {::tensorflow::DataType::DT_INT32, ov::element::i32}, - {::tensorflow::DataType::DT_INT64, ov::element::i64}, - {::tensorflow::DataType::DT_HALF, ov::element::f16}, - {::tensorflow::DataType::DT_FLOAT, ov::element::f32}, - {::tensorflow::DataType::DT_DOUBLE, ov::element::f64}, - {::tensorflow::DataType::DT_UINT8, ov::element::u8}, - {::tensorflow::DataType::DT_INT8, ov::element::i8}, - {::tensorflow::DataType::DT_BFLOAT16, ov::element::bf16}}; +namespace ov { +namespace frontend { +namespace tensorflow { + +void copy_conditional_flow_marker(const CfMarkerType& copy_from, CfMarkerType& copy_to) { + for (const auto& marker : copy_from.existing_markers_with_branches) { + const auto& switch_marker = marker.first; + const auto& branch_markers = marker.second; + copy_to.existing_markers_with_branches[switch_marker].insert(branch_markers.begin(), branch_markers.end()); + } + for (const auto& marker : copy_from.existing_markers_with_switches) { + const auto& switch_marker = marker.first; + const auto& branch_markers = marker.second; + copy_to.existing_markers_with_switches[switch_marker].insert(branch_markers.begin(), branch_markers.end()); + } +} + +bool CfMarkerType::is_copyable() const { + return false; +} + +Type get_ov_type(const ::tensorflow::DataType& type) { + static const map<::tensorflow::DataType, Type> type_map{{::tensorflow::DataType::DT_BOOL, boolean}, + {::tensorflow::DataType::DT_INT16, i16}, + {::tensorflow::DataType::DT_INT32, i32}, + {::tensorflow::DataType::DT_INT64, i64}, + {::tensorflow::DataType::DT_HALF, f16}, + {::tensorflow::DataType::DT_FLOAT, f32}, + {::tensorflow::DataType::DT_DOUBLE, f64}, + {::tensorflow::DataType::DT_UINT8, u8}, + {::tensorflow::DataType::DT_INT8, i8}, + {::tensorflow::DataType::DT_BFLOAT16, bf16}}; auto it = type_map.find(type); // for all unsupported types return dynamic type - return it == type_map.end() ? ov::element::dynamic : it->second; + return it == type_map.end() ? dynamic : it->second; } -ov::Any ov::frontend::tensorflow::unpack_tensor_proto(const ::tensorflow::TensorProto& tensor_proto) { +Any unpack_tensor_proto(const ::tensorflow::TensorProto& tensor_proto) { return unpack_tensor_proto(tensor_proto, tensor_proto.tensor_shape(), tensor_proto.dtype()); } -ov::Any ov::frontend::tensorflow::unpack_tensor_proto(const ::tensorflow::TensorProto& tensor_proto, - const ::tensorflow::TensorShapeProto& tensor_shape, - const ::tensorflow::DataType& tensor_type) { - ov::PartialShape pshape; +Any unpack_tensor_proto(const ::tensorflow::TensorProto& tensor_proto, + const ::tensorflow::TensorShapeProto& tensor_shape, + const ::tensorflow::DataType& tensor_type) { + PartialShape pshape; for (int i = 0; i < tensor_shape.dim_size(); i++) { pshape.push_back(tensor_shape.dim(i).size()); } FRONT_END_GENERAL_CHECK(pshape.is_static(), "Dynamic shapes are not supported for Tensor attribute."); - ov::element::Type ov_type = get_ov_type(tensor_type); + Type ov_type = get_ov_type(tensor_type); if (tensor_type != ::tensorflow::DataType::DT_STRING) { FRONT_END_GENERAL_CHECK( ov_type.is_static(), "Encountered unknown element type " + DataType_Name(tensor_type) + " on an empty tensor_proto"); } else { - auto data = std::vector(); + auto data = vector(); for (const auto& item : tensor_proto.string_val()) { data.push_back(item); } return data; } - ov::Tensor res(ov_type, pshape.get_shape()); + Tensor res(ov_type, pshape.get_shape()); auto tensor_content = tensor_proto.tensor_content(); if (!tensor_content.empty() && tensor_proto.has_tensor_shape()) { switch (ov_type) { - case ov::element::u8: + case u8: extract_tensor_content(tensor_content, &res); break; - case ov::element::i8: + case i8: extract_tensor_content(tensor_content, &res); break; - case ov::element::i16: + case i16: extract_tensor_content(tensor_content, &res); break; - case ov::element::i32: + case i32: extract_tensor_content(tensor_content, &res); break; - case ov::element::i64: + case i64: extract_tensor_content(tensor_content, &res); break; - case ov::element::f16: + case f16: extract_tensor_content(tensor_content, &res); break; - case ov::element::f32: + case f32: extract_tensor_content(tensor_content, &res); break; - case ov::element::f64: + case f64: extract_tensor_content(tensor_content, &res); break; - case ov::element::bf16: + case bf16: extract_tensor_content(tensor_content, &res); break; default: @@ -160,27 +225,27 @@ ov::Any ov::frontend::tensorflow::unpack_tensor_proto(const ::tensorflow::Tensor } else { int64_t val_size = 0; switch (ov_type) { - case ov::element::boolean: + case boolean: val_size = tensor_proto.bool_val_size(); extract_compressed_tensor_content(tensor_proto, val_size, &res); break; - case ov::element::i32: + case i32: val_size = tensor_proto.int_val_size(); extract_compressed_tensor_content(tensor_proto, val_size, &res); break; - case ov::element::i64: + case i64: val_size = tensor_proto.int64_val_size(); extract_compressed_tensor_content(tensor_proto, val_size, &res); break; - case ov::element::f16: + case f16: val_size = tensor_proto.half_val_size(); extract_compressed_tensor_content(tensor_proto, val_size, &res); break; - case ov::element::f32: + case f32: val_size = tensor_proto.float_val_size(); extract_compressed_tensor_content(tensor_proto, val_size, &res); break; - case ov::element::f64: + case f64: val_size = tensor_proto.double_val_size(); extract_compressed_tensor_content(tensor_proto, val_size, &res); break; @@ -190,3 +255,123 @@ ov::Any ov::frontend::tensorflow::unpack_tensor_proto(const ::tensorflow::Tensor } return res; } + +CfMarkerType get_cf_marker(const shared_ptr& node) { + auto rt_info = node->get_rt_info(); + FRONT_END_GENERAL_CHECK(rt_info.count(CF_MARKER_TAG) > 0, + "[TensorFlow Frontend] internal error: node does not contain conditional flow marker"); + auto& ov_any_cf_marker = rt_info[CF_MARKER_TAG]; + FRONT_END_GENERAL_CHECK(ov_any_cf_marker.is(), + "[TensorFlow Frontend] internal error: incorrect type of conditional flow marker"); + return ov_any_cf_marker.as(); +} + +uint32_t generate_cf_marker() { + static uint32_t marker = 0; + return marker++; +} + +bool propagate_conditional_flow(const OutputVector& ov_inputs, + const frontend::NamedOutputVector& ov_outputs, + const set>& input_control_deps, + set>& output_control_deps) { + // returns if there is conditional flow to propagate + // it checks all producer-nodes connected via data edges and control dependencies + // compute combined markers + // it is a map from conditional flow marker to a set of branch markers + unordered_map combined_markers_with_branches; + unordered_map combined_markers_with_switches; + for (const auto& ov_input : ov_inputs) { + // walk through all input producers and propagate CF marker + copy_conditional_flow_markers_for_producer(combined_markers_with_branches, + combined_markers_with_switches, + ov_input); + } + // walk through all control dependencies and collect conditional flow markers + for (const auto& input_control_dep : input_control_deps) { + // walk through all control dependencies and collect conditional flow markers + copy_conditional_flow_markers_for_producer(combined_markers_with_branches, + combined_markers_with_switches, + input_control_dep); + } + + // walk through all nodes and mark them if needed + bool to_propagate = false; + for (const auto& ov_output : ov_outputs) { + const auto& node = ov_output.port.get_node_shared_ptr(); + + // skip already marked node + // it can be a case of Identity node that the conversion rule skips + if (cf_marker_exists(node)) { + to_propagate = true; + continue; + } + + // if this is Merge node, it needs to eliminate markers with multiple branch markers + // and put such markers into eliminated list + CfMarkerType resulted_cf_marker; + if (as_type_ptr(node)) { + for (const auto& marker : combined_markers_with_branches) { + auto switch_marker = marker.first; + auto branch_markers = marker.second; + if (branch_markers.size() > 1) { + if (combined_markers_with_switches.count(switch_marker) > 0) { + resulted_cf_marker.merge_eliminated_markers[switch_marker] = + combined_markers_with_switches[switch_marker]; + } + } else { + resulted_cf_marker.existing_markers_with_branches.insert(marker); + if (combined_markers_with_switches.count(switch_marker) > 0) { + resulted_cf_marker.existing_markers_with_switches[switch_marker] = + combined_markers_with_switches[switch_marker]; + } + } + } + } else if (const auto& switch_node = as_type_ptr(node)) { + // update conditional flow marker with new marker for the current Switch node + auto switch_marker = switch_node->get_switch_marker(); + resulted_cf_marker.new_markers[switch_marker] = {switch_node}; + resulted_cf_marker.existing_markers_with_branches = combined_markers_with_branches; + resulted_cf_marker.existing_markers_with_switches = combined_markers_with_switches; + } else { + // check that non-Merge node does not expect data/flow from different Switch branches + // it means inconsistent model + for (const auto& marker : combined_markers_with_branches) { + auto branch_markers = marker.second; + FRONT_END_GENERAL_CHECK( + branch_markers.size() < 2, + "[TensorFlow Frontend] inconsistent input model: non-Merge node expects data or " + "flow from different branches of one Switch node"); + resulted_cf_marker.existing_markers_with_branches.insert(marker); + } + resulted_cf_marker.existing_markers_with_switches.insert(combined_markers_with_switches.begin(), + combined_markers_with_switches.end()); + } + + // set conditional flow marker only if one of the fields is not empty + // check if any input or input control dependency contain control flow + // if yes, it makes sense to continue + if (resulted_cf_marker.new_markers.size() > 0 || resulted_cf_marker.existing_markers_with_branches.size() > 0 || + resulted_cf_marker.existing_markers_with_switches.size() > 0 || + resulted_cf_marker.merge_eliminated_markers.size() > 0) { + set_cf_marker(resulted_cf_marker, node); + to_propagate = true; + } + } + + // compute output control dependencies + // logically, the next nodes will dependend on outputs and input control dependencies + output_control_deps.clear(); + if (to_propagate) { + output_control_deps = input_control_deps; + for (const auto& ov_output : ov_outputs) { + output_control_deps.insert(ov_output.port); + } + } + + return to_propagate; +} + +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow/src/tf_utils.hpp b/src/frontends/tensorflow/src/tf_utils.hpp index 8c8af31e231d66..a7a80a522b70a3 100644 --- a/src/frontends/tensorflow/src/tf_utils.hpp +++ b/src/frontends/tensorflow/src/tf_utils.hpp @@ -6,9 +6,12 @@ #include "attr_value.pb.h" #include "node_def.pb.h" +#include "openvino/core/node.hpp" #include "openvino/core/partial_shape.hpp" +#include "openvino/core/runtime_attribute.hpp" #include "openvino/core/type.hpp" #include "openvino/core/type/element_type.hpp" +#include "openvino/frontend/node_context.hpp" #include "openvino/runtime/tensor.hpp" #include "tensor.pb.h" #include "tensor_shape.pb.h" @@ -18,6 +21,8 @@ namespace ov { namespace frontend { namespace tensorflow { +#define CF_MARKER_TAG "tf_cf_marker_tag" + ov::element::Type get_ov_type(const ::tensorflow::DataType& type); ov::Any unpack_tensor_proto(const ::tensorflow::TensorProto& tensor_proto); @@ -26,6 +31,77 @@ ov::Any unpack_tensor_proto(const ::tensorflow::TensorProto& tensor_proto, const ::tensorflow::TensorShapeProto& tensor_shape, const ::tensorflow::DataType& tensor_type); +class Switch; +using SetOfSwitchNodes = std::unordered_set>; +using SetOfBranchIndices = std::unordered_set; + +// structure to save conditional flow marker +class CfMarkerType : public ov::RuntimeAttribute { +public: + OPENVINO_RTTI("CfMarkerType"); + CfMarkerType() = default; + bool is_copyable() const override; + +public: + // new_markers serves to mark Switch node and saves its own marker id + // Switch node contains only one marker + // for other type of nodes, new_markers vector is empty + // std::vector>> new_markers; + std::unordered_map new_markers; + + // existing_markers contains Switch node markers collected so far + // and indices of conditional flow branches + // for example, If operation (represented with Switch-Merge node) has two branches with indices 0 and 1 + std::unordered_map existing_markers_with_branches; + std::unordered_map existing_markers_with_switches; + + // merge_eliminated_markers is not empty only for Merge node when several branches of the same conditional flow + // are merging by this Merge node + // for example, if existing_markers contains element with a key = 4 (it means the fourth conditional flow) + // and value {0, 1}, it means Merge node eliminates this conditional flow with marker = 4 + // std::vector> merge_eliminated_markers; + std::unordered_map merge_eliminated_markers; + + // a container with already eliminated markers for nodes going after Merge nodes + // that eliminated conditional flow with these markers + // this container is needed do not duplicate markers for If sub-graphs that goes after other If + // sub-graphs with common condition + // std::unordered_set already_eliminated_markers; +}; + +// a map type to save data/control edges from which the node is dependent +using ControlDepsMap = std::unordered_map>>; + +// check if the given node contains conditional flow marker in run-time info +inline bool cf_marker_exists(const std::shared_ptr& node) { + const auto& rt_info = node->get_rt_info(); + return rt_info.count(CF_MARKER_TAG) > 0; +} + +// retrieves conditional flow marker in run-time info for the given node +CfMarkerType get_cf_marker(const std::shared_ptr& node); + +// sets conditional flow marker for the given node in run-time info +// inline void set_cf_marker(const CfMarkerType& cf_marker, const std::shared_ptr& node); +inline void set_cf_marker(const CfMarkerType& cf_marker, const std::shared_ptr& node) { + node->get_rt_info()[CF_MARKER_TAG] = cf_marker; +} + +// generates unique conditional flow marker index +// Note: the next TranslateSession (for conversion in parallel) does not reset initial marker +// and it must not affect conversion of models in different sessions +uint32_t generate_cf_marker(); + +// propagate conditional flow markers to nodes generating ov_outputs +// based on conditional flow presence in input nodes +// also, it creates a vector of tensor/edges output_control_deps from which the current node(s) is dependent +bool propagate_conditional_flow(const ov::OutputVector& ov_inputs, + const ov::frontend::NamedOutputVector& ov_outputs, + const std::set>& input_control_deps, + std::set>& output_control_deps); + +// copy existing markers from copy_from to copy_to marker +void copy_conditional_flow_marker(const CfMarkerType& copy_from, CfMarkerType& copy_to); } // namespace tensorflow } // namespace frontend } // namespace ov diff --git a/src/frontends/tensorflow/src/transformations/switch_merge_resolve.cpp b/src/frontends/tensorflow/src/transformations/switch_merge_resolve.cpp new file mode 100644 index 00000000000000..af03b24519c29d --- /dev/null +++ b/src/frontends/tensorflow/src/transformations/switch_merge_resolve.cpp @@ -0,0 +1,270 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/switch_merge_resolve.hpp" + +#include +#include + +#include "helper_ops/merge.hpp" +#include "helper_ops/switch.hpp" +#include "openvino/core/node.hpp" +#include "openvino/frontend/exception.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/if.hpp" +#include "openvino/op/parameter.hpp" +#include "openvino/op/result.hpp" +#include "tf_utils.hpp" + +using namespace ov; +using namespace ov::frontend::tensorflow; +using namespace ov::frontend; +using namespace ov::op; +using namespace std; + +namespace ov { +namespace frontend { +namespace tensorflow { + +namespace { +using ClusterType = pair>, unordered_set>>; + +bool intersected(const unordered_set>& s1, const unordered_set>& s2) { + bool is_intersected = false; + for (const auto& node1 : s1) { + for (const auto& node2 : s2) { + if (node1 == node2) { + is_intersected = true; + break; + } + } + } + return is_intersected; +} + +void generate_if_clusters(const shared_ptr& ov_model, + unordered_map>>& switch_clusters, + unordered_map>>& merge_clusters) { + // each pair represents a cluster circled with Switch and Merge nodes + vector clusters; + for (const auto& node : ov_model->get_ordered_ops()) { + if (const auto& merge_node = as_type_ptr(node)) { + if (!merge_node->is_cond_flow_eliminated()) { + continue; + } + auto eliminated_markers = merge_node->get_eliminated_cond_flow_marker(); + if (eliminated_markers.size() != 1) { + continue; + } + + auto eliminated_marker = eliminated_markers[0]; + auto switch_nodes = merge_node->get_switch_nodes_set_by_cond_index(eliminated_marker); + + // insert into clusters + ClusterType combined_cluster = {switch_nodes, {merge_node}}; + vector refined_clusters; + for (const auto& cluster : clusters) { + const auto& cluster_switches = cluster.first; + const auto& cluster_merges = cluster.second; + if (intersected(cluster_switches, combined_cluster.first)) { + combined_cluster.first.insert(cluster_switches.begin(), cluster_switches.end()); + combined_cluster.second.insert(cluster_merges.begin(), cluster_merges.end()); + } else { + refined_clusters.push_back(cluster); + } + } + refined_clusters.push_back(combined_cluster); + clusters = refined_clusters; + } + } + + // repack clusters to two separate maps for Switch and Merge nodes + switch_clusters.clear(); + merge_clusters.clear(); + uint32_t clusters_size = static_cast(clusters.size()); + for (uint32_t cluster_id = 0; cluster_id < clusters_size; ++cluster_id) { + switch_clusters[cluster_id] = clusters[cluster_id].first; + merge_clusters[cluster_id] = clusters[cluster_id].second; + } +} + +shared_ptr replace_switch_output_with_parameter(const shared_ptr& switch_node, + size_t output_ind) { + FRONT_END_GENERAL_CHECK(output_ind < 2, + "[TensorFlow Frontend] internal error: incorrect output index for Switch node"); + auto switch_output = switch_node->output(output_ind); + + auto parameter_node = + make_shared(switch_output.get_element_type(), switch_output.get_partial_shape()); + auto cf_marker = get_cf_marker(switch_node); + auto switch_marker = switch_node->get_cond_flow_marker(); + cf_marker.existing_markers_with_branches[switch_marker].insert(static_cast(output_ind)); + cf_marker.existing_markers_with_switches[switch_marker].insert(switch_node); + cf_marker.new_markers.clear(); + set_cf_marker(cf_marker, parameter_node); + + switch_output.replace(parameter_node); + + return parameter_node; +} + +void insert_result_before_merge(const shared_ptr& merge_node, + size_t input_ind, + uint32_t& branch_index, + shared_ptr& result_output, + shared_ptr& result_value_index) { + // check that handled Marge node contains conditional flow marker + auto merge_node_name = merge_node->get_friendly_name(); + FRONT_END_GENERAL_CHECK(cf_marker_exists(merge_node), + "[TensorFlow Frontend] internal error: Merge node " + merge_node_name + + " does not have conditional flow marker"); + + // get eliminated marker and check that it is the single one + auto merge_cf_marker = get_cf_marker(merge_node); + FRONT_END_GENERAL_CHECK(merge_cf_marker.merge_eliminated_markers.size() == 1, + "[TensorFlow Frontend] internal error: Merge node " + merge_node_name + + " does not contain the single eliminated marker"); + auto eliminated_marker = merge_cf_marker.merge_eliminated_markers.begin()->first; + + // check that producer contains the same conditional flow marker + // and retrive branch index for it + const auto& merge_input = merge_node->input(input_ind); + const auto& input_value = merge_node->input_value(input_ind); + const shared_ptr& merge_producer = merge_node->get_input_node_shared_ptr(input_ind); + auto producer_cf_marker = get_cf_marker(merge_producer); + FRONT_END_GENERAL_CHECK( + producer_cf_marker.existing_markers_with_branches.count(eliminated_marker) > 0, + "[TensorFlow Frontend] internal error: input producer for Merge node does not contain eliminated marker"); + + auto branch_index_set = producer_cf_marker.existing_markers_with_branches[eliminated_marker]; + FRONT_END_GENERAL_CHECK(branch_index_set.size() == 1, + "[TensorFlow Frontend] internal error: it must contain the single branch index"); + branch_index = *next(branch_index_set.begin(), 0); + + auto value_index = make_shared(element::i32, Shape{}, input_ind); + result_output = make_shared(input_value); + result_value_index = make_shared(value_index); + input_value.remove_target_input(merge_input); +} + +} // namespace + +bool pass::SwitchMergeResolver::run_on_model(const shared_ptr& m) { + // split set of Switch and Merge nodes to clusters + // where each cluster of Switch and Merge nodes will represent + // the single If operation for fusing + unordered_map>> switch_clusters; + unordered_map>> merge_clusters; + generate_if_clusters(m, switch_clusters, merge_clusters); + + // fuse Switch-Merge sub-graphs into If operation + for (const auto& marker_to_merge_nodes : merge_clusters) { + const auto& cluster_id = marker_to_merge_nodes.first; + const auto& merge_nodes = marker_to_merge_nodes.second; + const auto& switch_nodes = switch_clusters[cluster_id]; + if (merge_nodes.size() == 0 || switch_nodes.size() == 0) { + continue; + } + + auto cond = (*(switch_nodes.begin()))->input_value(1); + + // collect Parameter nodes and Result nodes for then and else bodies + // set inputs and outputs for If node + // create then bodies for which condition is true + ParameterVector then_params, else_params; + ResultVector then_results, else_results; + OutputVector if_inputs, if_outputs; + vector> if_outputs_names; + + for (const auto& switch_node : switch_nodes) { + if_inputs.push_back(switch_node->input_value(0)); + auto parameter_node_false = replace_switch_output_with_parameter(switch_node, 0); + auto parameter_node_true = replace_switch_output_with_parameter(switch_node, 1); + then_params.push_back(parameter_node_true); + else_params.push_back(parameter_node_false); + } + + CfMarkerType if_cf_marker; + for (const auto& merge_node : merge_nodes) { + // combine conditional markers from all Merge nodes + // from which it results If node + const auto& merge_cf_marker = get_cf_marker(merge_node); + copy_conditional_flow_marker(merge_cf_marker, if_cf_marker); + + for (size_t input_ind = 0; input_ind < merge_node->get_input_size(); ++input_ind) { + uint32_t branch_index = 0; + shared_ptr result_output, result_value_index; + insert_result_before_merge(merge_node, input_ind, branch_index, result_output, result_value_index); + FRONT_END_GENERAL_CHECK( + branch_index == 0 || branch_index == 1, + "[TensorFlow Frontend] internal error: conditional branch with unexpected index"); + if (branch_index == 0) { + // handle else-branch since the first output of Switch is output_false + else_results.push_back(result_output); + else_results.push_back(result_value_index); + } else if (branch_index == 1) { + // handle then-branch since the second output of Switch is output_true + then_results.push_back(result_output); + then_results.push_back(result_value_index); + } + } + for (const auto& merge_output : merge_node->outputs()) { + if_outputs.push_back(merge_output); + if_outputs_names.push_back(merge_output.get_names()); + } + } + + // create body graphs for then and else branches + auto then_body = make_shared(then_results, then_params); + auto else_body = make_shared(else_results, else_params); + + auto if_op = make_shared(cond); + set_cf_marker(if_cf_marker, if_op); + if_op->set_then_body(then_body); + if_op->set_else_body(else_body); + + // set inputs + size_t input_size = if_inputs.size(); + FRONT_END_GENERAL_CHECK( + input_size == then_params.size(), + "[TensorFlow Frontend] internal error: number of Switch inputs does not match a number of outputs"); + FRONT_END_GENERAL_CHECK( + input_size == else_params.size(), + "[TensorFlow Frontend] internal error: number of Switch inputs does not match a number of outputs"); + for (size_t ind = 0; ind < input_size; ++ind) { + auto curr_input = if_inputs[ind]; + auto then_param = then_params[ind]; + auto else_param = else_params[ind]; + if_op->set_input(curr_input, then_param, else_param); + } + + // set outputs + FRONT_END_GENERAL_CHECK(then_results.size() == else_results.size(), + "[TensorFlow Frontend] internal error: number of result nodes in " + "then and else branches do not match."); + size_t output_size = then_results.size(); + for (size_t ind = 0; ind < output_size; ++ind) { + if_op->set_output(then_results[ind], else_results[ind]); + } + + auto ov_outputs = if_op->outputs(); + FRONT_END_GENERAL_CHECK(if_op->outputs().size() == if_outputs.size(), + "[TensorFlow Frontend] internal error: number of actual If outputs does not match " + "expected number for Switch-Merge nodes fusing into If operation"); + // replace source for all consumers of Merge nodes outputs + // and move their tensor names to new outputs + size_t output_ind = 0; + for (auto& if_output : if_op->outputs()) { + if_outputs[output_ind].replace(if_output); + if_output.set_names(if_outputs_names[output_ind]); + ++output_ind; + } + } + + return true; +} + +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow/src/transformations/switch_merge_resolve.hpp b/src/frontends/tensorflow/src/transformations/switch_merge_resolve.hpp new file mode 100644 index 00000000000000..c2f38ab2092a4d --- /dev/null +++ b/src/frontends/tensorflow/src/transformations/switch_merge_resolve.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/pass/pass.hpp" + +namespace ov { +namespace frontend { +namespace tensorflow { +namespace pass { + +// This transformation fuses Switch-Merge sub-graphs into If operation +// After control flow markers propagation, Switch and Merge nodes +// can contain CF markers so that Switch and Merge nodes with the same marker values +// in new_markers and eliminated markers will be fused into If operation where +// then_branch is represented by a graph below output_true branch of Switch and else_branch is by output_false. +// Moreover, several Switch nodes may have the same new_markers that means the resulted If will have several inputs. +// Merge nodes can have the same eliminated markers that means the fused If will have several outputs. +class SwitchMergeResolver : public ov::pass::ModelPass { +public: + OPENVINO_RTTI("ov::frontend::tensorflow::SwitchMergeResolver"); + SwitchMergeResolver() = default; + + bool run_on_model(const std::shared_ptr& m) override; +}; + +} // namespace pass +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow/src/translate_session.cpp b/src/frontends/tensorflow/src/translate_session.cpp index 34262cb4014ef0..88722dc9dc21b1 100644 --- a/src/frontends/tensorflow/src/translate_session.cpp +++ b/src/frontends/tensorflow/src/translate_session.cpp @@ -9,6 +9,7 @@ #include "openvino/opsets/opset10.hpp" #include "openvino/opsets/opset8.hpp" #include "tf_framework_node.hpp" +#include "tf_utils.hpp" #include "utils.hpp" using namespace ov::frontend::tensorflow; @@ -186,6 +187,8 @@ void TranslateSession::inject_body_model(std::shared_ptr body_model, void TranslateSession::translate_graph(const ov::frontend::InputModel::Ptr& input_model, std::shared_ptr& ov_model) { OpMap ng_op_map; + ControlDepsMap control_deps_map; + ov::ParameterVector params; ov::ResultVector results; const auto& model_tf = std::dynamic_pointer_cast(input_model); @@ -241,16 +244,13 @@ void TranslateSession::translate_graph(const ov::frontend::InputModel::Ptr& inpu // prepare a list of OV node inputs for each node ov::OutputVector ov_inputs; size_t operation_input_size = operation_decoder->get_input_size(); + std::vector control_dependencies_names; if (operation_decoder->get_op_type() == "NextIteration") { // we expect no inputs for NextIteration because we break-up the cycle in InputModel operation_input_size = 0; } for (size_t input_port_idx = 0; input_port_idx < operation_input_size; ++input_port_idx) { - // TODO: Implement more general approach. Skipping Constants that have input edges - if (operation_decoder->get_op_type() == "Const") { - break; - } std::string producer_name; size_t producer_port_idx; try { @@ -270,6 +270,8 @@ void TranslateSession::translate_graph(const ov::frontend::InputModel::Ptr& inpu // skip conditional edges that must be resolved before operation translation // now we can meet them because we still work with TensorFlow protobuf if (is_conditional_edge(producer_name)) { + // control dependency contains "^" in the beginning + control_dependencies_names.push_back(producer_name.substr(1)); continue; } @@ -357,6 +359,20 @@ void TranslateSession::translate_graph(const ov::frontend::InputModel::Ptr& inpu ov_outputs = named_from_indexed(fw_node->outputs()); } + // create input control dependencies set for the current operation node + std::set> input_control_deps; + for (const auto& control_dep_name : control_dependencies_names) { + if (control_deps_map.count(control_dep_name) > 0) { + const auto& input_control_dep = control_deps_map[control_dep_name]; + input_control_deps.insert(input_control_dep.cbegin(), input_control_dep.cend()); + } + } + // register output control dependencies in control dependencies map + std::set> output_control_deps; + if (propagate_conditional_flow(ov_inputs, ov_outputs, input_control_deps, output_control_deps)) { + control_deps_map[operation_name] = output_control_deps; + } + // register OV node outputs in the map for new operation node for (const auto& output : ov_outputs) { if (auto result = as_type_ptr(output.port.get_node_shared_ptr())) { diff --git a/src/frontends/tensorflow/tests/convert_tricky_models.cpp b/src/frontends/tensorflow/tests/convert_tricky_models.cpp index e2a48462fed9bc..559e2884654390 100644 --- a/src/frontends/tensorflow/tests/convert_tricky_models.cpp +++ b/src/frontends/tensorflow/tests/convert_tricky_models.cpp @@ -716,3 +716,31 @@ TEST_F(FrontEndConversionWithReferenceTestsF, ControlDependencyNumberOutputs) { model_ref = make_shared(OutputVector{sub}, ParameterVector{input1, input2}); } } + +TEST_F(FrontEndConversionWithReferenceTestsF, TF1IfWithNonExistentOpInBranch) { + // This test aims to check conversion of a model with TF1 If operation that + // contains unsupported operation in one branch + // the conversion must avoid such branch in case proper condition freezing + { + bool cond_value = false; + model = convert_model("tf1_if_with_nonexistent_op/tf1_if_with_nonexistent_op.pb", + nullptr, + {}, + {}, + {}, + {"cond"}, + {&cond_value}); + } + { + auto y = make_shared(f32, Shape{2, 3}); + auto ind = make_shared(i32, Shape{3}); + + auto const_two = make_shared(i32, Shape{}, 2); + auto sub = make_shared(ind, const_two); + + auto convert = make_shared(sub, f32); + auto mul = make_shared(convert, y); + + model_ref = make_shared(OutputVector{mul}, ParameterVector{y, ind}); + } +} diff --git a/src/frontends/tensorflow/tests/test_models/gen_scripts/generate_tf1_if_with_nonexistent_op.py b/src/frontends/tensorflow/tests/test_models/gen_scripts/generate_tf1_if_with_nonexistent_op.py new file mode 100644 index 00000000000000..22b853fab07547 --- /dev/null +++ b/src/frontends/tensorflow/tests/test_models/gen_scripts/generate_tf1_if_with_nonexistent_op.py @@ -0,0 +1,59 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import os +import sys + +import numpy as np +import tensorflow as tf +from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2 + + +# generate a model with TF1 If operation that contains unsupported operation +# in one condition branch +def main(): + def simple_if_function(cond, ind, y): + def then_branch(): + const_one = tf.constant(1, dtype=tf.int32) + add = tf.add(ind, const_one) + output = tf.multiply(tf.cast(add, tf.float32), y) + return output + + def else_branch(): + const_two = tf.constant(2, dtype=tf.int32) + sub = tf.subtract(ind, const_two) + output = tf.multiply(tf.cast(sub, tf.float32), y) + return output + + if_output = tf.cond(cond, then_branch, else_branch) + return if_output + + tf_if_graph = tf.function(simple_if_function) + cond = np.random.randint(0, 2, []).astype(bool) + ind = np.random.randint(1, 10, [3]).astype(np.int32) + y = np.random.randint(-50, 50, [2, 3]).astype(np.float32) + concrete_func = tf_if_graph.get_concrete_function(cond, ind, y) + + # lower_control_flow defines representation of If operation + # in case of lower_control_flow=True it is decomposed into Switch and Merge nodes + frozen_func = convert_variables_to_constants_v2(concrete_func, + lower_control_flow=True) + + graph_def = frozen_func.graph.as_graph_def(add_shapes=True) + tf.io.write_graph(graph_def, os.path.join(sys.argv[1], "tf1_if_with_nonexistent_op"), + "tf1_if_with_nonexistent_op.pb", + False) + + with open(os.path.join(sys.argv[1], "tf1_if_with_nonexistent_op", "tf1_if_with_nonexistent_op.pb"), + mode='rb') as file: + modelContent = file.read() + + modelContent = modelContent.replace(b"AddV2", b"Rrrrr") + + with open(os.path.join(sys.argv[1], "tf1_if_with_nonexistent_op", "tf1_if_with_nonexistent_op.pb"), + mode='wb') as file: + file.write(modelContent) + + +if __name__ == "__main__": + main() diff --git a/src/frontends/tensorflow/tests/tf_utils.cpp b/src/frontends/tensorflow/tests/tf_utils.cpp index 5ce4dea34030e7..09c4fdf18bde04 100644 --- a/src/frontends/tensorflow/tests/tf_utils.cpp +++ b/src/frontends/tensorflow/tests/tf_utils.cpp @@ -20,7 +20,9 @@ shared_ptr convert_model(const string& model_path, const ConversionExtension::Ptr& conv_ext, const vector& input_names, const vector& input_types, - const vector& input_shapes) { + const vector& input_shapes, + const std::vector& input_names_to_freeze, + const std::vector& freeze_values) { FrontEndManager fem; auto front_end = fem.load_by_framework(TF_FE); if (!front_end) { @@ -64,6 +66,15 @@ shared_ptr convert_model(const string& model_path, input_model->override_all_inputs(input_places); } + // freeze some places with concrete values + if (input_names_to_freeze.size() != freeze_values.size()) { + throw "The number of input places to freeze and their values do not match"; + } + for (size_t ind = 0; ind < input_names_to_freeze.size(); ++ind) { + auto place_to_freeze = input_model->get_place_by_tensor_name(input_names_to_freeze[ind]); + input_model->set_tensor_value(place_to_freeze, freeze_values[ind]); + } + auto model = front_end->convert(input_model); if (!model) { throw "Model is not converted"; diff --git a/src/frontends/tensorflow/tests/tf_utils.hpp b/src/frontends/tensorflow/tests/tf_utils.hpp index 17112f81e3aa86..d039a9f9edb007 100644 --- a/src/frontends/tensorflow/tests/tf_utils.hpp +++ b/src/frontends/tensorflow/tests/tf_utils.hpp @@ -22,7 +22,9 @@ std::shared_ptr convert_model(const std::string& model_path, const ov::frontend::ConversionExtension::Ptr& conv_ext = nullptr, const std::vector& input_names = {}, const std::vector& input_types = {}, - const std::vector& input_shapes = {}); + const std::vector& input_shapes = {}, + const std::vector& input_names_to_freeze = {}, + const std::vector& freeze_values = {}); } // namespace tests } // namespace tensorflow diff --git a/src/frontends/tensorflow_common/include/helper_ops/merge.hpp b/src/frontends/tensorflow_common/include/helper_ops/merge.hpp new file mode 100644 index 00000000000000..eb7e611f3e21f0 --- /dev/null +++ b/src/frontends/tensorflow_common/include/helper_ops/merge.hpp @@ -0,0 +1,94 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "helper_ops/switch.hpp" +#include "internal_operation.hpp" +#include "openvino/core/type/element_type.hpp" +#include "tf_utils.hpp" + +namespace ov { +namespace frontend { +namespace tensorflow { + +// Forwards the value of an available tensor from inputs to output +// It has two outputs: +// 1. output that is available by one of the inputs +// 2. value_index - index of available input +class Merge : public InternalOperation { +public: + OPENVINO_OP("Merge", "ov::frontend::tensorflow", InternalOperation); + + Merge(OutputVector inputs, const std::shared_ptr& decoder = std::make_shared()) + : InternalOperation(decoder, inputs, 2, "Merge") { + validate_and_infer_types(); + } + + void validate_and_infer_types() override { + ov::element::Type output_data_type = ov::element::dynamic; + ov::PartialShape output_data_shape = ov::PartialShape::dynamic(); + + auto input_size = get_input_size(); + bool merge_output_shape = true; + for (size_t input_ind = 0; input_ind < input_size; ++input_ind) { + auto input_type = get_input_element_type(input_ind); + if (input_type.is_static()) { + output_data_type = input_type; + } + + // check if it still needs to merge input shapes + // if yes, it tries to merge them + if (merge_output_shape && + !PartialShape::merge_into(output_data_shape, get_input_partial_shape(input_ind))) { + merge_output_shape = false; + // reset output shape to dynamic rank + output_data_shape = ov::PartialShape::dynamic(); + } + } + + set_output_type(0, output_data_type, output_data_shape); + set_output_type(1, ov::element::i32, {}); + } + + bool is_cond_flow_eliminated() const { + const auto this_node = this->shared_from_this(); + if (!cf_marker_exists(this_node)) { + return false; + } + auto cf_marker = get_cf_marker(this_node); + return cf_marker.merge_eliminated_markers.size() > 0; + } + + std::vector get_eliminated_cond_flow_marker() const { + std::vector resulted_indices; + const auto this_node = this->shared_from_this(); + FRONT_END_GENERAL_CHECK( + cf_marker_exists(this_node), + "[TensorFlow Frontend] internal error: Switch node has not set conditional flow marker"); + auto cf_marker = get_cf_marker(this_node); + for (auto eliminated_marker : cf_marker.merge_eliminated_markers) { + resulted_indices.push_back(eliminated_marker.first); + } + return resulted_indices; + } + + std::unordered_set> get_switch_nodes_set_by_cond_index(uint32_t switch_marker) { + const auto this_node = this->shared_from_this(); + FRONT_END_GENERAL_CHECK( + cf_marker_exists(this_node), + "[TensorFlow Frontend] internal error: Switch node has not set conditional flow marker"); + auto cf_marker = get_cf_marker(this_node); + FRONT_END_GENERAL_CHECK( + cf_marker.merge_eliminated_markers.count(switch_marker) > 0, + "[TensorFlow Frontend] internal error: no Switch node with requiested conditional flow marker"); + return cf_marker.merge_eliminated_markers[switch_marker]; + } +}; + +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow_common/include/helper_ops/switch.hpp b/src/frontends/tensorflow_common/include/helper_ops/switch.hpp new file mode 100644 index 00000000000000..c22382815e9695 --- /dev/null +++ b/src/frontends/tensorflow_common/include/helper_ops/switch.hpp @@ -0,0 +1,76 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include "internal_operation.hpp" +#include "openvino/frontend/exception.hpp" +#include "tf_utils.hpp" + +namespace ov { +namespace frontend { +namespace tensorflow { + +// Internal operation for Switch +// Forwards data to the output port determined by predicate +// It has two outputs: +// 1. output_false - forward data to this output in case predicate to be false +// 2. output_true - forward data to this output in case predicate to be true +class Switch : public InternalOperation { +public: + OPENVINO_OP("Switch", "ov::frontend::tensorflow", InternalOperation); + + Switch(const Output& data, + const Output& pred, + uint32_t switch_marker, + const std::shared_ptr& decoder = std::make_shared()) + : InternalOperation(decoder, OutputVector{data, pred}, 2, "Switch"), + m_switch_marker(switch_marker) { + validate_and_infer_types(); + } + + void validate_and_infer_types() override { + auto data_type = get_input_element_type(0); + auto data_shape = get_input_partial_shape(0); + + set_output_type(0, data_type, data_shape); + set_output_type(1, data_type, data_shape); + } + + bool is_cond_flow_marker_set() const { + const auto this_node = this->shared_from_this(); + if (!cf_marker_exists(this_node)) { + return false; + } + + auto cf_marker = get_cf_marker(this_node); + return cf_marker.new_markers.size() == 1; + } + + uint32_t get_cond_flow_marker() const { + const auto this_node = this->shared_from_this(); + FRONT_END_GENERAL_CHECK( + cf_marker_exists(this_node), + "[TensorFlow Frontend] internal error: Switch node has not set conditional flow marker"); + auto cf_marker = get_cf_marker(this_node); + FRONT_END_GENERAL_CHECK( + cf_marker.new_markers.size() == 1, + "[TensorFlow Frontend] internal error: Switch node has incorrect value of conditional flow marker"); + return cf_marker.new_markers.begin()->first; + } + + uint32_t get_switch_marker() const { + return m_switch_marker; + } + +private: + uint32_t m_switch_marker; +}; + +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/inference/src/dev/icompiled_model_wrapper.cpp b/src/inference/src/dev/icompiled_model_wrapper.cpp index fd6a994d6c89b3..f8a7f0fa0014c5 100644 --- a/src/inference/src/dev/icompiled_model_wrapper.cpp +++ b/src/inference/src/dev/icompiled_model_wrapper.cpp @@ -44,6 +44,24 @@ ov::Any InferenceEngine::ICompiledModelWrapper::get_property(const std::string& if (ov::loaded_from_cache == name) { return m_model->isLoadedFromCache(); } + + auto get_supported_properties = [&]() { + auto ro_properties = m_model->GetMetric(METRIC_KEY(SUPPORTED_METRICS)).as>(); + auto rw_properties = m_model->GetMetric(METRIC_KEY(SUPPORTED_CONFIG_KEYS)).as>(); + std::vector supported_properties; + for (auto&& ro_property : ro_properties) { + if (ro_property != METRIC_KEY(SUPPORTED_METRICS) && ro_property != METRIC_KEY(SUPPORTED_CONFIG_KEYS)) { + supported_properties.emplace_back(ro_property, ov::PropertyMutability::RO); + } + } + for (auto&& rw_property : rw_properties) { + supported_properties.emplace_back(rw_property, ov::PropertyMutability::RW); + } + supported_properties.emplace_back(ov::supported_properties.name(), ov::PropertyMutability::RO); + supported_properties.emplace_back(ov::loaded_from_cache.name(), ov::PropertyMutability::RO); + return supported_properties; + }; + if (ov::supported_properties == name) { try { auto supported_properties = m_model->GetMetric(name).as>(); @@ -55,25 +73,16 @@ ov::Any InferenceEngine::ICompiledModelWrapper::get_property(const std::string& }), supported_properties.end()); return supported_properties; + } catch (ov::Exception&) { + return get_supported_properties(); } catch (InferenceEngine::Exception&) { - auto ro_properties = m_model->GetMetric(METRIC_KEY(SUPPORTED_METRICS)).as>(); - auto rw_properties = m_model->GetMetric(METRIC_KEY(SUPPORTED_CONFIG_KEYS)).as>(); - std::vector supported_properties; - for (auto&& ro_property : ro_properties) { - if (ro_property != METRIC_KEY(SUPPORTED_METRICS) && ro_property != METRIC_KEY(SUPPORTED_CONFIG_KEYS)) { - supported_properties.emplace_back(ro_property, ov::PropertyMutability::RO); - } - } - for (auto&& rw_property : rw_properties) { - supported_properties.emplace_back(rw_property, ov::PropertyMutability::RW); - } - supported_properties.emplace_back(ov::supported_properties.name(), ov::PropertyMutability::RO); - supported_properties.emplace_back(ov::loaded_from_cache.name(), ov::PropertyMutability::RO); - return supported_properties; + return get_supported_properties(); } } try { return m_model->GetMetric(name); + } catch (ov::Exception&) { + return m_model->GetConfig(name); } catch (InferenceEngine::Exception&) { return m_model->GetConfig(name); } diff --git a/src/plugins/intel_cpu/src/nodes/common/permute_kernel.cpp b/src/plugins/intel_cpu/src/nodes/common/permute_kernel.cpp index 641671a37e042e..59b3da4e45cebf 100644 --- a/src/plugins/intel_cpu/src/nodes/common/permute_kernel.cpp +++ b/src/plugins/intel_cpu/src/nodes/common/permute_kernel.cpp @@ -13,6 +13,8 @@ #include "cpu/x64/jit_generator.hpp" #include +#include "nodes/executors/transpose.hpp" +#include "nodes/executors/common/ref_transpose.hpp" using namespace InferenceEngine; using namespace dnnl; @@ -146,121 +148,7 @@ struct jit_uni_permute_kernel_f32 : public jit_uni_permute_kernel, public jit_ge #endif // OPENVINO_ARCH_X86_64 PermuteKernel::PermuteKernel(const PermuteParams& params) : params(params) { - prepareParams(); -} - -void PermuteKernel::prepareParams() { - SizeVector src_block_strides(params.src_block_dims.size(), 1); - SizeVector dst_block_strides(params.dst_block_dims.size(), 1); - for (int i = params.src_block_dims.size() - 2; i >= 0; i--) - src_block_strides[i] = src_block_strides[i + 1] * params.src_block_dims[i + 1]; - for (int i = params.dst_block_dims.size() - 2; i >= 0; i--) - dst_block_strides[i] = dst_block_strides[i + 1] * params.dst_block_dims[i + 1]; - - SizeVector new_dst_block_strides = dst_block_strides; - SizeVector new_dst_block_order = params.dst_block_order; - SizeVector new_dst_block_dims = params.dst_block_dims; - SizeVector new_src_block_strides(dst_block_strides.size()); - SizeVector mask(dst_block_strides.size()); - - SizeVector tmp_order; - for (size_t i = 0; i < params.dst_block_order.size(); i++) { - tmp_order.push_back(params.order[params.dst_block_order[i]]); - } - - for (int i = tmp_order.size() - 1; i >= 0; i--) { - int pos = std::distance(std::find( - params.src_block_order.rbegin(), params.src_block_order.rend(), tmp_order[i]), params.src_block_order.rend() - 1); - if (pos != -1) { - new_src_block_strides[i] = src_block_strides[pos]; - params.src_block_order.erase(params.src_block_order.begin() + pos); - src_block_strides.erase(src_block_strides.begin() + pos); - mask[i] = 0; - } else { - new_src_block_strides[i] = new_src_block_strides[tmp_order.size() - 1] * params.dst_block_dims[tmp_order.size() - 1]; - mask[i] = 1; - mask[tmp_order.size() - 1] = 1; - } - } - if (!params.src_block_order.empty()) { - int pos = std::distance(tmp_order.begin(), std::find(tmp_order.begin(), tmp_order.end(), params.src_block_order[0])); - new_src_block_strides.insert(new_src_block_strides.begin() + pos, - src_block_strides[0]); - new_dst_block_strides.insert(new_dst_block_strides.begin() + pos, - new_dst_block_strides[pos] * params.src_block_dims[params.src_block_dims.size() - 1]); - new_dst_block_order.insert(new_dst_block_order.begin() + pos, - new_dst_block_order[pos]); - new_dst_block_dims.insert(new_dst_block_dims.begin() + pos + 1, - params.src_block_dims[params.src_block_dims.size() - 1]); - new_dst_block_dims[pos] = div_up(new_dst_block_dims[pos], new_dst_block_dims[pos + 1]); - mask.insert(mask.begin() + pos + 1, 1); - mask[pos] = 1; - } - - SizeVector sorted_src_strides; - SizeVector sorted_dst_strides; - SizeVector sorted_order; - SizeVector sorted_dst_dims; - - // support dynamic batch - int batch_ord = std::distance(params.order.begin(), std::find(params.order.begin(), params.order.end(), 0)); - int batch_count = 0; - int batch_pos = 0; - for (size_t i = 0; i < new_dst_block_order.size(); i++) { - if (static_cast(new_dst_block_order[i]) == batch_ord) { - batch_count++; - batch_pos = i; - } - } - if (batch_count == 1) { - sorted_src_strides.push_back(new_src_block_strides[batch_pos]); - sorted_dst_strides.push_back(new_dst_block_strides[batch_pos]); - sorted_order.push_back(new_dst_block_order[batch_pos]); - sorted_dst_dims.push_back(new_dst_block_dims[batch_pos]); - jcp.supported_dynamic_batch = true; - } - - int n2 = 0; - for (size_t i = 0; i < mask.size(); i++) { - if (mask[i] == 0) { - n2++; - if (batch_count == 1 && static_cast(new_dst_block_order[i]) == batch_ord) { - continue; - } - sorted_src_strides.push_back(new_src_block_strides[i]); - sorted_dst_strides.push_back(new_dst_block_strides[i]); - sorted_order.push_back(new_dst_block_order[i]); - sorted_dst_dims.push_back(new_dst_block_dims[i]); - } - } - for (size_t i = 0; i < mask.size(); i++) { - if (mask[i] == 1) { - sorted_src_strides.push_back(new_src_block_strides[i]); - sorted_dst_strides.push_back(new_dst_block_strides[i]); - sorted_order.push_back(new_dst_block_order[i]); - sorted_dst_dims.push_back(new_dst_block_dims[i]); - } - } - - int max_threads = parallel_get_max_threads(); - const int n_max = 3; // max count dims for parallel - int n = 0; - int work_amount = sorted_dst_dims[0]; - for (size_t i = 1; i < sorted_dst_dims.size() && n < n_max; i++) { - n++; - if (work_amount >= 4 * max_threads) { // 4 * max_threads is a specially selected value for best performance - break; - } - work_amount *= sorted_dst_dims[i]; - } - - jcp.src_strides = sorted_src_strides; - jcp.dst_strides = sorted_dst_strides; - jcp.dst_block_dims = sorted_dst_dims; - jcp.n = std::min(n, n2); - jcp.ndims = sorted_order.size(); - jcp.data_size = params.data_size; - + jcp = TransposeExecutor::prepareParams(params); #if defined(OPENVINO_ARCH_X86_64) if (mayiuse(cpu::x64::avx512_core)) { permute_kernel.reset(new jit_uni_permute_kernel_f32(jcp)); @@ -281,7 +169,7 @@ void PermuteKernel::execute(const uint8_t* src_data, uint8_t* dst_data, const in return; } - referenceExecute(src_data, dst_data, mb); + RefTransposeExecutor::referenceExecute(src_data, dst_data, jcp, mb); } void PermuteKernel::execute(const uint8_t* src_data, uint8_t* dst_data) { @@ -291,7 +179,7 @@ void PermuteKernel::execute(const uint8_t* src_data, uint8_t* dst_data) { return; } - referenceExecute(src_data, dst_data, dst_dims[0]); + RefTransposeExecutor::referenceExecute(src_data, dst_data, jcp, dst_dims[0]); } void PermuteKernel::optimizedExecute(const uint8_t* src_data, uint8_t* dst_data, const int mb) { @@ -343,60 +231,6 @@ void PermuteKernel::optimizedExecute(const uint8_t* src_data, uint8_t* dst_data, return; } -static inline size_t parallel_init(size_t start, size_t nDims, const SizeVector& dims, SizeVector& indexes) { - for (int j = nDims - 1; j >= 0; j--) { - indexes[j] = start % dims[j]; - start = start / dims[j]; - } - return start; -} - -static inline void parallel_step(size_t nDims, const SizeVector& dims, SizeVector& indexes) { - for (int j = nDims - 1; j >= 0; --j) { - ++indexes[j]; - if (indexes[j] < dims[j]) - break; - else - indexes[j] = 0; - } -} - -void PermuteKernel::referenceExecute(const uint8_t* src_data, uint8_t* dst_data, const int mb) { - SizeVector dst_dims = jcp.dst_block_dims; - const SizeVector dst_strides = jcp.dst_strides; - const SizeVector src_strides = jcp.src_strides; - const size_t data_size = jcp.data_size; - const size_t ndims = dst_dims.size(); - - if (static_cast(dst_dims[0]) != mb) - dst_dims[0] = mb; - - size_t work_amount = std::accumulate(dst_dims.begin(), dst_dims.end(), 1, std::multiplies()); - - auto get_idx = [ndims, data_size](const SizeVector& indexes, const SizeVector& strides) { - size_t idx = 0; - for (size_t i = 0; i < ndims; ++i) - idx += indexes[i] * strides[i]; - return idx * data_size; - }; - - parallel_nt(0, [&](const int ithr, const int nthr) { - size_t start = 0, end = 0; - SizeVector indexes(ndims, 0); - splitter(work_amount, nthr, ithr, start, end); - - parallel_init(start, ndims, dst_dims, indexes); - - for (size_t iwork = start; iwork < end; ++iwork) { - const size_t dst_idx = get_idx(indexes, dst_strides); - const size_t src_idx = get_idx(indexes, src_strides); - cpu_memcpy(&dst_data[dst_idx], &src_data[src_idx], data_size); - - parallel_step(ndims, dst_dims, indexes); - } - }); -} - size_t PermuteParams::hash() const { using namespace dnnl::impl; using namespace dnnl::impl::primitive_hashing; diff --git a/src/plugins/intel_cpu/src/nodes/common/permute_kernel.h b/src/plugins/intel_cpu/src/nodes/common/permute_kernel.h index 3a6731674df4ff..52e136338b5b7f 100644 --- a/src/plugins/intel_cpu/src/nodes/common/permute_kernel.h +++ b/src/plugins/intel_cpu/src/nodes/common/permute_kernel.h @@ -66,10 +66,7 @@ class PermuteKernel { } private: - void prepareParams(); - void optimizedExecute(const uint8_t* src_data, uint8_t* dst_data, const int mb); - void referenceExecute(const uint8_t* src_data, uint8_t* dst_data, const int mb); jit_permute_config_params jcp = {}; std::shared_ptr permute_kernel; diff --git a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_interpolate.cpp b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_interpolate.cpp index 5b6beb0ec3fa59..b5689105b06b6f 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_interpolate.cpp +++ b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_interpolate.cpp @@ -50,12 +50,8 @@ bool ov::intel_cpu::ACLInterpolateExecutor::init(const InterpolateAttrs &interpo auto dstDims = dstDescs[0]->getShape().getDims(); if (srcDescs[0]->hasLayoutType(LayoutType::nspc) && dstDescs[0]->hasLayoutType(LayoutType::nspc)) { - auto mover = [](VectorDims &_shape) { - std::swap(_shape[1], _shape[2]); - std::swap(_shape[2], _shape[3]); - }; - mover(srcDims); - mover(dstDims); + changeLayoutToNhwc(srcDims); + changeLayoutToNhwc(dstDims); } auto srcTensorInfo = arm_compute::TensorInfo(shapeCast(srcDims), 1, diff --git a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_transpose.cpp b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_transpose.cpp new file mode 100644 index 00000000000000..4031e174b65481 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_transpose.cpp @@ -0,0 +1,67 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "acl_transpose.hpp" +#include "acl_utils.hpp" + +bool ov::intel_cpu::ACLTransposeExecutor::init(const ov::intel_cpu::TransposeParams &transposeParams, + const std::vector &srcDescs, + const std::vector &dstDescs, + const dnnl::primitive_attr &attr) { + auto inputOrder = transposeParams.permuteParams.order; + if (inputOrder.empty()) { + inputOrder.resize(srcDescs[0]->getShape().getRank()); + std::iota(inputOrder.begin(), inputOrder.end(), 0); + } + + std::vector vec; + auto srcDims = srcDescs[0]->getShape().getStaticDims(); + auto dstDims = dstDescs[0]->getShape().getStaticDims(); + if (srcDescs[0]->hasLayoutType(LayoutType::nspc)) { + changeLayoutToNhwc(srcDims); + changeLayoutToNhwc(dstDims); + for (int i = inputOrder.size() - 1; i >= 0 ; --i) { + auto it = find(srcDims.rbegin(), srcDims.rend(), dstDims[i]); + int index = it - srcDims.rbegin(); + vec.push_back(index); + } + } else { + for (unsigned int i = 0; i < inputOrder.size(); ++i) { + vec.push_back(axisCast(inputOrder[i], inputOrder.size())); + } + std::reverse(vec.begin(), vec.end()); + } + arm_compute::PermutationVector order; + for (unsigned int i = 0; i < inputOrder.size(); ++i) { + order.set(i, vec[i]); + } + auto srcTensorInfo = arm_compute::TensorInfo(shapeCast(srcDims), 1, + precisionToAclDataType(srcDescs[0]->getPrecision()), + getAclDataLayoutByMemoryDesc(srcDescs[0])); + auto dstTensorInfo = arm_compute::TensorInfo(shapeCast(dstDims), 1, + precisionToAclDataType(dstDescs[0]->getPrecision()), + getAclDataLayoutByMemoryDesc(dstDescs[0])); + arm_compute::Status status = arm_compute::NEPermute::validate(&srcTensorInfo, &dstTensorInfo, order); + if (!status) { + DEBUG_LOG("NEPermute validation failed: ", status.error_description()); + return false; + } + srcTensor.allocator()->init(srcTensorInfo); + dstTensor.allocator()->init(dstTensorInfo); + + acl_permute = std::make_unique(); + acl_permute->configure(&srcTensor, &dstTensor, order); + return true; +} + +void ov::intel_cpu::ACLTransposeExecutor::exec(const std::vector &src, const std::vector &dst, + const int MB) { + srcTensor.allocator()->import_memory(src[0]->getData()); + dstTensor.allocator()->import_memory(dst[0]->getData()); + + acl_permute->run(); + + srcTensor.allocator()->free(); + dstTensor.allocator()->free(); +} diff --git a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_transpose.hpp b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_transpose.hpp new file mode 100644 index 00000000000000..a2a67dd3decf82 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_transpose.hpp @@ -0,0 +1,57 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "nodes/executors/transpose.hpp" +#include "utils/debug_capabilities.h" + +namespace ov { +namespace intel_cpu { + +class ACLTransposeExecutor : public TransposeExecutor { +public: + using TransposeExecutor::TransposeExecutor; + + bool init(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs, + const dnnl::primitive_attr &attr) override; + void exec(const std::vector& src, const std::vector& dst, const int MB) override; + impl_desc_type getImplType() const override { return implType; } +private: + static const impl_desc_type implType = impl_desc_type::acl; + arm_compute::Tensor srcTensor, dstTensor; + std::unique_ptr acl_permute; +}; + +class ACLTransposeExecutorBuilder : public TransposeExecutorBuilder { +public: + bool isSupported(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs) const override { + if (!(srcDescs[0]->hasLayoutType(LayoutType::ncsp) && + dstDescs[0]->hasLayoutType(LayoutType::ncsp)) && + !(srcDescs[0]->hasLayoutType(LayoutType::nspc) && + dstDescs[0]->hasLayoutType(LayoutType::nspc))) { + DEBUG_LOG("NEPermute does not support precisions:", + " src: ", srcDescs[0]->serializeFormat(), + " dst: ", dstDescs[0]->serializeFormat()); + return false; + } + if (srcDescs[0]->getShape().getRank() > 4) { + DEBUG_LOG("NEPermute supports up to 4D input tensor. Passed tensor rank: ", + srcDescs[0]->getShape().getRank()); + return false; + } + return true; + } + + TransposeExecutorPtr makeExecutor(const ExecutorContext::CPtr context) const override { + return std::make_shared(context); + } +}; + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_utils.hpp b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_utils.hpp index 9a4ccfcdd803bc..42b35970993b2b 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_utils.hpp +++ b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_utils.hpp @@ -10,6 +10,17 @@ namespace ov { namespace intel_cpu { +/** +* @brief ACL handles NHWC specifically, it thinks it is NCHW, so we need to change layout manually: +* NCHW (0, 1, 2, 3) -> NHWC (0, 2, 3, 1) +* @param shape shape to convert +* @return none +*/ +inline void changeLayoutToNhwc(VectorDims& shape) { + std::swap(shape[1], shape[2]); + std::swap(shape[2], shape[3]); +} + /** * @brief Return ComputeLibrary TensorShape with reverted layout schema used in ACL * @param dims vector of dimensions to convert diff --git a/src/plugins/intel_cpu/src/nodes/executors/common/ref_opt_transpose.cpp b/src/plugins/intel_cpu/src/nodes/executors/common/ref_opt_transpose.cpp new file mode 100644 index 00000000000000..71997a495d50e0 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/common/ref_opt_transpose.cpp @@ -0,0 +1,138 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "ref_opt_transpose.hpp" +#include "ie_parallel.hpp" + +namespace ov { +namespace intel_cpu { +namespace { + +struct TransposeContext { + MemoryCPtr srcMemPtr; + MemoryPtr dstMemPtr; + int MB; +}; + +template +void transpose_to_0312(const int MB, const MemoryCPtr& srcMemPtr, MemoryPtr& dstMemPtr) { + const auto src_data = reinterpret_cast(srcMemPtr->getData()); + auto dst_data = reinterpret_cast(dstMemPtr->getData()); + + const int DIM1 = srcMemPtr->getStaticDims()[1]; + const int DIM2 = srcMemPtr->getStaticDims()[2]; + const int DIM3 = srcMemPtr->getStaticDims()[3]; + + parallel_for3d(MB, DIM1, DIM2, [&](const int n, const int dim1, const int dim2) { + for (int dim3 = 0; dim3 < DIM3; ++dim3) { + const int src_off = n * DIM1 * DIM2 * DIM3 + + dim1 * DIM2 * DIM3 + + dim2 * DIM3 + + dim3; + const int dst_off = n * DIM1 * DIM2 * DIM3 + + dim3 * DIM1 * DIM2 + + dim1 * DIM2 + + dim2; + + dst_data[dst_off] = src_data[src_off]; + } + }); +} + +template +void transpose_to_04123(const int MB, const MemoryCPtr& srcMemPtr, MemoryPtr& dstMemPtr) { + const auto src_data = reinterpret_cast(srcMemPtr->getData()); + auto dst_data = reinterpret_cast(dstMemPtr->getData()); + + const int DIM1 = srcMemPtr->getStaticDims()[1]; + const int DIM2 = srcMemPtr->getStaticDims()[2]; + const int DIM3 = srcMemPtr->getStaticDims()[3]; + const int DIM4 = srcMemPtr->getStaticDims()[4]; + + parallel_for4d(MB, DIM1, DIM2, DIM3, [&](const int n, const int dim1, const int dim2, const int dim3) { + for (int dim4 = 0; dim4 < DIM4; ++dim4) { + const int src_off = n * DIM1 * DIM2 * DIM3 * DIM4 + + dim1 * DIM2 * DIM3 * DIM4 + + dim2 * DIM3 * DIM4 + + dim3 * DIM4 + + dim4; + const int dst_off = n * DIM1 * DIM2 * DIM3 * DIM4 + + dim4 * DIM1 * DIM2 * DIM3 + + dim1 * DIM2 * DIM3 + + dim2 * DIM3 + + dim3; + + dst_data[dst_off] = src_data[src_off]; + } + }); +} + +template +void transpose_to_051234(const int MB, const MemoryCPtr& srcMemPtr, MemoryPtr& dstMemPtr) { + const auto src_data = reinterpret_cast(srcMemPtr->getData()); + auto dst_data = reinterpret_cast(dstMemPtr->getData()); + + const int DIM1 = srcMemPtr->getStaticDims()[1]; + const int DIM2 = srcMemPtr->getStaticDims()[2]; + const int DIM3 = srcMemPtr->getStaticDims()[3]; + const int DIM4 = srcMemPtr->getStaticDims()[4]; + const int DIM5 = srcMemPtr->getStaticDims()[5]; + + parallel_for5d(MB, DIM1, DIM2, DIM3, DIM4, [&](const int n, const int dim1, const int dim2, const int dim3, const int dim4) { + for (int dim5 = 0; dim5 < DIM5; ++dim5) { + const int src_off = n * DIM1 * DIM2 * DIM3 * DIM4 * DIM5 + + dim1 * DIM2 * DIM3 * DIM4 * DIM5 + + dim2 * DIM3 * DIM4 * DIM5 + + dim3 * DIM4 * DIM5 + + dim4 * DIM5 + + dim5; + const int dst_off = n * DIM5 * DIM1 * DIM2 * DIM3 * DIM4 + + dim5 * DIM1 * DIM2 * DIM3 * DIM4 + + dim1 * DIM2 * DIM3 * DIM4 + + dim2 * DIM3 * DIM4 + + dim3 * DIM4 + + dim4; + + dst_data[dst_off] = src_data[src_off]; + } + }); +} + +template +struct TransposeOptimizedEmitter { + void operator()(TransposeContext& ctx) { + switch (ctx.srcMemPtr->getStaticDims().size()) { + case 4: + transpose_to_0312(ctx.MB, ctx.srcMemPtr, ctx.dstMemPtr); + break; + case 5: + transpose_to_04123(ctx.MB, ctx.srcMemPtr, ctx.dstMemPtr); + break; + case 6: + transpose_to_051234(ctx.MB, ctx.srcMemPtr, ctx.dstMemPtr); + break; + default: + IE_THROW() << "Transpose supports optimized execution with only 4D, 5D and 6D shapes"; + } + } +}; +} // namespace +void RefOptimizedTransposeExecutor::exec(const std::vector& src, const std::vector& dst, const int MB) { + const size_t dataSize = src[0]->getDesc().getPrecision().size(); + TransposeContext ctx = {src[0], dst[0], MB}; + OV_SWITCH(intel_cpu, TransposeOptimizedEmitter, ctx, dataSize, + OV_CASE(1u, InferenceEngine::PrecisionTrait::value_type), + OV_CASE(2u, InferenceEngine::PrecisionTrait::value_type), + OV_CASE(4u, InferenceEngine::PrecisionTrait::value_type)); +} + +bool RefOptimizedTransposeExecutor::init(const TransposeParams &transposeParams, + const std::vector &srcDescs, + const std::vector &dstDescs, + const dnnl::primitive_attr &attr) { + return true; +} + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/common/ref_opt_transpose.hpp b/src/plugins/intel_cpu/src/nodes/executors/common/ref_opt_transpose.hpp new file mode 100644 index 00000000000000..f79bbd86cd231d --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/common/ref_opt_transpose.hpp @@ -0,0 +1,50 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "../transpose.hpp" +#include "utils/debug_capabilities.h" + +namespace ov { +namespace intel_cpu { +class RefOptimizedTransposeExecutor : public TransposeExecutor { +public: + using TransposeExecutor::TransposeExecutor; + + bool init(const TransposeParams &transposeParams, + const std::vector &srcDescs, + const std::vector &dstDescs, + const dnnl::primitive_attr &attr) override; + void exec(const std::vector &src, const std::vector &dst, const int MB) override; + impl_desc_type getImplType() const override { return implType; } +private: + static const impl_desc_type implType = impl_desc_type::ref; +}; + +class RefOptimizedTransposeExecutorBuilder : public TransposeExecutorBuilder { +public: + bool isSupported(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs) const override { + static const std::vector> optimizedOrders = { + std::vector{0, 3, 1, 2}, + std::vector{0, 4, 1, 2, 3}, + std::vector{0, 5, 1, 2, 3, 4}, + }; + if (srcDescs[0]->hasLayoutType(LayoutType::ncsp) && + std::find(optimizedOrders.begin(), optimizedOrders.end(), transposeParams.permuteParams.order) != optimizedOrders.end()) { + return true; + } + DEBUG_LOG("RefOptimizedTransposeExecutor is not supported, because passed order is not optimized"); + return false; + } + + TransposeExecutorPtr makeExecutor(const ExecutorContext::CPtr context) const override { + return std::make_shared(context); + } +}; + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/common/ref_transpose.cpp b/src/plugins/intel_cpu/src/nodes/executors/common/ref_transpose.cpp new file mode 100644 index 00000000000000..885dd1200132cf --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/common/ref_transpose.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "ref_transpose.hpp" +#include "ie_parallel.hpp" +#include "nodes/common/cpu_memcpy.h" + +using namespace InferenceEngine; + +namespace ov { +namespace intel_cpu { + +static inline size_t parallel_init(size_t start, size_t nDims, const SizeVector& dims, SizeVector& indexes) { + for (int j = nDims - 1; j >= 0; j--) { + indexes[j] = start % dims[j]; + start = start / dims[j]; + } + return start; +} + +static inline void parallel_step(size_t nDims, const SizeVector& dims, SizeVector& indexes) { + for (int j = nDims - 1; j >= 0; --j) { + ++indexes[j]; + if (indexes[j] < dims[j]) + break; + else + indexes[j] = 0; + } +} + +void RefTransposeExecutor::referenceExecute(const uint8_t* src_data, uint8_t* dst_data, jit_permute_config_params jcp, const int mb) { + SizeVector dst_dims = jcp.dst_block_dims; + const SizeVector dst_strides = jcp.dst_strides; + const SizeVector src_strides = jcp.src_strides; + const size_t data_size = jcp.data_size; + const size_t ndims = dst_dims.size(); + + if (static_cast(dst_dims[0]) != mb) + dst_dims[0] = mb; + + size_t work_amount = std::accumulate(dst_dims.begin(), dst_dims.end(), 1, std::multiplies()); + + auto get_idx = [ndims, data_size](const SizeVector& indexes, const SizeVector& strides) { + size_t idx = 0; + for (size_t i = 0; i < ndims; ++i) + idx += indexes[i] * strides[i]; + return idx * data_size; + }; + + parallel_nt(0, [&](const int ithr, const int nthr) { + size_t start = 0, end = 0; + SizeVector indexes(ndims, 0); + splitter(work_amount, nthr, ithr, start, end); + + parallel_init(start, ndims, dst_dims, indexes); + + for (size_t iwork = start; iwork < end; ++iwork) { + const size_t dst_idx = get_idx(indexes, dst_strides); + const size_t src_idx = get_idx(indexes, src_strides); + cpu_memcpy(&dst_data[dst_idx], &src_data[src_idx], data_size); + + parallel_step(ndims, dst_dims, indexes); + } + }); +} + +void RefTransposeExecutor::exec(const std::vector& src, const std::vector& dst, const int MB) { + const uint8_t* src_data = reinterpret_cast(src[0]->getData()); + uint8_t* dst_data = reinterpret_cast(dst[0]->getData()); + referenceExecute(src_data, dst_data, jcp, MB); +} + +bool RefTransposeExecutor::init(const TransposeParams &transposeParams, + const std::vector &srcDescs, + const std::vector &dstDescs, + const dnnl::primitive_attr &attr) { + jcp = TransposeExecutor::prepareParams(transposeParams.permuteParams); + return true; +} + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/common/ref_transpose.hpp b/src/plugins/intel_cpu/src/nodes/executors/common/ref_transpose.hpp new file mode 100644 index 00000000000000..23195dcbd72826 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/common/ref_transpose.hpp @@ -0,0 +1,40 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "../transpose.hpp" + +namespace ov { +namespace intel_cpu { +class RefTransposeExecutor : public TransposeExecutor { +public: + using TransposeExecutor::TransposeExecutor; + static void referenceExecute(const uint8_t* src_data, uint8_t* dst_data, jit_permute_config_params jcp, const int mb); + bool init(const TransposeParams &transposeParams, + const std::vector &srcDescs, + const std::vector &dstDescs, + const dnnl::primitive_attr &attr) override; + void exec(const std::vector &src, const std::vector &dst, const int MB) override; + impl_desc_type getImplType() const override { return implType; } +private: + static const impl_desc_type implType = impl_desc_type::ref; + jit_permute_config_params jcp; +}; + +class RefTransposeExecutorBuilder : public TransposeExecutorBuilder { +public: + bool isSupported(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs) const override { + return true; + } + + TransposeExecutorPtr makeExecutor(const ExecutorContext::CPtr context) const override { + return std::make_shared(context); + } +}; + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/transpose.cpp b/src/plugins/intel_cpu/src/nodes/executors/transpose.cpp new file mode 100644 index 00000000000000..d81badd7d4bd4d --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/transpose.cpp @@ -0,0 +1,134 @@ +// Copyright (C) 2018-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include "transpose.hpp" + +namespace ov { +namespace intel_cpu { + +using namespace InferenceEngine; + +TransposeExecutor::TransposeExecutor(const ExecutorContext::CPtr context) : context(context) {} + +jit_permute_config_params TransposeExecutor::prepareParams(const PermuteParams& params) { + jit_permute_config_params jcp = {}; + SizeVector src_block_order = params.src_block_order; + SizeVector src_block_strides(params.src_block_dims.size(), 1); + SizeVector dst_block_strides(params.dst_block_dims.size(), 1); + for (int i = params.src_block_dims.size() - 2; i >= 0; i--) + src_block_strides[i] = src_block_strides[i + 1] * params.src_block_dims[i + 1]; + for (int i = params.dst_block_dims.size() - 2; i >= 0; i--) + dst_block_strides[i] = dst_block_strides[i + 1] * params.dst_block_dims[i + 1]; + + SizeVector new_dst_block_strides = dst_block_strides; + SizeVector new_dst_block_order = params.dst_block_order; + SizeVector new_dst_block_dims = params.dst_block_dims; + SizeVector new_src_block_strides(dst_block_strides.size()); + SizeVector mask(dst_block_strides.size()); + + SizeVector tmp_order; + for (size_t i = 0; i < params.dst_block_order.size(); i++) { + tmp_order.push_back(params.order[params.dst_block_order[i]]); + } + + for (int i = tmp_order.size() - 1; i >= 0; i--) { + int pos = std::distance(std::find( + src_block_order.rbegin(), src_block_order.rend(), tmp_order[i]), src_block_order.rend() - 1); + if (pos != -1) { + new_src_block_strides[i] = src_block_strides[pos]; + src_block_order.erase(src_block_order.begin() + pos); + src_block_strides.erase(src_block_strides.begin() + pos); + mask[i] = 0; + } else { + new_src_block_strides[i] = new_src_block_strides[tmp_order.size() - 1] * params.dst_block_dims[tmp_order.size() - 1]; + mask[i] = 1; + mask[tmp_order.size() - 1] = 1; + } + } + if (!src_block_order.empty()) { + int pos = std::distance(tmp_order.begin(), std::find(tmp_order.begin(), tmp_order.end(), src_block_order[0])); + new_src_block_strides.insert(new_src_block_strides.begin() + pos, + src_block_strides[0]); + new_dst_block_strides.insert(new_dst_block_strides.begin() + pos, + new_dst_block_strides[pos] * params.src_block_dims[params.src_block_dims.size() - 1]); + new_dst_block_order.insert(new_dst_block_order.begin() + pos, + new_dst_block_order[pos]); + new_dst_block_dims.insert(new_dst_block_dims.begin() + pos + 1, + params.src_block_dims[params.src_block_dims.size() - 1]); + new_dst_block_dims[pos] = div_up(new_dst_block_dims[pos], new_dst_block_dims[pos + 1]); + mask.insert(mask.begin() + pos + 1, 1); + mask[pos] = 1; + } + + SizeVector sorted_src_strides; + SizeVector sorted_dst_strides; + SizeVector sorted_order; + SizeVector sorted_dst_dims; + + // support dynamic batch + int batch_ord = std::distance(params.order.begin(), std::find(params.order.begin(), params.order.end(), 0)); + int batch_count = 0; + int batch_pos = 0; + for (size_t i = 0; i < new_dst_block_order.size(); i++) { + if (static_cast(new_dst_block_order[i]) == batch_ord) { + batch_count++; + batch_pos = i; + } + } + if (batch_count == 1) { + sorted_src_strides.push_back(new_src_block_strides[batch_pos]); + sorted_dst_strides.push_back(new_dst_block_strides[batch_pos]); + sorted_order.push_back(new_dst_block_order[batch_pos]); + sorted_dst_dims.push_back(new_dst_block_dims[batch_pos]); + jcp.supported_dynamic_batch = true; + } + + int n2 = 0; + for (size_t i = 0; i < mask.size(); i++) { + if (mask[i] == 0) { + n2++; + if (batch_count == 1 && static_cast(new_dst_block_order[i]) == batch_ord) { + continue; + } + sorted_src_strides.push_back(new_src_block_strides[i]); + sorted_dst_strides.push_back(new_dst_block_strides[i]); + sorted_order.push_back(new_dst_block_order[i]); + sorted_dst_dims.push_back(new_dst_block_dims[i]); + } + } + for (size_t i = 0; i < mask.size(); i++) { + if (mask[i] == 1) { + sorted_src_strides.push_back(new_src_block_strides[i]); + sorted_dst_strides.push_back(new_dst_block_strides[i]); + sorted_order.push_back(new_dst_block_order[i]); + sorted_dst_dims.push_back(new_dst_block_dims[i]); + } + } + + int max_threads = parallel_get_max_threads(); + const int n_max = 3; // max count dims for parallel + int n = 0; + int work_amount = sorted_dst_dims[0]; + for (size_t i = 1; i < sorted_dst_dims.size() && n < n_max; i++) { + n++; + if (work_amount >= 4 * max_threads) { // 4 * max_threads is a specially selected value for best performance + break; + } + work_amount *= sorted_dst_dims[i]; + } + + jcp.src_strides = sorted_src_strides; + jcp.dst_strides = sorted_dst_strides; + jcp.dst_block_dims = sorted_dst_dims; + jcp.n = std::min(n, n2); + jcp.ndims = sorted_order.size(); + jcp.data_size = params.data_size; + + return jcp; +} + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/transpose.hpp b/src/plugins/intel_cpu/src/nodes/executors/transpose.hpp new file mode 100644 index 00000000000000..0039719a785eeb --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/transpose.hpp @@ -0,0 +1,50 @@ +// Copyright (C) 2018-2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "cpu_memory.h" +#include "onednn/iml_type_mapper.h" +#include "executor.hpp" +#include "nodes/common/permute_kernel.h" + +namespace ov { +namespace intel_cpu { + +struct TransposeParams { + PermuteParams permuteParams; +}; + +class TransposeExecutor { +public: + static jit_permute_config_params prepareParams(const PermuteParams& params); + explicit TransposeExecutor(const ExecutorContext::CPtr context); + virtual bool init(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs, + const dnnl::primitive_attr &attr) = 0; + virtual void exec(const std::vector& src, const std::vector& dst, const int MB) = 0; + virtual impl_desc_type getImplType() const = 0; + virtual ~TransposeExecutor() = default; +protected: + PermuteParams permuteParams; + const ExecutorContext::CPtr context; +}; +using TransposeExecutorPtr = std::shared_ptr; +using TransposeExecutorCPtr = std::shared_ptr; + +class TransposeExecutorBuilder { +public: + virtual ~TransposeExecutorBuilder() = default; + virtual bool isSupported(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs) const = 0; + virtual TransposeExecutorPtr makeExecutor(const ExecutorContext::CPtr context) const = 0; +}; + +using TransposeExecutorBuilderPtr = std::shared_ptr; +using TransposeExecutorBuilderCPtr = std::shared_ptr; + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/transpose_list.cpp b/src/plugins/intel_cpu/src/nodes/executors/transpose_list.cpp new file mode 100644 index 00000000000000..1249aad5685450 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/transpose_list.cpp @@ -0,0 +1,51 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transpose_list.hpp" + +namespace ov { +namespace intel_cpu { + +const std::vector& getTransposeExecutorsList() { + static const std::vector descs = { + OV_CPU_INSTANCE_COMMON(ExecutorType::Common, std::make_shared()) + OV_CPU_INSTANCE_ACL(ExecutorType::Acl, std::make_shared()) + OV_CPU_INSTANCE_X64(ExecutorType::x64, std::make_shared()) + OV_CPU_INSTANCE_COMMON(ExecutorType::Common, std::make_shared()) + }; + + return descs; +} + +TransposeExecutorPtr TransposeExecutorFactory::makeExecutor(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs, + const dnnl::primitive_attr &attr) { + auto build = [&](const TransposeExecutorDesc* desc) { + auto executor = desc->builder->makeExecutor(context); + if (executor->init(transposeParams, srcDescs, dstDescs, attr)) { + return executor; + } + TransposeExecutorPtr ptr = nullptr; + return ptr; + }; + + if (chosenDesc) { + if (auto executor = build(chosenDesc)) { + return executor; + } + } + + for (const auto& sd : supportedDescs) { + if (auto executor = build(&sd)) { + chosenDesc = &sd; + return executor; + } + } + + IE_THROW() << "Supported executor is not found"; +} + +} // namespace intel_cpu +} // namespace ov diff --git a/src/plugins/intel_cpu/src/nodes/executors/transpose_list.hpp b/src/plugins/intel_cpu/src/nodes/executors/transpose_list.hpp new file mode 100644 index 00000000000000..89d322ed91fd5f --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/transpose_list.hpp @@ -0,0 +1,59 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "executor.hpp" + +#include "transpose.hpp" +#if defined(OV_CPU_WITH_ACL) +#include "acl/acl_transpose.hpp" +#endif + +#include "common/ref_opt_transpose.hpp" +#include "common/ref_transpose.hpp" +#include "x64/jit_transpose.hpp" + +#include "onednn/iml_type_mapper.h" +#include "common/primitive_cache.hpp" + +namespace ov { +namespace intel_cpu { + +struct TransposeExecutorDesc { + ExecutorType executorType; + TransposeExecutorBuilderCPtr builder; +}; + +const std::vector& getTransposeExecutorsList(); + +class TransposeExecutorFactory : public ExecutorFactory { +public: +TransposeExecutorFactory(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs, + const ExecutorContext::CPtr context) : ExecutorFactory(context) { + for (auto& desc : getTransposeExecutorsList()) { + if (desc.builder->isSupported(transposeParams, srcDescs, dstDescs)) { + supportedDescs.push_back(desc); + } + } +} + +~TransposeExecutorFactory() = default; +virtual TransposeExecutorPtr makeExecutor(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs, + const dnnl::primitive_attr &attr); + +private: + std::vector supportedDescs; + const TransposeExecutorDesc* chosenDesc = nullptr; +}; + +using TransposeExecutorFactoryPtr = std::shared_ptr; +using TransposeExecutorFactoryCPtr = std::shared_ptr; + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/x64/jit_transpose.cpp b/src/plugins/intel_cpu/src/nodes/executors/x64/jit_transpose.cpp new file mode 100644 index 00000000000000..3776cf9b084647 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/x64/jit_transpose.cpp @@ -0,0 +1,42 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "jit_transpose.hpp" +#include "cpu/x64/cpu_isa_traits.hpp" + +using namespace dnnl::impl::cpu; +using namespace dnnl::impl::cpu::x64; + +namespace ov { +namespace intel_cpu { +void JitTransposeExecutor::exec(const std::vector& src, const std::vector& dst, const int MB) { + if (!pKernel) + IE_THROW() << "Could not execute. Kernel for Transpose node was not compiled."; + + const uint8_t* srcData = reinterpret_cast(src[0]->getData()); + uint8_t* dstData = reinterpret_cast(dst[0]->getData()); + + pKernel->execute(srcData, dstData, MB); +} + +bool JitTransposeExecutor::init(const TransposeParams &transposeParams, + const std::vector &srcDescs, + const std::vector &dstDescs, const dnnl::primitive_attr &attr) { + pKernel = std::make_shared(transposeParams.permuteParams); + return true; +} + +bool JitTransposeExecutorBuilder::isSupported(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs) const { +#if defined(OPENVINO_ARCH_X86_64) + if (mayiuse(x64::sse41)) { + return true; + } +#endif // OPENVINO_ARCH_X86_64 + return false; +} + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/executors/x64/jit_transpose.hpp b/src/plugins/intel_cpu/src/nodes/executors/x64/jit_transpose.hpp new file mode 100644 index 00000000000000..2e757fef58ce82 --- /dev/null +++ b/src/plugins/intel_cpu/src/nodes/executors/x64/jit_transpose.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "nodes/executors/transpose.hpp" + +namespace ov { +namespace intel_cpu { + +class JitTransposeExecutor : public TransposeExecutor { +public: + using TransposeExecutor::TransposeExecutor; + + bool init(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs, + const dnnl::primitive_attr &attr) override; + void exec(const std::vector& src, const std::vector& dst, const int MB) override; + impl_desc_type getImplType() const override { return implType; } +private: + std::shared_ptr pKernel; + static const impl_desc_type implType = impl_desc_type::jit; +}; + +class JitTransposeExecutorBuilder : public TransposeExecutorBuilder { +public: + bool isSupported(const TransposeParams& transposeParams, + const std::vector& srcDescs, + const std::vector& dstDescs) const override; + TransposeExecutorPtr makeExecutor(const ExecutorContext::CPtr context) const override { + return std::make_shared(context); + } +}; + +} // namespace intel_cpu +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/nodes/transpose.cpp b/src/plugins/intel_cpu/src/nodes/transpose.cpp index 1998c90023788c..750ae6bf711ca0 100644 --- a/src/plugins/intel_cpu/src/nodes/transpose.cpp +++ b/src/plugins/intel_cpu/src/nodes/transpose.cpp @@ -142,35 +142,49 @@ void Transpose::initSupportedPrimitiveDescriptors() { Precision::I32, getInputShapeAtPort(INPUT_ORDER_IDX))); config.outConfs[0].inPlace(-1); config.outConfs[0].constant(false); + transpose_context = std::make_shared(context, getImplPriority()); + + auto supportedPrimitiveDescriptorsBuilder = [this](NodeConfig config, TransposeParams transposeParams) { + std::vector srcMemoryDescs; + for (size_t i = 0; i < config.inConfs.size(); i++) { + srcMemoryDescs.push_back(config.inConfs[i].getMemDesc()); + } + std::vector dstMemoryDescs; + for (size_t i = 0; i < config.outConfs.size(); i++) { + dstMemoryDescs.push_back(config.outConfs[i].getMemDesc()); + } + auto factory = std::make_shared(transposeParams, srcMemoryDescs, dstMemoryDescs, transpose_context); + supportedPrimitiveDescriptors.push_back({config, impl_desc_type::unknown, factory}); + }; const auto& inputDataShape = getInputShapeAtPort(INPUT_DATA_IDX); const auto& outputDataShape = getOutputShapeAtPort(0); if (inputDataShape.getRank() == 4 || inputDataShape.getRank() == 5) { config.inConfs[0].setMemDesc(creatorsMap.at(LayoutType::ncsp)->createSharedDesc(prec, inputDataShape)); config.outConfs[0].setMemDesc(creatorsMap.at(LayoutType::ncsp)->createSharedDesc(prec, outputDataShape)); - supportedPrimitiveDescriptors.push_back({config, impl_desc_type::unknown}); - + supportedPrimitiveDescriptorsBuilder(config, transposeParams); +#if defined(OPENVINO_ARCH_X86_64) const auto& srcDims = inputDataShape.getDims(); if (srcDims[1] != Shape::UNDEFINED_DIM && srcDims[1] % 8 == 0) { config.inConfs[0].setMemDesc(creatorsMap.at(LayoutType::nCsp8c)->createSharedDesc(prec, inputDataShape)); - supportedPrimitiveDescriptors.push_back({config, impl_desc_type::unknown}); + supportedPrimitiveDescriptorsBuilder(config, transposeParams); } if (srcDims[1] != Shape::UNDEFINED_DIM && srcDims[1] % 16 == 0) { config.inConfs[0].setMemDesc(creatorsMap.at(LayoutType::nCsp16c)->createSharedDesc(prec, inputDataShape)); - supportedPrimitiveDescriptors.push_back({config, impl_desc_type::unknown}); + supportedPrimitiveDescriptorsBuilder(config, transposeParams); } - +#endif // OPENVINO_ARCH_X86_64 if (prec == Precision::FP32 || prec == Precision::I8 || prec == Precision::U8) { config.inConfs[0].setMemDesc(creatorsMap.at(LayoutType::nspc)->createSharedDesc(prec, inputDataShape)); config.outConfs[0].setMemDesc(creatorsMap.at(LayoutType::nspc)->createSharedDesc(prec, outputDataShape)); - supportedPrimitiveDescriptors.push_back({config, impl_desc_type::unknown}); + supportedPrimitiveDescriptorsBuilder(config, transposeParams); } } else { // general plain case config.inConfs[0].setMemDesc(creatorsMap.at(LayoutType::ncsp)->createSharedDesc(prec, inputDataShape)); config.outConfs[0].setMemDesc(creatorsMap.at(LayoutType::ncsp)->createSharedDesc(prec, outputDataShape)); - supportedPrimitiveDescriptors.push_back({config, impl_desc_type::unknown}); + supportedPrimitiveDescriptorsBuilder(config, transposeParams); } } @@ -179,8 +193,6 @@ bool Transpose::isExecutable() const { } bool Transpose::needPrepareParams() const { - if (isOptimized) - return false; return inputShapesModified(); } @@ -211,23 +223,29 @@ void Transpose::prepareParams() { } auto srcDesc = getParentEdgeAt(INPUT_DATA_IDX)->getMemory().getDescWithType(); - params.src_block_dims = srcDesc->getBlockDims(); + transposeParams.permuteParams.src_block_dims = srcDesc->getBlockDims(); auto dstDesc = getChildEdgeAt(0)->getMemory().getDescWithType(); - params.dst_block_dims = dstDesc->getBlockDims(); + transposeParams.permuteParams.dst_block_dims = dstDesc->getBlockDims(); if (!isInputOrderConst) { auto orderPtr = reinterpret_cast(getParentEdgeAt(0)->getMemoryPtr()->getData()); auto orderLen = getParentEdgeAt(0)->getMemoryPtr()->getSize(); - params.order.assign(orderPtr, orderPtr + orderLen); + transposeParams.permuteParams.order.assign(orderPtr, orderPtr + orderLen); } auto engine = getEngine(); - auto builder = [](const PermuteParams& key) -> std::shared_ptr { - return std::make_shared(key); + auto builder = [&srcDesc, &dstDesc, this](const PermuteParams& key) -> std::shared_ptr { + dnnl::primitive_attr attr; + auto selectedPD = getSelectedPrimitiveDescriptor(); + auto jitExec = selectedPD->getExecutorFactoryAs()->makeExecutor(transposeParams, + {srcDesc}, + {dstDesc}, + attr); + return jitExec; }; auto cache = context->getParamsCache(); - auto result = cache->getOrCreate(params, builder); + auto result = cache->getOrCreate(transposeParams.permuteParams, builder); if (!result.first) { IE_THROW() << "Primitive descriptor was not found for node " << getName() << "."; @@ -250,21 +268,16 @@ void Transpose::createPrimitive() { getChildEdgeAt(0)->getMemory().getDesc().hasLayoutType(LayoutType::ncsp) && order == std::vector{0, 3, 1, 2}) { performAsReorder = true; - } else if (getParentEdgeAt(INPUT_DATA_IDX)->getMemory().getDesc().hasLayoutType(LayoutType::ncsp) && - std::find(optimizedOrders.begin(), optimizedOrders.end(), order) != optimizedOrders.end()) { - isOptimized = true; - execPtr = std::make_shared(); - return; } if (!performAsReorder) { - params.data_size = getSelectedPrimitiveDescriptor()->getConfig().inConfs[0].getMemDesc()->getPrecision().size(); + transposeParams.permuteParams.data_size = getSelectedPrimitiveDescriptor()->getConfig().inConfs[0].getMemDesc()->getPrecision().size(); if (isInputOrderConst) - params.order = order; + transposeParams.permuteParams.order = order; auto srcDesc = getParentEdgeAt(INPUT_DATA_IDX)->getMemory().getDescWithType(); - params.src_block_order = srcDesc->getOrder(); + transposeParams.permuteParams.src_block_order = srcDesc->getOrder(); auto dstDesc = getChildEdgeAt(0)->getMemory().getDescWithType(); - params.dst_block_order = dstDesc->getOrder(); + transposeParams.permuteParams.dst_block_order = dstDesc->getOrder(); } if (inputShapesDefined() && isExecutable()) { @@ -273,107 +286,6 @@ void Transpose::createPrimitive() { } } -template -static void transpose_to_0312(const int MB, const MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr) { - const auto src_data = reinterpret_cast(srcMemPtr->getData()); - auto dst_data = reinterpret_cast(dstMemPtr->getData()); - - const int DIM1 = srcMemPtr->getStaticDims()[1]; - const int DIM2 = srcMemPtr->getStaticDims()[2]; - const int DIM3 = srcMemPtr->getStaticDims()[3]; - - parallel_for3d(MB, DIM1, DIM2, [&](const int n, const int dim1, const int dim2) { - for (int dim3 = 0; dim3 < DIM3; ++dim3) { - const int src_off = n * DIM1 * DIM2 * DIM3 + - dim1 * DIM2 * DIM3 + - dim2 * DIM3 + - dim3; - const int dst_off = n * DIM1 * DIM2 * DIM3 + - dim3 * DIM1 * DIM2 + - dim1 * DIM2 + - dim2; - - dst_data[dst_off] = src_data[src_off]; - } - }); -} - -template -static void transpose_to_04123(const int MB, const MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr) { - const auto src_data = reinterpret_cast(srcMemPtr->getData()); - auto dst_data = reinterpret_cast(dstMemPtr->getData()); - - const int DIM1 = srcMemPtr->getStaticDims()[1]; - const int DIM2 = srcMemPtr->getStaticDims()[2]; - const int DIM3 = srcMemPtr->getStaticDims()[3]; - const int DIM4 = srcMemPtr->getStaticDims()[4]; - - parallel_for4d(MB, DIM1, DIM2, DIM3, [&](const int n, const int dim1, const int dim2, const int dim3) { - for (int dim4 = 0; dim4 < DIM4; ++dim4) { - const int src_off = n * DIM1 * DIM2 * DIM3 * DIM4 + - dim1 * DIM2 * DIM3 * DIM4 + - dim2 * DIM3 * DIM4 + - dim3 * DIM4 + - dim4; - const int dst_off = n * DIM1 * DIM2 * DIM3 * DIM4 + - dim4 * DIM1 * DIM2 * DIM3 + - dim1 * DIM2 * DIM3 + - dim2 * DIM3 + - dim3; - - dst_data[dst_off] = src_data[src_off]; - } - }); -} - -template -static void transpose_to_051234(const int MB, const MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr) { - const auto src_data = reinterpret_cast(srcMemPtr->getData()); - auto dst_data = reinterpret_cast(dstMemPtr->getData()); - - const int DIM1 = srcMemPtr->getStaticDims()[1]; - const int DIM2 = srcMemPtr->getStaticDims()[2]; - const int DIM3 = srcMemPtr->getStaticDims()[3]; - const int DIM4 = srcMemPtr->getStaticDims()[4]; - const int DIM5 = srcMemPtr->getStaticDims()[5]; - - parallel_for5d(MB, DIM1, DIM2, DIM3, DIM4, [&](const int n, const int dim1, const int dim2, const int dim3, const int dim4) { - for (int dim5 = 0; dim5 < DIM5; ++dim5) { - const int src_off = n * DIM1 * DIM2 * DIM3 * DIM4 * DIM5 + - dim1 * DIM2 * DIM3 * DIM4 * DIM5 + - dim2 * DIM3 * DIM4 * DIM5 + - dim3 * DIM4 * DIM5 + - dim4 * DIM5 + - dim5; - const int dst_off = n * DIM5 * DIM1 * DIM2 * DIM3 * DIM4 + - dim5 * DIM1 * DIM2 * DIM3 * DIM4 + - dim1 * DIM2 * DIM3 * DIM4 + - dim2 * DIM3 * DIM4 + - dim3 * DIM4 + - dim4; - - dst_data[dst_off] = src_data[src_off]; - } - }); -} - -template -void Transpose::optimizedExecute(const int MB, const MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr) { - switch (srcMemPtr->getStaticDims().size()) { - case 4: - transpose_to_0312(MB, srcMemPtr, dstMemPtr); - break; - case 5: - transpose_to_04123(MB, srcMemPtr, dstMemPtr); - break; - case 6: - transpose_to_051234(MB, srcMemPtr, dstMemPtr); - break; - default: - IE_THROW() << "Transpose '" << getName() << "' supports optimized execution with only 4D, 5D and 6D shapes"; - } -} - void Transpose::execute(dnnl::stream strm) { if (prim) { prim.execute(strm, primArgs); @@ -383,7 +295,7 @@ void Transpose::execute(dnnl::stream strm) { int MB = srcMemPtr->getStaticDims()[0]; - execPtr->exec(this, srcMemPtr, dstMemPtr, MB); + execPtr->exec({srcMemPtr}, {dstMemPtr}, MB); } else { IE_THROW() << "Could not execute Transpose node. Primitive was not created."; } @@ -393,29 +305,6 @@ void Transpose::executeDynamicImpl(dnnl::stream strm) { execute(strm); } -Transpose::TransposeJitExecutor::TransposeJitExecutor(const PermuteParams& params) { - pKernel = std::make_shared(params); -} - -void Transpose::TransposeJitExecutor::exec(Transpose* node, MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr, const int MB) { - if (!pKernel) - IE_THROW() << "Could not execute. Kernel for Transpose node was not compiled."; - - const uint8_t* srcData = reinterpret_cast(srcMemPtr->getData()); - uint8_t* dstData = reinterpret_cast(dstMemPtr->getData()); - - pKernel->execute(srcData, dstData, MB); -} - -void Transpose::TransposeRefExecutor::exec(Transpose* node, MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr, const int MB) { - const size_t dataSize = srcMemPtr->getDesc().getPrecision().size(); - TransposeContext ctx = {node, srcMemPtr, dstMemPtr, MB}; - OV_SWITCH(intel_cpu, TransposeOptimizedEmitter, ctx, dataSize, - OV_CASE(1u, PrecisionTrait::value_type), - OV_CASE(2u, PrecisionTrait::value_type), - OV_CASE(4u, PrecisionTrait::value_type)); -} - bool Transpose::created() const { return getType() == Type::Transpose; } diff --git a/src/plugins/intel_cpu/src/nodes/transpose.h b/src/plugins/intel_cpu/src/nodes/transpose.h index 03988d24fe8367..5fb7e9f76570bf 100644 --- a/src/plugins/intel_cpu/src/nodes/transpose.h +++ b/src/plugins/intel_cpu/src/nodes/transpose.h @@ -5,6 +5,7 @@ #pragma once #include "common/permute_kernel.h" +#include "executors/transpose_list.hpp" #include #include @@ -39,56 +40,15 @@ class Transpose : public Node { protected: void executeDynamicImpl(dnnl::stream strm) override; + std::shared_ptr transpose_context; private: - struct TransposeExecutor { - TransposeExecutor() = default; - virtual void exec(Transpose* node, MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr, const int MB) = 0; - virtual ~TransposeExecutor() = default; - }; - using executorPtr = std::shared_ptr; - executorPtr execPtr = nullptr; + TransposeExecutorPtr execPtr = nullptr; dnnl::primitive prim; - - struct TransposeJitExecutor : public TransposeExecutor { - TransposeJitExecutor(const PermuteParams& params); - void exec(Transpose* node, MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr, const int MB) override; - - std::shared_ptr pKernel; - }; - - struct TransposeRefExecutor : public TransposeExecutor { - TransposeRefExecutor() = default; - void exec(Transpose* node, MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr, const int MB) override; - }; - - template void optimizedExecute(const int MB, const MemoryPtr& srcMemPtr, MemoryPtr& dstMemPtr); - InferenceEngine::SizeVector order; InferenceEngine::Precision prec; - bool isOptimized = false; - - const std::vector> optimizedOrders = { - std::vector{0, 3, 1, 2}, - std::vector{0, 4, 1, 2, 3}, - std::vector{0, 5, 1, 2, 3, 4}, - }; - - PermuteParams params; - - struct TransposeContext { - Transpose* nodePtr; - MemoryPtr srcMemPtr; - MemoryPtr dstMemPtr; - int MB; - }; - template - struct TransposeOptimizedEmitter { - void operator()(TransposeContext& ctx) { - ctx.nodePtr->optimizedExecute(ctx.MB, ctx.srcMemPtr, ctx.dstMemPtr); - } - }; + TransposeParams transposeParams; bool isInputOrderConst = false; diff --git a/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/transpose.cpp b/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/transpose.cpp new file mode 100644 index 00000000000000..f90af8c07d008e --- /dev/null +++ b/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/transpose.cpp @@ -0,0 +1,121 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transpose.hpp" + +#include "gtest/gtest.h" +#include "test_utils/cpu_test_utils.hpp" + +using namespace InferenceEngine; +using namespace CPUTestUtils; +using namespace ngraph::helpers; +using namespace ov::test; + +namespace CPULayerTestsDefinitions { +std::string TransposeLayerCPUTest::getTestCaseName(testing::TestParamInfo obj) { + Precision netPrecision; + InputShape inputShapes; + std::vector inputOrder; + std::string targetDevice; + CPUSpecificParams cpuParams; + std::map additionalConfig; + std::tie(inputShapes, inputOrder, netPrecision, targetDevice, additionalConfig, cpuParams) = obj.param; + + std::ostringstream result; + result << "IS=" << CommonTestUtils::partialShape2str({inputShapes.first}) << "_"; + result << "TS=("; + for (const auto& shape : inputShapes.second) { + result << CommonTestUtils::vec2str(shape) << "_"; + } + result << ")_"; + result << "inputOrder=" << CommonTestUtils::vec2str(inputOrder) << "_"; + result << "netPRC=" << netPrecision.name() << "_"; + result << "trgDev=" << targetDevice; + result << CPUTestsBase::getTestCaseName(cpuParams); + return result.str(); +} + +void TransposeLayerCPUTest::SetUp() { + Precision netPrecision; + InputShape inputShapes; + std::vector inputOrder; + CPUSpecificParams cpuParams; + std::map additionalConfig; + std::tie(inputShapes, inputOrder, netPrecision, targetDevice, additionalConfig, cpuParams) = this->GetParam(); + configuration.insert(additionalConfig.begin(), additionalConfig.end()); + + inType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + outType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + + std::tie(inFmts, outFmts, priority, selectedType) = cpuParams; + + selectedType = makeSelectedTypeStr("unknown", inType); + + init_input_shapes({inputShapes}); + + auto params = ngraph::builder::makeDynamicParams(inType, {inputDynamicShapes[0]}); + + const auto inputOrderOp = + std::make_shared(ov::element::i64, ov::Shape({inputOrder.size()}), inputOrder); + const auto transpose = std::make_shared(params[0], inputOrderOp); + transpose->get_rt_info() = getCPUInfo(); + const ov::ResultVector results{std::make_shared(transpose)}; + + function = std::make_shared(results, params, "TransposeLayerCPUTest"); + functionRefs = ngraph::clone_function(*function); +} + +TEST_P(TransposeLayerCPUTest, CompareWithRefs) { + run(); + CheckPluginRelatedResults(compiledModel, "Transpose"); +} + +namespace Transpose { +const std::vector& netPrecisionsPerChannels() { + static const std::vector netPrecisionsPerChannels = {Precision::I8, Precision::FP32}; + return netPrecisionsPerChannels; +} + +const std::vector& dynamicInputShapes4DC16() { + static const std::vector dynamicInputShapes4DC16 = {InputShape{// dynamic + {-1, 16, -1, -1}, + // target + {{2, 16, 21, 10}, {3, 16, 11, 12}, {2, 16, 21, 10}}}}; + return dynamicInputShapes4DC16; +} + +const std::vector& dynamicInputShapes4DC32() { + static const std::vector dynamicInputShapes4DC32 = {InputShape{// dynamic + {-1, 32, -1, -1}, + // target + {{4, 32, 16, 14}, {16, 32, 5, 16}, {4, 32, 16, 14}}}}; + return dynamicInputShapes4DC32; +} + +const std::vector& dynamicInputShapes4D() { + static const std::vector dynamicInputShapes4D = { + InputShape{// dynamic + {ov::Dimension(1, 20), ov::Dimension(10, 40), ov::Dimension(10, 40), ov::Dimension(10, 40)}, + // target + {{1, 32, 21, 10}, {2, 25, 11, 12}, {4, 15, 16, 14}, {7, 10, 20, 16}, {1, 32, 21, 10}}}, + InputShape{// dynamic + {-1, -1, -1, -1}, + // target + {{1, 24, 21, 8}, {2, 16, 11, 6}, {1, 24, 21, 8}}} + }; + return dynamicInputShapes4D; +} + +const std::vector>& inputOrder4D() { + static const std::vector> inputOrder4D = { + std::vector{0, 1, 2, 3}, + std::vector{0, 2, 3, 1}, + std::vector{0, 2, 1, 3}, + std::vector{1, 0, 2, 3}, + std::vector{}, + }; + return inputOrder4D; +} +} // namespace Transpose +} // namespace CPULayerTestsDefinitions \ No newline at end of file diff --git a/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/transpose.hpp b/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/transpose.hpp new file mode 100644 index 00000000000000..6d07d4a0d22943 --- /dev/null +++ b/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/transpose.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_layer/transpose.hpp" +#include "ngraph_functions/builders.hpp" +#include "shared_test_classes/base/ov_subgraph.hpp" +#include "test_utils/cpu_test_utils.hpp" +#include "gtest/gtest.h" + + +using namespace InferenceEngine; +using namespace CPUTestUtils; +using namespace ov::test; + +namespace CPULayerTestsDefinitions { +typedef std::tuple< + InputShape, // Input shapes + std::vector, // Input order + InferenceEngine::Precision, // Net precision + std::string, // Target device name + std::map, // Additional network configuration + CPUSpecificParams> TransposeLayerCPUTestParamSet; + +class TransposeLayerCPUTest : public testing::WithParamInterface, + public ov::test::SubgraphBaseTest, public CPUTestsBase { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); +protected: + void SetUp() override; +}; + +namespace Transpose { + const std::vector& netPrecisionsPerChannels(); + const std::vector& dynamicInputShapes4DC16(); + const std::vector& dynamicInputShapes4DC32(); + const std::vector& dynamicInputShapes4D(); + const std::vector>& inputOrder4D(); +} // namespace Transpose +} // namespace CPULayerTestsDefinitions \ No newline at end of file diff --git a/src/plugins/intel_cpu/tests/functional/single_layer_tests/instances/common/transpose.cpp b/src/plugins/intel_cpu/tests/functional/single_layer_tests/instances/common/transpose.cpp new file mode 100644 index 00000000000000..0684aaeaec622d --- /dev/null +++ b/src/plugins/intel_cpu/tests/functional/single_layer_tests/instances/common/transpose.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "single_layer_tests/classes/transpose.hpp" +#include "shared_test_classes/single_layer/transpose.hpp" +#include "test_utils/cpu_test_utils.hpp" + +using namespace InferenceEngine; +using namespace CPUTestUtils; +using namespace ngraph::helpers; +using namespace ov::test; + +namespace CPULayerTestsDefinitions { +namespace Transpose { +std::map additional_config; + +const auto cpuParams_nhwc = CPUSpecificParams {{nhwc}, {}, {}, {}}; +const auto cpuParams_nchw = CPUSpecificParams {{nchw}, {}, {}, {}}; + +const std::vector netPrecisions = { + Precision::I8, + Precision::FP32 +}; + +const std::vector> inputOrderPerChannels4D = { + std::vector{0, 1, 2, 3}, + std::vector{0, 2, 1, 3}, + std::vector{1, 0, 2, 3}, + std::vector{}, +}; + +const std::vector CPUParams4D = { + cpuParams_nchw, +}; + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC16_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4DC16()), + ::testing::ValuesIn(inputOrder4D()), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParams4D)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC32_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4DC32()), + ::testing::ValuesIn(inputOrder4D()), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParams4D)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes4D_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4D()), + ::testing::ValuesIn(inputOrder4D()), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(CPUSpecificParams{})), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC16_PermutePerChannels, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4DC16()), + ::testing::ValuesIn(inputOrderPerChannels4D), + ::testing::ValuesIn(netPrecisionsPerChannels()), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(cpuParams_nhwc)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC32_PermutePerChannels, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4DC32()), + ::testing::ValuesIn(inputOrderPerChannels4D), + ::testing::ValuesIn(netPrecisionsPerChannels()), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(cpuParams_nhwc)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes4D_PermutePerChannels, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4D()), + ::testing::ValuesIn(inputOrderPerChannels4D), + ::testing::ValuesIn(netPrecisionsPerChannels()), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(CPUSpecificParams{})), + TransposeLayerCPUTest::getTestCaseName); + +} // namespace Transpose +} // namespace CPULayerTestsDefinitions \ No newline at end of file diff --git a/src/plugins/intel_cpu/tests/functional/single_layer_tests/instances/x64/transpose.cpp b/src/plugins/intel_cpu/tests/functional/single_layer_tests/instances/x64/transpose.cpp new file mode 100644 index 00000000000000..b6dbb7657007e2 --- /dev/null +++ b/src/plugins/intel_cpu/tests/functional/single_layer_tests/instances/x64/transpose.cpp @@ -0,0 +1,181 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "single_layer_tests/classes/transpose.hpp" +#include "shared_test_classes/single_layer/transpose.hpp" +#include "test_utils/cpu_test_utils.hpp" + +using namespace InferenceEngine; +using namespace CPUTestUtils; +using namespace ngraph::helpers; +using namespace ov::test; + + +namespace CPULayerTestsDefinitions { +namespace Transpose { +namespace { +std::map additional_config; + +const auto cpuParams_ndhwc = CPUSpecificParams {{ndhwc}, {}, {}, {}}; +const auto cpuParams_ncdhw = CPUSpecificParams {{ncdhw}, {}, {}, {}}; + +const auto cpuParams_nChw16c = CPUSpecificParams {{nChw16c}, {}, {}, {}}; +const auto cpuParams_nCdhw16c = CPUSpecificParams {{nCdhw16c}, {}, {}, {}}; + +const auto cpuParams_nChw8c = CPUSpecificParams {{nChw8c}, {}, {}, {}}; +const auto cpuParams_nCdhw8c = CPUSpecificParams {{nCdhw8c}, {}, {}, {}}; + +const std::vector netPrecisions = { + Precision::I8, + Precision::BF16, + Precision::FP32 +}; + +const std::vector CPUParams4D_blocked = { + cpuParams_nChw16c, + cpuParams_nChw8c, +}; + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC16_TransposeBlocked, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4DC16()), + ::testing::ValuesIn(inputOrder4D()), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParams4D_blocked)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC32_TransposeBlocked, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4DC32()), + ::testing::ValuesIn(inputOrder4D()), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParams4D_blocked)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes4D_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes4D()), + ::testing::ValuesIn(inputOrder4D()), + ::testing::Values(Precision::BF16), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(CPUSpecificParams{})), + TransposeLayerCPUTest::getTestCaseName); + +const std::vector staticInputShapes5DC16 = {InputShape{ + // dynamic + {-1, 16, -1, -1, -1}, + // Static shapes + {{2, 16, 5, 6, 5}, {3, 16, 6, 5, 6}, {2, 16, 5, 6, 5}}} +}; + +const std::vector staticInputShapes5DC32 = {InputShape{ + // dynamic + {-1, 32, -1, -1, -1}, + // Static shapes + {{4, 32, 5, 6, 5}, {5, 32, 6, 5, 6}, {4, 32, 5, 6, 5}}} +}; + +const std::vector dynamicInputShapes5D = {InputShape{ + // dynamic + {ov::Dimension(1, 20), ov::Dimension(5, 150), ov::Dimension(5, 40), ov::Dimension(5, 40), ov::Dimension(5, 40)}, + // target + {{1, 32, 5, 6, 5}, {2, 32, 6, 5, 6}, {4, 55, 5, 6, 5}, {3, 129, 6, 5, 6}, {1, 32, 5, 6, 5}}} +}; + +const std::vector> inputOrder5D = { + std::vector{0, 1, 2, 3, 4}, + std::vector{0, 4, 2, 3, 1}, + std::vector{0, 4, 2, 1, 3}, + std::vector{0, 2, 3, 4, 1}, + std::vector{0, 2, 4, 3, 1}, + std::vector{0, 3, 2, 4, 1}, + std::vector{0, 3, 1, 4, 2}, + std::vector{1, 0, 2, 3, 4}, + std::vector{}, +}; + +const std::vector> inputOrderPerChannels5D = { + std::vector{0, 1, 2, 3, 4}, + std::vector{0, 4, 2, 3, 1}, + std::vector{0, 4, 2, 1, 3}, + std::vector{0, 2, 4, 3, 1}, + std::vector{0, 3, 2, 4, 1}, + std::vector{0, 3, 1, 4, 2}, + std::vector{1, 0, 2, 3, 4}, + std::vector{}, +}; + +const std::vector CPUParams5D = { + cpuParams_nCdhw16c, + cpuParams_nCdhw8c, + cpuParams_ncdhw, +}; + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC16_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(staticInputShapes5DC16), + ::testing::ValuesIn(inputOrder5D), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParams5D)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC32_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(staticInputShapes5DC32), + ::testing::ValuesIn(inputOrder5D), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParams5D)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes5D_Transpose, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes5D), + ::testing::ValuesIn(inputOrder5D), + ::testing::Values(Precision::BF16), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(CPUSpecificParams{})), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC16_PermutePerChannels, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(staticInputShapes5DC16), + ::testing::ValuesIn(inputOrderPerChannels5D), + ::testing::ValuesIn(netPrecisionsPerChannels()), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(cpuParams_ndhwc)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC32_PermutePerChannels, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(staticInputShapes5DC32), + ::testing::ValuesIn(inputOrderPerChannels5D), + ::testing::ValuesIn(netPrecisionsPerChannels()), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(cpuParams_ndhwc)), + TransposeLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes5D_PermutePerChannels, TransposeLayerCPUTest, + ::testing::Combine( + ::testing::ValuesIn(dynamicInputShapes5D), + ::testing::ValuesIn(inputOrderPerChannels5D), + ::testing::ValuesIn(netPrecisionsPerChannels()), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(CPUSpecificParams{})), + TransposeLayerCPUTest::getTestCaseName); +} // namespace +} // namespace Transpose +} // namespace CPULayerTestsDefinitions \ No newline at end of file diff --git a/src/plugins/intel_cpu/tests/functional/single_layer_tests/transpose.cpp b/src/plugins/intel_cpu/tests/functional/single_layer_tests/transpose.cpp deleted file mode 100644 index 79ba069b5f91a3..00000000000000 --- a/src/plugins/intel_cpu/tests/functional/single_layer_tests/transpose.cpp +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "test_utils/cpu_test_utils.hpp" -#include "ngraph_functions/builders.hpp" - -#include "shared_test_classes/base/ov_subgraph.hpp" -// Since the Transpose ngraph operation is converted to the transpose node, we will use it in the transpose test - -using namespace InferenceEngine; -using namespace CPUTestUtils; -using namespace ov::test; - -namespace CPULayerTestsDefinitions { - -typedef std::tuple< - InputShape, // Input shapes - std::vector, // Input order - InferenceEngine::Precision, // Net precision - std::string, // Target device name - std::map, // Additional network configuration - CPUSpecificParams> TransposeLayerCPUTestParamSet; - -class TransposeLayerCPUTest : public testing::WithParamInterface, - public ov::test::SubgraphBaseTest, public CPUTestsBase { -public: - static std::string getTestCaseName(testing::TestParamInfo obj) { - Precision netPrecision; - InputShape inputShapes; - std::vector inputOrder; - std::string targetDevice; - CPUSpecificParams cpuParams; - std::map additionalConfig; - std::tie(inputShapes, inputOrder, netPrecision, targetDevice, additionalConfig, cpuParams) = obj.param; - - std::ostringstream result; - result << "IS=" << CommonTestUtils::partialShape2str({inputShapes.first}) << "_"; - result << "TS=("; - for (const auto& shape : inputShapes.second) { - result << CommonTestUtils::vec2str(shape) << "_"; - } - result << ")_"; - result << "inputOrder=" << CommonTestUtils::vec2str(inputOrder) << "_"; - result << "netPRC=" << netPrecision.name() << "_"; - result << "trgDev=" << targetDevice; - result << CPUTestsBase::getTestCaseName(cpuParams); - return result.str(); - } -protected: - void SetUp() override { - Precision netPrecision; - InputShape inputShapes; - std::vector inputOrder; - CPUSpecificParams cpuParams; - std::map additionalConfig; - std::tie(inputShapes, inputOrder, netPrecision, targetDevice, additionalConfig, cpuParams) = this->GetParam(); - configuration.insert(additionalConfig.begin(), additionalConfig.end()); - - inType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); - outType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); - - std::tie(inFmts, outFmts, priority, selectedType) = cpuParams; - - selectedType = makeSelectedTypeStr("unknown", inType); - - init_input_shapes({inputShapes}); - - auto params = ngraph::builder::makeDynamicParams(inType, { inputDynamicShapes[0] }); - - const auto inputOrderOp = std::make_shared(ov::element::i64, - ov::Shape({inputOrder.size()}), - inputOrder); - const auto transpose = std::make_shared(params[0], inputOrderOp); - transpose->get_rt_info() = getCPUInfo(); - const ov::ResultVector results{std::make_shared(transpose)}; - - function = std::make_shared(results, params, "TransposeLayerCPUTest"); - functionRefs = ngraph::clone_function(*function); - } -}; - -TEST_P(TransposeLayerCPUTest, CompareWithRefs) { - run(); - CheckPluginRelatedResults(compiledModel, "Transpose"); -} - -namespace { -std::map additional_config; - -const auto cpuParams_nChw16c = CPUSpecificParams {{nChw16c}, {}, {}, {}}; -const auto cpuParams_nCdhw16c = CPUSpecificParams {{nCdhw16c}, {}, {}, {}}; - -const auto cpuParams_nChw8c = CPUSpecificParams {{nChw8c}, {}, {}, {}}; -const auto cpuParams_nCdhw8c = CPUSpecificParams {{nCdhw8c}, {}, {}, {}}; - -const auto cpuParams_nhwc = CPUSpecificParams {{nhwc}, {}, {}, {}}; -const auto cpuParams_ndhwc = CPUSpecificParams {{ndhwc}, {}, {}, {}}; - -const auto cpuParams_nchw = CPUSpecificParams {{nchw}, {}, {}, {}}; -const auto cpuParams_ncdhw = CPUSpecificParams {{ncdhw}, {}, {}, {}}; - -const std::vector netPrecisions = { - Precision::I8, - Precision::BF16, - Precision::FP32 -}; - -const std::vector netPrecisionsPerChannels = {Precision::I8, Precision::FP32}; - -const std::vector staticInputShapes4DC16 = {InputShape{// dynamic - {-1, 16, -1, -1}, - // target - {{2, 16, 21, 10}, {3, 16, 11, 12}, {2, 16, 21, 10}}}}; - -const std::vector staticInputShapes4DC32 = {InputShape{// dynamic - {-1, 32, -1, -1}, - // target - {{4, 32, 16, 14}, {16, 32, 5, 16}, {4, 32, 16, 14}}}}; - -const std::vector dynamicInputShapes4D = { - InputShape{// dynamic - {ov::Dimension(1, 20), ov::Dimension(10, 40), ov::Dimension(10, 40), ov::Dimension(10, 40)}, - // target - {{1, 32, 21, 10}, {2, 25, 11, 12}, {4, 15, 16, 14}, {7, 10, 20, 16}, {1, 32, 21, 10}}}, - InputShape{// dynamic - {-1, -1, -1, -1}, - // target - {{1, 24, 21, 8}, {2, 16, 11, 6}, {1, 24, 21, 8}}} -}; - -const std::vector> inputOrder4D = { - std::vector{0, 1, 2, 3}, - std::vector{0, 2, 3, 1}, - std::vector{0, 2, 1, 3}, - std::vector{1, 0, 2, 3}, - std::vector{}, -}; - -const std::vector> inputOrderPerChannels4D = { - std::vector{0, 1, 2, 3}, - std::vector{0, 2, 1, 3}, - std::vector{1, 0, 2, 3}, - std::vector{}, -}; - -const std::vector CPUParams4D = { - cpuParams_nChw16c, - cpuParams_nChw8c, - cpuParams_nchw, -}; - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC16_Transpose, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes4DC16), - ::testing::ValuesIn(inputOrder4D), - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::ValuesIn(CPUParams4D)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC32_Transpose, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes4DC32), - ::testing::ValuesIn(inputOrder4D), - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::ValuesIn(CPUParams4D)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes4D_Transpose, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(dynamicInputShapes4D), - ::testing::ValuesIn(inputOrder4D), - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(CPUSpecificParams{})), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC16_PermutePerChannels, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes4DC16), - ::testing::ValuesIn(inputOrderPerChannels4D), - ::testing::ValuesIn(netPrecisionsPerChannels), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(cpuParams_nhwc)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes4DC32_PermutePerChannels, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes4DC32), - ::testing::ValuesIn(inputOrderPerChannels4D), - ::testing::ValuesIn(netPrecisionsPerChannels), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(cpuParams_nhwc)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes4D_PermutePerChannels, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(dynamicInputShapes4D), - ::testing::ValuesIn(inputOrderPerChannels4D), - ::testing::ValuesIn(netPrecisionsPerChannels), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(CPUSpecificParams{})), - TransposeLayerCPUTest::getTestCaseName); - -const std::vector staticInputShapes5DC16 = {InputShape{ - // dynamic - {-1, 16, -1, -1, -1}, - // Static shapes - {{2, 16, 5, 6, 5}, {3, 16, 6, 5, 6}, {2, 16, 5, 6, 5}}} -}; - -const std::vector staticInputShapes5DC32 = {InputShape{ - // dynamic - {-1, 32, -1, -1, -1}, - // Static shapes - {{4, 32, 5, 6, 5}, {5, 32, 6, 5, 6}, {4, 32, 5, 6, 5}}} -}; - -const std::vector dynamicInputShapes5D = {InputShape{ - // dynamic - {ov::Dimension(1, 20), ov::Dimension(5, 150), ov::Dimension(5, 40), ov::Dimension(5, 40), ov::Dimension(5, 40)}, - // target - {{1, 32, 5, 6, 5}, {2, 32, 6, 5, 6}, {4, 55, 5, 6, 5}, {3, 129, 6, 5, 6}, {1, 32, 5, 6, 5}}} -}; - -const std::vector> inputOrder5D = { - std::vector{0, 1, 2, 3, 4}, - std::vector{0, 4, 2, 3, 1}, - std::vector{0, 4, 2, 1, 3}, - std::vector{0, 2, 3, 4, 1}, - std::vector{0, 2, 4, 3, 1}, - std::vector{0, 3, 2, 4, 1}, - std::vector{0, 3, 1, 4, 2}, - std::vector{1, 0, 2, 3, 4}, - std::vector{}, -}; - -const std::vector> inputOrderPerChannels5D = { - std::vector{0, 1, 2, 3, 4}, - std::vector{0, 4, 2, 3, 1}, - std::vector{0, 4, 2, 1, 3}, - std::vector{0, 2, 4, 3, 1}, - std::vector{0, 3, 2, 4, 1}, - std::vector{0, 3, 1, 4, 2}, - std::vector{1, 0, 2, 3, 4}, - std::vector{}, -}; - -const std::vector CPUParams5D = { - cpuParams_nCdhw16c, - cpuParams_nCdhw8c, - cpuParams_ncdhw, -}; - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC16_Transpose, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes5DC16), - ::testing::ValuesIn(inputOrder5D), - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::ValuesIn(CPUParams5D)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC32_Transpose, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes5DC32), - ::testing::ValuesIn(inputOrder5D), - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::ValuesIn(CPUParams5D)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes5D_Transpose, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(dynamicInputShapes5D), - ::testing::ValuesIn(inputOrder5D), - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(CPUSpecificParams{})), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC16_PermutePerChannels, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes5DC16), - ::testing::ValuesIn(inputOrderPerChannels5D), - ::testing::ValuesIn(netPrecisionsPerChannels), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(cpuParams_ndhwc)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_staticShapes5DC32_PermutePerChannels, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(staticInputShapes5DC32), - ::testing::ValuesIn(inputOrderPerChannels5D), - ::testing::ValuesIn(netPrecisionsPerChannels), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(cpuParams_ndhwc)), - TransposeLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_SUITE_P(smoke_dynamicShapes5D_PermutePerChannels, TransposeLayerCPUTest, - ::testing::Combine( - ::testing::ValuesIn(dynamicInputShapes5D), - ::testing::ValuesIn(inputOrderPerChannels5D), - ::testing::ValuesIn(netPrecisionsPerChannels), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(CPUSpecificParams{})), - TransposeLayerCPUTest::getTestCaseName); - -} // namespace -} // namespace CPULayerTestsDefinitions diff --git a/src/plugins/intel_gna/src/gna_device.cpp b/src/plugins/intel_gna/src/gna_device.cpp index e367c6af499889..0f3319b1646e85 100644 --- a/src/plugins/intel_gna/src/gna_device.cpp +++ b/src/plugins/intel_gna/src/gna_device.cpp @@ -583,5 +583,10 @@ uint32_t GNADeviceHelper::retrieveMaxLayersCount() { return Limitations::kMaxLayersCountGNA3_X; } } + +bool GNADeviceHelper::isHwAvailable() { + return target->get_detected_device_version() != DeviceVersion::SoftwareEmulation && + target->get_detected_device_version() != DeviceVersion::NotSet; +} } // namespace intel_gna } // namespace ov diff --git a/src/plugins/intel_gna/src/gna_device.hpp b/src/plugins/intel_gna/src/gna_device.hpp index d52b4cee3ce331..3e4f1eb72bf157 100644 --- a/src/plugins/intel_gna/src/gna_device.hpp +++ b/src/plugins/intel_gna/src/gna_device.hpp @@ -123,6 +123,7 @@ class GNADeviceHelper : public GNADevice { void getGnaPerfCounters(std::map& retPerfCounters); static std::string GetGnaLibraryVersion(); + bool isHwAvailable(); const GnaAllocations& getAllAllocations() const { return allAllocations; } diff --git a/src/plugins/intel_gna/src/gna_plugin.cpp b/src/plugins/intel_gna/src/gna_plugin.cpp index af2e44e27956e7..20d8302a848cff 100644 --- a/src/plugins/intel_gna/src/gna_plugin.cpp +++ b/src/plugins/intel_gna/src/gna_plugin.cpp @@ -796,6 +796,10 @@ void GNAPlugin::DumpXNNToFile() const { } uint32_t GNAPlugin::QueueInference(const InferenceEngine::BlobMap& inputs, InferenceEngine::BlobMap& result) { + if (config.GetParameter(ov::intel_gna::execution_mode.name()).as() == "GNA_HW" && + !gnadevice->isHwAvailable()) { + THROW_GNA_EXCEPTION << "Execution mode GNA_HW is set, but hardware acceleration is unavailable"; + } auto freeWorker = requestWorkerPool_->findFreeModelWorker(); if (freeWorker == nullptr) { if (!m_graph_compiler->memory_connection.empty()) { diff --git a/src/plugins/intel_gpu/include/intel_gpu/graph/network.hpp b/src/plugins/intel_gpu/include/intel_gpu/graph/network.hpp index 9a1a59f5efc8b9..36f0ce9f081c63 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/graph/network.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/graph/network.hpp @@ -4,6 +4,8 @@ #pragma once +#include "openvino/runtime/threading/cpu_streams_executor.hpp" + #include "intel_gpu/graph/topology.hpp" #include "intel_gpu/graph/program.hpp" #include "intel_gpu/graph/serialization/binary_buffer.hpp" @@ -81,12 +83,12 @@ struct network { const topology& topo, const ExecutionConfig& config = {}, bool is_internal = false, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor = nullptr); + std::shared_ptr task_executor = nullptr); network(engine& engine, const std::set>& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal); network(program::ptr program, uint16_t stream_id = 0); @@ -103,13 +105,13 @@ struct network { static ptr build_network(engine& engine, const topology& topology, const ExecutionConfig& config = {}, - std::shared_ptr task_executor = nullptr, + std::shared_ptr task_executor = nullptr, bool is_internal = false); static ptr build_network(engine& engine, const std::set>& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal); static ptr allocate_network(stream::ptr stream, diff --git a/src/plugins/intel_gpu/include/intel_gpu/graph/program.hpp b/src/plugins/intel_gpu/include/intel_gpu/graph/program.hpp index 78258239f78ac3..c576185ae88f24 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/graph/program.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/graph/program.hpp @@ -4,6 +4,8 @@ #pragma once +#include "openvino/runtime/threading/cpu_streams_executor.hpp" + #include "intel_gpu/runtime/engine.hpp" #include "intel_gpu/runtime/stream.hpp" #include "intel_gpu/runtime/lru_cache.hpp" @@ -125,7 +127,7 @@ struct program { program(engine& engine_ref, topology const& topology, const ExecutionConfig& config, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor, + std::shared_ptr task_executor, bool is_internal = false, bool no_optimizations = false, bool is_body_program = false); @@ -133,14 +135,14 @@ struct program { program(engine& engine_ref, std::set> const& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal); explicit program(engine& engine); ~program(); engine& get_engine() const { return _engine; } const ExecutionConfig& get_config() const { return _config; } - InferenceEngine::CPUStreamsExecutor::Ptr get_task_executor() const { return _task_executor; } + std::shared_ptr get_task_executor() const { return _task_executor; } std::list& get_inputs() { return inputs; } // ToDo: redesign trim to ouptut pass to make it const as_well as get_engine and get options @@ -240,14 +242,14 @@ struct program { static ptr build_program(engine& engine, const topology& topology, const ExecutionConfig& config, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor, + std::shared_ptr task_executor, bool is_internal = false, bool no_optimizations = false, bool is_body_program = false); static ptr build_program(engine& engine, const std::set>& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal); static void init_primitives(); kernels_cache& get_kernels_cache() const; @@ -261,7 +263,7 @@ struct program { ICompilationContext& get_compilation_context() const { return *_compilation_context; } void cancel_compilation_context(); - static std::shared_ptr make_task_executor(const ExecutionConfig& config); + static std::shared_ptr make_task_executor(const ExecutionConfig& config); private: uint32_t prog_id = 0; @@ -270,7 +272,7 @@ struct program { // TODO: Consider moving it to engine std::unique_ptr _kernels_cache; ExecutionConfig _config; - std::shared_ptr _task_executor = nullptr; + std::shared_ptr _task_executor = nullptr; std::list inputs; std::vector outputs; nodes_ordering processing_order; diff --git a/src/plugins/intel_gpu/include/intel_gpu/graph/serialization/utils.hpp b/src/plugins/intel_gpu/include/intel_gpu/graph/serialization/utils.hpp index 1010280b7b5e94..9c77b1b66f6df3 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/graph/serialization/utils.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/graph/serialization/utils.hpp @@ -7,11 +7,13 @@ #define RUN_ALL_MODEL_CACHING_TESTS #include +#include "openvino/core/deprecated.hpp" #include "ie/ie_common.h" namespace cldnn { class serial_util { public: + OPENVINO_SUPPRESS_DEPRECATED_START static InferenceEngine::Layout layout_from_string(const std::string& name) { static const std::unordered_map layouts = { { "ANY", InferenceEngine::Layout::ANY }, @@ -36,8 +38,9 @@ class serial_util { if (it != layouts.end()) { return it->second; } - IE_THROW(NetworkNotRead) << "Unknown layout with name '" << name << "'"; + OPENVINO_THROW("Unknown layout with name '", name, "'"); } + OPENVINO_SUPPRESS_DEPRECATED_END }; class membuf : public std::streambuf { diff --git a/src/plugins/intel_gpu/include/intel_gpu/plugin/common_utils.hpp b/src/plugins/intel_gpu/include/intel_gpu/plugin/common_utils.hpp index 25d7b8308a28c7..767d60e7df3625 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/plugin/common_utils.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/plugin/common_utils.hpp @@ -7,6 +7,7 @@ #include #include "intel_gpu/runtime/layout.hpp" #include "openvino/core/layout.hpp" +#include "openvino/core/deprecated.hpp" #include "ngraph/type/element_type.hpp" @@ -15,7 +16,7 @@ namespace intel_gpu { #define TensorValue(val) static_cast(val) -inline cldnn::tensor tensor_from_dims(const InferenceEngine::SizeVector& dims, int def = 1) { +inline cldnn::tensor tensor_from_dims(const ov::Shape& dims, int def = 1) { switch (dims.size()) { case 0: return cldnn::tensor(cldnn::batch(def), cldnn::feature(def), cldnn::spatial(def, def)); case 1: return cldnn::tensor(cldnn::batch(dims[0]), cldnn::feature(def), cldnn::spatial(def, def)); @@ -24,10 +25,11 @@ inline cldnn::tensor tensor_from_dims(const InferenceEngine::SizeVector& dims, i case 4: return cldnn::tensor(cldnn::batch(dims[0]), cldnn::feature(dims[1]), cldnn::spatial(dims[3], dims[2])); case 5: return cldnn::tensor(cldnn::batch(dims[0]), cldnn::feature(dims[1]), cldnn::spatial(dims[4], dims[3], dims[2])); case 6: return cldnn::tensor(cldnn::batch(dims[0]), cldnn::feature(dims[1]), cldnn::spatial(dims[5], dims[4], dims[3], dims[2])); - default: IE_THROW() << "Invalid dimensions size(" << dims.size() << ") for gpu tensor"; + default: OPENVINO_THROW("Invalid dimensions size(", dims.size(), ") for gpu tensor"); } } +OPENVINO_SUPPRESS_DEPRECATED_START inline cldnn::data_types DataTypeFromPrecision(InferenceEngine::Precision p) { switch (p) { case InferenceEngine::Precision::I16: @@ -74,7 +76,7 @@ inline InferenceEngine::Precision PrecisionFromDataType(cldnn::data_types dt) { case cldnn::data_types::i64: return InferenceEngine::Precision::ePrecision::I64; default: - IE_THROW(ParameterMismatch) << "The plugin does not support " << cldnn::data_type_traits::name(dt) << " data type"; + OPENVINO_THROW("The plugin does not support ", cldnn::data_type_traits::name(dt), " data type"); } } @@ -140,21 +142,7 @@ inline cldnn::format ImageFormatFromLayout(InferenceEngine::Layout l) { << "The plugin does not support " << l << " image layout"; } } - -inline InferenceEngine::Layout InferenceEngineLayoutFromOVLayout(ov::Layout l) { - if (l == ov::Layout("C")) return InferenceEngine::Layout::C; - if (l == ov::Layout("CN")) return InferenceEngine::Layout::CN; - if (l == ov::Layout("HW")) return InferenceEngine::Layout::HW; - if (l == ov::Layout("NC")) return InferenceEngine::Layout::NC; - if (l == ov::Layout("CHW")) return InferenceEngine::Layout::CHW; - if (l == ov::Layout("HWC")) return InferenceEngine::Layout::HWC; - if (l == ov::Layout("NCHW")) return InferenceEngine::Layout::NCHW; - if (l == ov::Layout("NC??")) return InferenceEngine::Layout::NCHW; - if (l == ov::Layout("NHWC")) return InferenceEngine::Layout::NHWC; - if (l == ov::Layout("NCDHW")) return InferenceEngine::Layout::NCDHW; - if (l == ov::Layout("NDHWC")) return InferenceEngine::Layout::NDHWC; - IE_THROW() << "The plugin does not support " << l.to_string() << " layout"; -} +OPENVINO_SUPPRESS_DEPRECATED_END /// WA: Force exit. Any opencl api call can be hang after CL_OUT_OF_RESOURCES. inline void ForceExit() { diff --git a/src/plugins/intel_gpu/include/intel_gpu/plugin/legacy_api_helper.hpp b/src/plugins/intel_gpu/include/intel_gpu/plugin/legacy_api_helper.hpp index 164bf86c73095e..b6752b56a433f8 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/plugin/legacy_api_helper.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/plugin/legacy_api_helper.hpp @@ -3,6 +3,12 @@ // #include "intel_gpu/runtime/execution_config.hpp" +#include "ie_metric_helpers.hpp" +#include +#include "ie_plugin_config.hpp" +#include "gpu/gpu_config.hpp" +#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp" +#include "ie_icore.hpp" namespace ov { namespace intel_gpu { diff --git a/src/plugins/intel_gpu/include/intel_gpu/plugin/program.hpp b/src/plugins/intel_gpu/include/intel_gpu/plugin/program.hpp index 4385708ba7db45..7976bafd6b7087 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/plugin/program.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/plugin/program.hpp @@ -31,16 +31,15 @@ enum class reduce_mode : uint16_t; enum class eltwise_mode : int32_t; } // namespace cldnn -#define REGISTER_FACTORY_IMPL(op_version, op_name) \ -void __register ## _ ## op_name ## _ ## op_version(); \ -void __register ## _ ## op_name ## _ ## op_version() { \ - Program::RegisterFactory( \ - [](Program& p, const std::shared_ptr& op) { \ - auto op_casted = std::dynamic_pointer_cast(op); \ - if (!op_casted) \ - IE_THROW() << "Invalid ov Node type passed into " << __PRETTY_FUNCTION__; \ - Create##op_name##Op(p, op_casted); \ - }); \ +#define REGISTER_FACTORY_IMPL(op_version, op_name) \ +void __register ## _ ## op_name ## _ ## op_version(); \ +void __register ## _ ## op_name ## _ ## op_version() { \ + Program::RegisterFactory( \ + [](Program& p, const std::shared_ptr& op) { \ + auto op_casted = std::dynamic_pointer_cast(op); \ + OPENVINO_ASSERT(op_casted, "[GPU] Invalid ov Node type passed into ", __PRETTY_FUNCTION__); \ + Create##op_name##Op(p, op_casted); \ + }); \ } namespace ov { @@ -84,7 +83,7 @@ class Program { Program(InferenceEngine::CNNNetwork& network, cldnn::engine& engine, const ExecutionConfig& config, bool createTopologyOnly = false, bool partialBuild = false, InferenceEngine::InputsDataMap* inputs = nullptr, InferenceEngine::OutputsDataMap* outputs = nullptr, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor = nullptr, bool innerProgram = false); + std::shared_ptr task_executor = nullptr, bool innerProgram = false); Program(cldnn::engine& engine, const ExecutionConfig& config, InferenceEngine::InputsDataMap* inputs = nullptr, InferenceEngine::OutputsDataMap* outputs = nullptr); @@ -159,7 +158,7 @@ class Program { bool use_new_shape_infer() const { return allow_new_shape_infer; } bool requires_new_shape_infer(const ngraph::Node& op) const; - InferenceEngine::CPUStreamsExecutor::Ptr get_task_executor() { return m_task_executor; } + std::shared_ptr get_task_executor() { return m_task_executor; } private: static factories_map_t factories_map; @@ -177,7 +176,7 @@ class Program { bool queryMode; - InferenceEngine::CPUStreamsExecutor::Ptr m_task_executor; + std::shared_ptr m_task_executor; void EnableQueryMode() { queryMode = true; } void DisableQueryMode() { queryMode = false; } diff --git a/src/plugins/intel_gpu/include/intel_gpu/runtime/engine.hpp b/src/plugins/intel_gpu/include/intel_gpu/runtime/engine.hpp index 16481a42595248..71b8a11a209ed5 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/runtime/engine.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/runtime/engine.hpp @@ -11,7 +11,6 @@ #include "layout.hpp" #include "execution_config.hpp" #include "engine_configuration.hpp" -#include #include #include @@ -147,7 +146,6 @@ class engine { /// Factory method which creates engine object with impl configured by @p engine_type /// @param engine_type requested engine type - /// @param task_executor GPU plugin internal task executor /// @param runtime_type requested execution runtime for the engine. @note some runtime/engine types configurations might be unsupported /// @param device specifies the device which the engine is created for /// @param configuration options for the engine @@ -156,7 +154,6 @@ class engine { /// Factory method which creates engine object with impl configured by @p engine_type /// @param engine_type requested engine type /// @param runtime_type requested execution runtime for the engine. @note some runtime/engine types configurations might be unsupported - /// @param task_executor GPU plugin internal task executor /// @param configuration options for the engine /// @note engine is created for the first device returned by devices query static std::shared_ptr create(engine_types engine_type, runtime_types runtime_type); diff --git a/src/plugins/intel_gpu/include/intel_gpu/runtime/engine_configuration.hpp b/src/plugins/intel_gpu/include/intel_gpu/runtime/engine_configuration.hpp index f03969f6ab9b7d..f3a48d4c74f96e 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/runtime/engine_configuration.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/runtime/engine_configuration.hpp @@ -4,12 +4,7 @@ #pragma once -#include "utils.hpp" - #include -#include -#include -#include namespace cldnn { diff --git a/src/plugins/intel_gpu/src/graph/arg_max_min.cpp b/src/plugins/intel_gpu/src/graph/arg_max_min.cpp index e83cba5b6c5dcc..06585294e895fd 100644 --- a/src/plugins/intel_gpu/src/graph/arg_max_min.cpp +++ b/src/plugins/intel_gpu/src/graph/arg_max_min.cpp @@ -60,7 +60,7 @@ layout arg_max_min_inst::calc_output_layout(arg_max_min_node const& node, kernel auto format = input_layout.format; auto sizes = input_layout.get_dims(); if (desc->axis >= static_cast(sizes.size()) || desc->axis < 0) { - IE_THROW() << "Incorrect arg_max_min axis."; + OPENVINO_THROW("Incorrect arg_max_min axis."); } sizes[desc->axis] = desc->top_k; return layout{output_data_type, format, tensor(format::get_default_format(input_layout.get_rank()), sizes)}; diff --git a/src/plugins/intel_gpu/src/graph/compilation_context.cpp b/src/plugins/intel_gpu/src/graph/compilation_context.cpp index 75c6b3a65b8b12..e0696e4a64271e 100644 --- a/src/plugins/intel_gpu/src/graph/compilation_context.cpp +++ b/src/plugins/intel_gpu/src/graph/compilation_context.cpp @@ -12,9 +12,9 @@ namespace cldnn { class CompilationContext : public ICompilationContext { public: - CompilationContext(InferenceEngine::CPUStreamsExecutor::Config task_executor_config) : _task_executor_config(task_executor_config) { + CompilationContext(ov::threading::IStreamsExecutor::Config task_executor_config) : _task_executor_config(task_executor_config) { _task_executor_config._streams = 4; - _task_executor = std::make_shared(_task_executor_config); + _task_executor = std::make_shared(_task_executor_config); } void push_task(size_t key, Task&& task) override { @@ -62,14 +62,14 @@ class CompilationContext : public ICompilationContext { } private: - InferenceEngine::CPUStreamsExecutor::Config _task_executor_config; - InferenceEngine::CPUStreamsExecutor::Ptr _task_executor; + ov::threading::IStreamsExecutor::Config _task_executor_config; + std::shared_ptr _task_executor; std::mutex _mutex; std::unordered_set _task_keys; std::atomic_bool _stop_compilation{false}; }; -std::unique_ptr ICompilationContext::create(InferenceEngine::CPUStreamsExecutor::Config task_executor_config) { +std::unique_ptr ICompilationContext::create(ov::threading::IStreamsExecutor::Config task_executor_config) { return cldnn::make_unique(task_executor_config); } diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/compile_graph.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/compile_graph.cpp index d219e25b9c681f..537fa7412b09f5 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/compile_graph.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/compile_graph.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include "openvino/runtime/threading/cpu_streams_executor.hpp" using namespace cldnn; @@ -35,7 +35,7 @@ void compile_graph::run(program& p) { auto task_executor = p.get_task_executor(); auto& proc_order = p.get_processing_order(); - std::vector tasks; + std::vector tasks; std::exception_ptr exception; for (size_t idx = 0; idx < proc_order.size(); idx++) { auto& node = *(std::next(proc_order.begin(), idx)); @@ -97,7 +97,7 @@ void compile_graph::run(program& p) { } } - task_executor->runAndWait(tasks); + task_executor->run_and_wait(tasks); tasks.clear(); if (exception) { diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/propagate_constants.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/propagate_constants.cpp index 1767a2c360bf48..82d01394e88729 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/propagate_constants.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/propagate_constants.cpp @@ -110,7 +110,7 @@ bool propagate_constants::has_non_const_user(program_node& node) const { std::list> propagate_constants::calculate(engine& engine, const ExecutionConfig& config, - std::shared_ptr task_executor) { + std::shared_ptr task_executor) { if (!has_non_trivial_constants) return {}; diff --git a/src/plugins/intel_gpu/src/graph/impls/common/condition.cpp b/src/plugins/intel_gpu/src/graph/impls/common/condition.cpp index c81f5e0d587724..dadd65e13889cb 100644 --- a/src/plugins/intel_gpu/src/graph/impls/common/condition.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/common/condition.cpp @@ -24,7 +24,7 @@ struct condition_impl : typed_primitive_impl { } void set_node_params(const program_node& arg) override { - IE_ASSERT(arg.is_type()); + OPENVINO_ASSERT(arg.is_type()); const auto& node = arg.as(); _node_id = node.id(); } diff --git a/src/plugins/intel_gpu/src/graph/impls/common/loop.cpp b/src/plugins/intel_gpu/src/graph/impls/common/loop.cpp index de99afaaa4d7cf..f75cc121089079 100644 --- a/src/plugins/intel_gpu/src/graph/impls/common/loop.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/common/loop.cpp @@ -35,7 +35,7 @@ struct loop_impl : typed_primitive_impl { } void set_node_params(const program_node& arg) override { - IE_ASSERT(arg.is_type()); + OPENVINO_ASSERT(arg.is_type()); const auto& node = arg.as(); _max_iteration = node.get_max_iteration(); _back_edges = node.get_back_edges(); diff --git a/src/plugins/intel_gpu/src/graph/impls/cpu/assign.cpp b/src/plugins/intel_gpu/src/graph/impls/cpu/assign.cpp index 49f16dd3c8129e..97a530eefc29f0 100644 --- a/src/plugins/intel_gpu/src/graph/impls/cpu/assign.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/cpu/assign.cpp @@ -29,7 +29,7 @@ struct assign_impl : public typed_primitive_impl { } void set_node_params(const program_node& arg) override { - IE_ASSERT(arg.is_type()); + OPENVINO_ASSERT(arg.is_type()); const auto& node = arg.as(); variable_id = node.get_primitive()->variable_id; } diff --git a/src/plugins/intel_gpu/src/graph/impls/cpu/detection_output.cpp b/src/plugins/intel_gpu/src/graph/impls/cpu/detection_output.cpp index 86428d682b3b4b..27c9f3993e8e13 100644 --- a/src/plugins/intel_gpu/src/graph/impls/cpu/detection_output.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/cpu/detection_output.cpp @@ -56,7 +56,7 @@ struct detection_output_impl : typed_primitive_impl { } void set_node_params(const program_node& arg) override { - IE_ASSERT(arg.is_type()); + OPENVINO_ASSERT(arg.is_type()); const auto& node = arg.as(); nms_type = (node.get_primitive()->decrease_label_id ? NMSType::MXNET : NMSType::CAFFE); } diff --git a/src/plugins/intel_gpu/src/graph/impls/cpu/read_value.cpp b/src/plugins/intel_gpu/src/graph/impls/cpu/read_value.cpp index e7d6085fcef7d5..d5481ac106da09 100644 --- a/src/plugins/intel_gpu/src/graph/impls/cpu/read_value.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/cpu/read_value.cpp @@ -29,7 +29,7 @@ struct read_value_impl : public typed_primitive_impl { } void set_node_params(const program_node& arg) override { - IE_ASSERT(arg.is_type()); + OPENVINO_ASSERT(arg.is_type()); const auto& node = arg.as(); variable_id = node.get_primitive()->variable_id; } diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/arg_max_min.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/arg_max_min.cpp index 8ca2f251a8f6db..fd069138083eb3 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/arg_max_min.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/arg_max_min.cpp @@ -29,7 +29,7 @@ static inline kernel_selector::argm_axis GetArgMaxMinAxis(int64_t axis, size_t r else return kernel_selector::argm_axis::X; case 4: return kernel_selector::argm_axis::X; - default: IE_THROW() << "Invalid arg_max_min axis " << axis; + default: OPENVINO_THROW("Invalid arg_max_min axis ", axis); } } diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/concatenation.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/concatenation.cpp index d44982f1b3b92f..653fecca64507d 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/concatenation.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/concatenation.cpp @@ -15,7 +15,7 @@ namespace { kernel_selector::concat_axis convert_axis(int64_t axis, size_t rank) { auto cldnn_axis = axis >= 0 ? axis : axis + static_cast(rank); if (cldnn_axis >= static_cast(rank)) - IE_THROW() << "Concatenation axis exceeds number of dimensions"; + OPENVINO_THROW("Concatenation axis exceeds number of dimensions"); // Difference in dimension ordering between IE and GPU plugin, // reverse spatial dimensions after batch and feature. @@ -33,7 +33,7 @@ kernel_selector::concat_axis convert_axis(int64_t axis, size_t rank) { case 3: return kernel_selector::concat_axis::Y; case 4: return kernel_selector::concat_axis::Z; case 5: return kernel_selector::concat_axis::W; - default: IE_THROW() << "Unsupported concatenation axis: " << axis; + default: OPENVINO_THROW("Unsupported concatenation axis: ", axis); } return kernel_selector::concat_axis::FEATURE; // shouldn't get here diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/gather.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/gather.cpp index 54f33ff1d95c31..1799fc85d58a4f 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/gather.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/gather.cpp @@ -24,7 +24,7 @@ static kernel_selector::gather_axis convert_axis(int64_t axis, size_t rank) { case -1: return kernel_selector::gather_axis::Y; case -2: return kernel_selector::gather_axis::FEATURE; case -3: return kernel_selector::gather_axis::BATCH; - default: IE_THROW() << "Unsupported gather axis: " << axis; + default: OPENVINO_THROW("Unsupported gather axis: ", axis); } } else if (rank == 5) { switch (axis) { @@ -35,7 +35,7 @@ static kernel_selector::gather_axis convert_axis(int64_t axis, size_t rank) { case -2: return kernel_selector::gather_axis::Z; case -3: return kernel_selector::gather_axis::FEATURE; case -4: return kernel_selector::gather_axis::BATCH; - default: IE_THROW() << "Unsupported gather axis: " << axis; + default: OPENVINO_THROW("Unsupported gather axis: ", axis); } } else if (rank == 6) { switch (axis) { @@ -48,10 +48,10 @@ static kernel_selector::gather_axis convert_axis(int64_t axis, size_t rank) { case -3: return kernel_selector::gather_axis::W; case -4: return kernel_selector::gather_axis::FEATURE; case -5: return kernel_selector::gather_axis::BATCH; - default: IE_THROW() << "Unsupported gather axis: " << axis; + default: OPENVINO_THROW("Unsupported gather axis: ", axis); } } else { - IE_THROW() << "Unsupported gather axis: " << axis; + OPENVINO_THROW("Unsupported gather axis: ", axis); } } diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/gather_elements.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/gather_elements.cpp index a3f2bfe131618e..9f1a21b08f1034 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/gather_elements.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/gather_elements.cpp @@ -38,7 +38,7 @@ static inline kernel_selector::gather_elements_axis convert_axis(int64_t axis, s else return kernel_selector::gather_elements_axis::X; case 5: return kernel_selector::gather_elements_axis::X; - default: IE_THROW() << "Incorrect gather_elements axis."; + default: OPENVINO_THROW("Incorrect gather_elements axis."); } } diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/softmax.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/softmax.cpp index a3757ce3f5a147..b4029ac3b3b3ea 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/softmax.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/softmax.cpp @@ -29,7 +29,7 @@ static inline kernel_selector::softmax_dim get_softmax_dim(int64_t axis, size_t else return kernel_selector::softmax_dim::X; case 4: return kernel_selector::softmax_dim::X; - default: IE_THROW() << "Invalid softmax axis " << axis; + default: OPENVINO_THROW("Invalid softmax axis ", axis); } } diff --git a/src/plugins/intel_gpu/src/graph/include/compilation_context.hpp b/src/plugins/intel_gpu/src/graph/include/compilation_context.hpp index f26aa904004630..cb117c4c954d05 100644 --- a/src/plugins/intel_gpu/src/graph/include/compilation_context.hpp +++ b/src/plugins/intel_gpu/src/graph/include/compilation_context.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include "openvino/runtime/threading/cpu_streams_executor.hpp" #include #include @@ -19,7 +19,7 @@ class ICompilationContext { virtual bool is_stopped() = 0; virtual void cancel() = 0; - static std::unique_ptr create(InferenceEngine::CPUStreamsExecutor::Config task_executor_config); + static std::unique_ptr create(ov::threading::IStreamsExecutor::Config task_executor_config); }; } // namespace cldnn diff --git a/src/plugins/intel_gpu/src/graph/include/pass_manager.h b/src/plugins/intel_gpu/src/graph/include/pass_manager.h index e637b4baa52056..2ea466764d5131 100644 --- a/src/plugins/intel_gpu/src/graph/include/pass_manager.h +++ b/src/plugins/intel_gpu/src/graph/include/pass_manager.h @@ -254,7 +254,7 @@ class propagate_constants : public base_pass { void run(program& p) override; std::list> calculate(engine& engine, const ExecutionConfig& config, - std::shared_ptr task_executor); + std::shared_ptr task_executor); bool has_non_const_user(program_node& node) const; void handle_constant(program& prog, program_node& node); void add_constant(program& prog, program_node& node); diff --git a/src/plugins/intel_gpu/src/graph/network.cpp b/src/plugins/intel_gpu/src/graph/network.cpp index 484b2766295a3e..54c280f57d627e 100644 --- a/src/plugins/intel_gpu/src/graph/network.cpp +++ b/src/plugins/intel_gpu/src/graph/network.cpp @@ -353,13 +353,13 @@ network::network(engine& engine, const topology& topo, const ExecutionConfig& config, bool is_internal, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor) + std::shared_ptr task_executor) : network(program::build_program(engine, topo, config, task_executor, is_internal), config, engine.create_stream(config), is_internal) {} network::network(engine& engine, const std::set>& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal) : network(program::build_program(engine, nodes, config, task_executor, is_internal), config, engine.create_stream(config), is_internal) {} @@ -674,7 +674,7 @@ network::ptr network::allocate_network(engine& engine, program::ptr program, boo network::ptr network::build_network(engine& engine, const topology& topology, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal) { return std::make_shared(engine, topology, config, is_internal, task_executor); } @@ -682,7 +682,7 @@ network::ptr network::build_network(engine& engine, network::ptr network::build_network(engine& engine, const std::set>& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal) { return std::make_shared(engine, nodes, config, task_executor, is_internal); } diff --git a/src/plugins/intel_gpu/src/graph/primitive_inst.cpp b/src/plugins/intel_gpu/src/graph/primitive_inst.cpp index becfcc45c084c0..78940db3d30cfb 100644 --- a/src/plugins/intel_gpu/src/graph/primitive_inst.cpp +++ b/src/plugins/intel_gpu/src/graph/primitive_inst.cpp @@ -1525,7 +1525,7 @@ int32_t primitive_inst::get_index_in_deps(memory::cptr arg) const { return idx; } - IE_THROW() << "[get_index_in_deps]: not found in _deps"; + OPENVINO_THROW("[get_index_in_deps]: not found in _deps"); } void primitive_inst::load(cldnn::BinaryInputBuffer& ib) { diff --git a/src/plugins/intel_gpu/src/graph/program.cpp b/src/plugins/intel_gpu/src/graph/program.cpp index 6bc1c56266c47a..9e1317fca48aa6 100644 --- a/src/plugins/intel_gpu/src/graph/program.cpp +++ b/src/plugins/intel_gpu/src/graph/program.cpp @@ -104,7 +104,7 @@ using namespace cldnn; using namespace ov::intel_gpu; -static void adjust_num_cores(InferenceEngine::CPUStreamsExecutor::Config& config) { +static void adjust_num_cores(ov::threading::IStreamsExecutor::Config& config) { if (InferenceEngine::getAvailableCoresTypes().size() == 1) { return; } @@ -115,23 +115,23 @@ static void adjust_num_cores(InferenceEngine::CPUStreamsExecutor::Config& config auto core_type = config._threadPreferredCoreType; int num_cores = total_num_cores; - if (core_type == InferenceEngine::IStreamsExecutor::Config::BIG) { + if (core_type == ov::threading::IStreamsExecutor::Config::BIG) { num_cores = total_num_big_cores; - } else if (core_type == InferenceEngine::IStreamsExecutor::Config::LITTLE) { + } else if (core_type == ov::threading::IStreamsExecutor::Config::LITTLE) { num_cores = total_num_little_cores; } config._streams = std::min(config._streams, num_cores); } -static InferenceEngine::CPUStreamsExecutor::Config make_task_executor_config(const ExecutionConfig& config, std::string tags) { - InferenceEngine::CPUStreamsExecutor::Config task_executor_config(tags, 1); +static ov::threading::IStreamsExecutor::Config make_task_executor_config(const ExecutionConfig& config, std::string tags) { + ov::threading::IStreamsExecutor::Config task_executor_config(tags, 1); task_executor_config._streams = config.get_property(ov::compilation_num_threads); auto priority = config.get_property(ov::intel_gpu::hint::host_task_priority); switch (priority) { - case ov::hint::Priority::LOW: task_executor_config._threadPreferredCoreType = InferenceEngine::IStreamsExecutor::Config::LITTLE; break; - case ov::hint::Priority::MEDIUM: task_executor_config._threadPreferredCoreType = InferenceEngine::IStreamsExecutor::Config::ANY; break; - case ov::hint::Priority::HIGH: task_executor_config._threadPreferredCoreType = InferenceEngine::IStreamsExecutor::Config::BIG; break; + case ov::hint::Priority::LOW: task_executor_config._threadPreferredCoreType = ov::threading::IStreamsExecutor::Config::LITTLE; break; + case ov::hint::Priority::MEDIUM: task_executor_config._threadPreferredCoreType = ov::threading::IStreamsExecutor::Config::ANY; break; + case ov::hint::Priority::HIGH: task_executor_config._threadPreferredCoreType = ov::threading::IStreamsExecutor::Config::BIG; break; default: OPENVINO_ASSERT(false, "[GPU] Can't create task executor: invalid host task priority value: ", priority); } @@ -140,15 +140,15 @@ static InferenceEngine::CPUStreamsExecutor::Config make_task_executor_config(con return task_executor_config; } -std::shared_ptr program::make_task_executor(const ExecutionConfig& config) { - InferenceEngine::CPUStreamsExecutor::Config task_executor_config = make_task_executor_config(config, "CPU Tasks executor for GPU plugin"); - return std::make_shared(task_executor_config); +std::shared_ptr program::make_task_executor(const ExecutionConfig& config) { + ov::threading::IStreamsExecutor::Config task_executor_config = make_task_executor_config(config, "CPU Tasks executor for GPU plugin"); + return std::make_shared(task_executor_config); } program::program(engine& engine_ref, topology const& topology, const ExecutionConfig& config, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor, + std::shared_ptr task_executor, bool is_internal, bool no_optimizations, bool is_body_program) @@ -175,7 +175,7 @@ program::program(engine& engine_ref, program::program(engine& engine_ref, std::set> const& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal) : _engine(engine_ref), _stream(_engine.create_stream(config)), @@ -246,7 +246,7 @@ kernels_cache& program::get_kernels_cache() const { program::ptr program::build_program(engine& engine, const topology& topology, const ExecutionConfig& config, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor, + std::shared_ptr task_executor, bool is_internal, bool no_optimizations, bool is_body_program) { @@ -265,7 +265,7 @@ program::ptr program::build_program(engine& engine, program::ptr program::build_program(engine& engine, const std::set>& nodes, const ExecutionConfig& config, - std::shared_ptr task_executor, + std::shared_ptr task_executor, bool is_internal) { return std::make_shared(engine, nodes, config, task_executor, is_internal); } diff --git a/src/plugins/intel_gpu/src/graph/program_node.cpp b/src/plugins/intel_gpu/src/graph/program_node.cpp index a6c0c7b5f975aa..6b33d8278e46e1 100644 --- a/src/plugins/intel_gpu/src/graph/program_node.cpp +++ b/src/plugins/intel_gpu/src/graph/program_node.cpp @@ -987,8 +987,8 @@ void program_node::init_onednn_primitive_attributes() { } else { dnnl::algorithm alg = onednn::convert_activation_func(fused_desc->activation_function); if (alg == dnnl::algorithm::undef) - IE_THROW() << "Activations that are undef algorithms must be converted to other activations before " - "pushing to post-op."; + OPENVINO_THROW("Activations that are undef algorithms must be converted to other activations before " + "pushing to post-op."); // Usage of alpha and beta between cldnn::pow and dnnl::eltwise::pow is different : d = pow(src, a) / d = a * pow(src, b) if (alg == dnnl::algorithm::eltwise_pow) post_ops.append_eltwise(alg, 1.0f, fused_desc->additional_params.a); diff --git a/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp b/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp index e653da1859c3c7..fe6ffe80088e35 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp @@ -1741,8 +1741,7 @@ JitConstants FusedOpsCodeGenerator::MakeOpJitConstants(const FusedOpsConfigurati if (desc.GetType() == KernelType::ELTWISE) { auto p = desc.GetOpParams(); - if (!p) - IE_THROW() << "[clDNN] Eltwise fuse params can't be nullptr"; + OPENVINO_ASSERT(p != nullptr, "[GPU] Eltwise fuse params can't be nullptr"); if (p->mode == kernel_selector::EltwiseMode::DIV) { if (p->m_pythondiv) diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernels/convert_color/convert_color_kernel_base.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernels/convert_color/convert_color_kernel_base.cpp index a38c677b24cca2..971728f3acd399 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernels/convert_color/convert_color_kernel_base.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernels/convert_color/convert_color_kernel_base.cpp @@ -47,7 +47,7 @@ JitConstants ConvertColorKernelBase::GetJitConstants(const convert_color_params& jit.AddConstant(MakeJitConstant("CONVERT_FROM_I420", "")); break; default: - IE_THROW() << "Not supported input color format"; + OPENVINO_THROW("Not supported input color format"); } switch (params.output_color_format) { @@ -58,7 +58,7 @@ JitConstants ConvertColorKernelBase::GetJitConstants(const convert_color_params& jit.AddConstant(MakeJitConstant("CONVERT_TO_BGR", "")); break; default: - IE_THROW() << "Not supported output color format"; + OPENVINO_THROW("Not supported output color format"); } switch (params.mem_type) { @@ -69,7 +69,7 @@ JitConstants ConvertColorKernelBase::GetJitConstants(const convert_color_params& jit.AddConstant(MakeJitConstant("SURFACE_MEM", "")); break; default: - IE_THROW() << "Not supported memory type"; + OPENVINO_THROW("Not supported memory type"); } return jit; } diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernels/eltwise/eltwise_kernel_blocked_opt.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernels/eltwise/eltwise_kernel_blocked_opt.cpp index 0ef8692bb348c2..d1381d41a8bb4a 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernels/eltwise/eltwise_kernel_blocked_opt.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernels/eltwise/eltwise_kernel_blocked_opt.cpp @@ -189,7 +189,7 @@ JitConstants EltwiseKernel_blocked_opt::MakeLoadJitConstants(const eltwise_param else if (DataTensor::ChannelsCount(params.inputs[input_idx].GetLayout()) == 5) default_indexing_str = "b, (f_block * " + toCodeString(vec_size) +"), z, y, x"; else - IE_ASSERT("MakeLoadJit : Unexpected dimension for eltwise optimized kernel."); + OPENVINO_ASSERT("MakeLoadJit : Unexpected dimension for eltwise optimized kernel."); // Generate Jit switch (input.mode) { @@ -439,7 +439,7 @@ static inline int GetInnerBatchBlockSize(const DataTensor& tensor) { case DataLayout::bs_fs_zyx_bsv32_fsv16: return 32; default: - IE_ASSERT("GetInnerBatchBlockSize : Unexpected format for eltwise_blocked_optimized kernel."); + OPENVINO_ASSERT("GetInnerBatchBlockSize : Unexpected format for eltwise_blocked_optimized kernel."); } return 1; @@ -465,7 +465,7 @@ static inline int GetInnerFeatureBlockSize(const DataTensor& tensor) { case DataLayout::bs_fs_zyx_bsv16_fsv32: return 32; default: - IE_ASSERT("GetInnerFeatureBlockSize : Unexpected format for eltwise_blocked_optimized kernel."); + OPENVINO_ASSERT("GetInnerFeatureBlockSize : Unexpected format for eltwise_blocked_optimized kernel."); } return 1; diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernels/gather/gather_kernel_ref.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernels/gather/gather_kernel_ref.cpp index 72c864f217972e..538c4fcfb4e15f 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernels/gather/gather_kernel_ref.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernels/gather/gather_kernel_ref.cpp @@ -105,7 +105,7 @@ static inline Tensor::Dim GetGatherIndexDim(const gather_params& params) { case GatherAxis::X: return params.inputs[0].X(); default: - IE_THROW() << "Unknown gather axis=" << static_cast(params.axis); + OPENVINO_THROW("Unknown gather axis=", static_cast(params.axis)); } } @@ -124,7 +124,7 @@ static inline int64_t GetGatherAxisIndexInShapeInfo(const gather_params& params) case GatherAxis::X: return 7; default: - IE_THROW() << "Unknown gather axis=" << static_cast(params.axis); + OPENVINO_THROW("Unknown gather axis=", static_cast(params.axis)); } } @@ -224,7 +224,7 @@ CommonDispatchData GatherKernelRef::SetDefault(const gather_params& params) cons {Tensor::DataChannelName::Z, Tensor::DataChannelName::W}, {Tensor::DataChannelName::FEATURE, Tensor::DataChannelName::BATCH}}; } else { - IE_THROW() << "Unknown rank: rank=" << rank; + OPENVINO_THROW("Unknown rank: rank=", rank); } dispatchData.lws = diff --git a/src/plugins/intel_gpu/src/plugin/compiled_model.cpp b/src/plugins/intel_gpu/src/plugin/compiled_model.cpp index fe09e450df9e8f..d4229c3c879ec9 100644 --- a/src/plugins/intel_gpu/src/plugin/compiled_model.cpp +++ b/src/plugins/intel_gpu/src/plugin/compiled_model.cpp @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "ie_metric_helpers.hpp" +#include "intel_gpu/plugin/legacy_api_helper.hpp" + +#include "openvino/runtime/intel_gpu/properties.hpp" + #include "intel_gpu/graph/serialization/binary_buffer.hpp" #include "intel_gpu/graph/serialization/layout_serializer.hpp" #include "intel_gpu/graph/serialization/string_serializer.hpp" @@ -14,10 +17,7 @@ #include "intel_gpu/plugin/compiled_model.hpp" #include "intel_gpu/plugin/async_infer_request.hpp" #include "intel_gpu/plugin/async_infer_request_legacy.hpp" -#include "intel_gpu/plugin/legacy_api_helper.hpp" -#include "openvino/runtime/intel_gpu/properties.hpp" -#include #include #include "threading/ie_cpu_streams_executor.hpp" #include "cpp_interfaces/interface/ie_internal_plugin_config.hpp" @@ -143,16 +143,16 @@ IInferRequestInternal::Ptr CompiledModel::CreateInferRequest() { OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::CreateInferRequest"); InferenceEngine::IInferRequestInternal::Ptr internalRequest; if (m_graphs.empty()) { - IE_THROW(NetworkNotLoaded); + OPENVINO_THROW("[GPU] Model not loaded"); } for (auto& graph : m_graphs) { if (graph == nullptr) { - IE_THROW(NetworkNotLoaded); + OPENVINO_THROW("[GPU] Model not loaded"); } if (!graph->IsLoaded()) { - IE_THROW(NetworkNotLoaded) << ": no networks created"; + OPENVINO_THROW("[GPU] Model not loaded: no networks created"); } } @@ -186,7 +186,7 @@ IInferRequestInternal::Ptr CompiledModel::CreateInferRequest() { void CompiledModel::Export(std::ostream& networkModel) { OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::Export"); if (m_graphs.empty()) - IE_THROW(NetworkNotLoaded); + OPENVINO_THROW("[GPU] Model not loaded"); cldnn::BinaryOutputBuffer ob(networkModel); @@ -286,7 +286,7 @@ void CompiledModel::Export(std::ostream& networkModel) { std::shared_ptr CompiledModel::GetExecGraphInfo() { if (m_graphs.empty()) - IE_THROW(NetworkNotLoaded); + OPENVINO_THROW("[GPU] Model not loaded"); return m_graphs.front()->GetExecGraphInfo(); } @@ -331,7 +331,7 @@ InferenceEngine::Parameter CompiledModel::GetMetric(const std::string &name) con ov::PropertyName{ov::execution_devices.name(), PropertyMutability::RO} }; } else if (name == ov::model_name) { - IE_ASSERT(!m_graphs.empty()); + OPENVINO_ASSERT(!m_graphs.empty()); return decltype(ov::model_name)::value_type {m_graphs[0]->getName()}; } else if (name == METRIC_KEY(SUPPORTED_METRICS)) { std::vector metrics; @@ -367,7 +367,7 @@ InferenceEngine::Parameter CompiledModel::GetMetric(const std::string &name) con } else if (name == ov::execution_devices) { return decltype(ov::execution_devices)::value_type{m_context->getDeviceName()}; } else { - IE_THROW() << "Unsupported ExecutableNetwork metric: " << name; + OPENVINO_THROW("[GPU] Unsupported CompiledModel property: ", name); } } diff --git a/src/plugins/intel_gpu/src/plugin/custom_layer.cpp b/src/plugins/intel_gpu/src/plugin/custom_layer.cpp index ca07172dbb1737..f8eea3e5007aad 100644 --- a/src/plugins/intel_gpu/src/plugin/custom_layer.cpp +++ b/src/plugins/intel_gpu/src/plugin/custom_layer.cpp @@ -237,8 +237,7 @@ void CustomLayer::LoadFromFile(const std::string configFile, CustomLayerMap& cus // config file might not exist - like global config, for example return; } else { - IE_THROW() << "Error loading custom layer configuration file: " << configFile << ", " << res.description() - << " at offset " << res.offset; + OPENVINO_THROW("Error loading custom layer configuration file: ", configFile, ", ", res.description(), " at offset ", res.offset); } } @@ -252,8 +251,7 @@ void CustomLayer::LoadFromFile(const std::string configFile, CustomLayerMap& cus #error "Intel GPU plugin: unknown target system" #endif if (abs_path_ptr == nullptr) { - IE_THROW() << "Error loading custom layer configuration file: " << configFile << ", " - << "Can't get canonicalized absolute pathname."; + OPENVINO_THROW("Error loading custom layer configuration file: ", configFile, ", ", "Can't get canonicalized absolute pathname."); } std::string abs_file_name(path); @@ -268,8 +266,7 @@ void CustomLayer::LoadFromFile(const std::string configFile, CustomLayerMap& cus // path is absolute dir_path = abs_file_name.substr(0, dir_split_pos); } else { - IE_THROW() << "Error loading custom layer configuration file: " << configFile << ", " - << "Path is not valid"; + OPENVINO_THROW("Error loading custom layer configuration file: ", configFile, ", ", "Path is not valid"); } for (auto r = xmlDoc.document_element(); r; r = r.next_sibling()) { @@ -277,7 +274,7 @@ void CustomLayer::LoadFromFile(const std::string configFile, CustomLayerMap& cus layer->LoadSingleLayer(r); if (layer->Error()) { customLayers.clear(); - IE_THROW() << layer->m_ErrorMessage; + OPENVINO_THROW(layer->m_ErrorMessage); } else { customLayers[layer->Name()] = layer; } diff --git a/src/plugins/intel_gpu/src/plugin/graph.cpp b/src/plugins/intel_gpu/src/plugin/graph.cpp index 056753ebcf2d24..487421680c924f 100644 --- a/src/plugins/intel_gpu/src/plugin/graph.cpp +++ b/src/plugins/intel_gpu/src/plugin/graph.cpp @@ -11,17 +11,13 @@ #include "intel_gpu/graph/serialization/vector_serializer.hpp" #include "intel_gpu/runtime/profiling.hpp" #include "intel_gpu/runtime/debug_configuration.hpp" - +#include "intel_gpu/runtime/itt.hpp" #include "intel_gpu/plugin/graph.hpp" #include "intel_gpu/plugin/simple_math.hpp" #include "intel_gpu/plugin/infer_request.hpp" -#include "intel_gpu/runtime/itt.hpp" - -#include -#include -#include -#include +#include "openvino/runtime/threading/executor_manager.hpp" +#include "openvino/runtime/exec_model_info.hpp" #include #include @@ -34,9 +30,6 @@ #include #include #include -#include -#include -#include using namespace InferenceEngine; using namespace InferenceEngine::details; @@ -74,7 +67,7 @@ Graph::Graph(cldnn::BinaryInputBuffer &ib, RemoteContextImpl::Ptr context, const #ifdef ENABLE_ONEDNN_FOR_GPU get_engine().create_onednn_engine(config); #else - IE_THROW() << "[GPU] Current model cache requires OneDNN, but cannot use it."; + OPENVINO_THROW("[GPU] Current model cache requires OneDNN, but cannot use it."); #endif // ENABLE_ONEDNN_FOR_GPU } @@ -178,7 +171,7 @@ std::shared_ptr Graph::BuildNetwork(std::shared_ptrget_external_queue(); if (externalQueue) { if (m_config.get_property(ov::num_streams) != 1) - IE_THROW(ParameterMismatch) << "Throughput streams can't be used with shared queue!\n"; + OPENVINO_THROW("Throughput streams can't be used with shared queue!\n"); auto &engine = m_program->get_engine(); network = std::make_shared(program, engine.create_stream(m_config, externalQueue), m_stream_id); } else { @@ -375,7 +368,7 @@ std::shared_ptr Graph::GetExecGraphInfoByPrimitivesInfo(std::v params.push_back(param); return_node = param; } else { - return_node = std::make_shared(get_inputs(prim_info), output_size); + return_node = std::make_shared(get_inputs(prim_info), output_size); if (is_output) { // create additional result node nodes.push_back(return_node); @@ -405,12 +398,12 @@ std::shared_ptr Graph::GetExecGraphInfoByPrimitivesInfo(std::v std::map info; Precision prec = data_type_to_precision(prim_info.output_layout.data_type); Precision inference_precision = data_type_to_precision(prim_info.runtime_precision); - info[ExecGraphInfoSerialization::OUTPUT_PRECISIONS] = prec.name(); - info[ExecGraphInfoSerialization::LAYER_TYPE] = to_IE_type_name(prim_info.type_id); - info[ExecGraphInfoSerialization::OUTPUT_LAYOUTS] = prim_info.layout_str; - info[ExecGraphInfoSerialization::EXECUTION_ORDER] = std::to_string(prim_info.exec_id); - info[ExecGraphInfoSerialization::IMPL_TYPE] = prim_info.kernel_id; - info[ExecGraphInfoSerialization::RUNTIME_PRECISION] = inference_precision.name(); + info[ov::exec_model_info::OUTPUT_PRECISIONS] = prec.name(); + info[ov::exec_model_info::LAYER_TYPE] = to_IE_type_name(prim_info.type_id); + info[ov::exec_model_info::OUTPUT_LAYOUTS] = prim_info.layout_str; + info[ov::exec_model_info::EXECUTION_ORDER] = std::to_string(prim_info.exec_id); + info[ov::exec_model_info::IMPL_TYPE] = prim_info.kernel_id; + info[ov::exec_model_info::RUNTIME_PRECISION] = inference_precision.name(); std::vector originalNames{find_origin_layers(prim_info.original_id)}; for (auto& fused_id : prim_info.c_fused_ids) { @@ -419,7 +412,7 @@ std::shared_ptr Graph::GetExecGraphInfoByPrimitivesInfo(std::v originalNames.push_back(origin_id); } } - info[ExecGraphInfoSerialization::ORIGINAL_NAMES] = concat_strings(originalNames, ','); + info[ov::exec_model_info::ORIGINAL_NAMES] = concat_strings(originalNames, ','); std::string exec_time = "not_executed"; if (perfMap.find(prim_info.original_id) != perfMap.end()) { @@ -428,7 +421,7 @@ std::shared_ptr Graph::GetExecGraphInfoByPrimitivesInfo(std::v exec_time = std::to_string(perfCounter.realTime_avg()); } } - info[ExecGraphInfoSerialization::PERF_COUNTER] = exec_time; + info[ov::exec_model_info::PERF_COUNTER] = exec_time; for (auto&& kvp : info) { return_node->get_rt_info()[kvp.first] = kvp.second; @@ -436,7 +429,7 @@ std::shared_ptr Graph::GetExecGraphInfoByPrimitivesInfo(std::v results.back()->get_rt_info()[kvp.first] = kvp.second; } if (is_output) - results.back()->get_rt_info()[ExecGraphInfoSerialization::LAYER_TYPE] = "Result"; + results.back()->get_rt_info()[ov::exec_model_info::LAYER_TYPE] = "Result"; nodes.push_back(return_node); node2layer[prim_info.original_id] = return_node; @@ -824,7 +817,7 @@ std::map Graph::GetPer std::shared_ptr Graph::GetNetwork(size_t idx) const { if (idx >= GetNetworksCount()) - IE_THROW() << "Unable to find network with id=" << idx << ". Stored networks count: " << GetNetworksCount(); + OPENVINO_THROW("Unable to find network with id=", idx, ". Stored networks count: ", GetNetworksCount()); return m_networks[idx]; } @@ -836,18 +829,18 @@ std::string Graph::MapOutputName(std::string outName) const { // Find correct output ID. Start with name stored in IR. if (primitiveIDs.find(outName) == primitiveIDs.end()) { - IE_THROW() << "output with name " << outName << " was not found in primitiveIDs"; + OPENVINO_THROW("output with name ", outName, " was not found in primitiveIDs"); } std::string outputID = primitiveIDs.at(outName); while (std::find(networkOutputsIDs.begin(), networkOutputsIDs.end(), outputID) == networkOutputsIDs.end()) { // If current ID isn't found in cldnn network outputs, get previous primitive id and try again. auto prim = allPrimitiveIds.find(outputID); if (prim == allPrimitiveIds.end()) { - IE_THROW() << "Unknown primitive id " << outputID; + OPENVINO_THROW("Unknown primitive id ", outputID); } if (prevPrimitiveIDs.at(outputID).size() != 1 || prim->second != "_optimized_") { - IE_THROW() << "Unable to find parent for output primitive " << outputID; + OPENVINO_THROW("Unable to find parent for output primitive ", outputID); } outputID = prevPrimitiveIDs.at(outputID)[0]; } diff --git a/src/plugins/intel_gpu/src/plugin/infer_request.cpp b/src/plugins/intel_gpu/src/plugin/infer_request.cpp index 4d8b38f84aceed..22e5defe3ec383 100644 --- a/src/plugins/intel_gpu/src/plugin/infer_request.cpp +++ b/src/plugins/intel_gpu/src/plugin/infer_request.cpp @@ -7,17 +7,14 @@ #include #include #include -#include #include "intel_gpu/plugin/infer_request.hpp" #include "intel_gpu/plugin/remote_context.hpp" #include "intel_gpu/plugin/remote_allocators.hpp" #include "intel_gpu/plugin/compiled_model.hpp" -#include "intel_gpu/runtime/itt.hpp" #include "intel_gpu/plugin/variable_state.hpp" +#include "intel_gpu/runtime/itt.hpp" #include "intel_gpu/runtime/debug_configuration.hpp" #include "openvino/core/preprocess/input_tensor_info.hpp" -#include -#include "ie_ngraph_utils.hpp" #include using namespace InferenceEngine; @@ -35,13 +32,12 @@ void convertAndCopy(const InferenceEngine::Blob* src, dst_t* dst) { } auto t_blob = dynamic_cast*>(src); if (!t_blob) { - IE_THROW() << "input type is " << src->getTensorDesc().getPrecision() << " but input is not " - << typeid(src_t).name(); + OPENVINO_THROW("input type is ", src->getTensorDesc().getPrecision(), " but input is not ", typeid(src_t).name()); } const src_t* srcPtr = t_blob->readOnly(); if (!srcPtr) { - IE_THROW(NotAllocated) << str_input_not_allocated; + OPENVINO_THROW(str_input_not_allocated); } for (size_t i = 0; i < t_blob->size(); i++) dst[i] = srcPtr[i]; @@ -88,7 +84,7 @@ inline void checkAlloc(const Blob::Ptr& blob, const std::string& err_str) { not_allocated = !ov::intel_gpu::getBlobImpl(blob->as())->is_allocated(); } if (not_allocated) { - IE_THROW(NotAllocated) << err_str; + OPENVINO_THROW(err_str); } } @@ -98,7 +94,7 @@ void checkInputBlob(const Blob::Ptr &blob, const std::string strNotMatched("The input blob size is not equal to the network input size"); if (!blob) { - IE_THROW(NotAllocated) << str_input_not_allocated; + OPENVINO_THROW(str_input_not_allocated); } SizeVector dims = foundInput->getTensorDesc().getDims(); @@ -107,7 +103,7 @@ void checkInputBlob(const Blob::Ptr &blob, : 1; if (refSize != blob->size()) { - IE_THROW() << strNotMatched + ": got " << blob->size() << " expecting " << refSize; + OPENVINO_THROW(strNotMatched + ": got ", blob->size(), " expecting ", refSize); } checkAlloc(blob, str_input_not_allocated); @@ -119,7 +115,7 @@ void checkOutputBlob(const Blob::Ptr &blob, const std::string strNotMatched("The output blob size is not equal to the network output size"); if (!blob) { - IE_THROW(NotAllocated) << str_output_not_allocated; + OPENVINO_THROW(str_output_not_allocated); } SizeVector dims = foundOutput->getTensorDesc().getDims(); size_t refSize = foundOutput->getTensorDesc().getLayout() != SCALAR @@ -127,7 +123,7 @@ void checkOutputBlob(const Blob::Ptr &blob, : 1; if (refSize != blob->size()) { - IE_THROW() << strNotMatched + ": got " << blob->size() << " expecting " << refSize; + OPENVINO_THROW(strNotMatched + ": got ", blob->size(), " expecting ", refSize); } checkAlloc(blob, str_output_not_allocated); @@ -175,10 +171,10 @@ void InferRequest::SetBlob(const std::string& name, const Blob::Ptr& data) { // perform all common checks first if (name.empty()) { - IE_THROW(NotFound) << "Failed to set blob with empty name"; + OPENVINO_THROW("Failed to set blob with empty name"); } if (!data) - IE_THROW(NotAllocated) << "Failed to set empty blob with name: \'" << name << "\'"; + OPENVINO_THROW("Failed to set empty blob with name: \'", name, "\'"); if (inputTensorsMap.find(name) != inputTensorsMap.end()) { inputTensorsMap.erase(name); @@ -194,8 +190,7 @@ void InferRequest::SetBlob(const std::string& name, const Blob::Ptr& data) { : foundOutput->getTensorDesc(); if (desc.getPrecision() != blobDesc.getPrecision()) { - IE_THROW(ParameterMismatch) << "Failed to set Blob with precision not corresponding to user " - << (is_input ? "input" : "output") << " precision"; + OPENVINO_THROW("Failed to set Blob with precision not corresponding to user ", (is_input ? "input" : "output"), " precision"); } size_t netReqBinSize = std::accumulate(desc.getDims().begin(), desc.getDims().end(), @@ -206,14 +201,14 @@ void InferRequest::SetBlob(const std::string& name, const Blob::Ptr& data) { size_t dataSize = data->size(); if (0 == dataSize && !isDynamic) { - IE_THROW() << "Input data is empty. Input name: \'" << name << "\'"; + OPENVINO_THROW("Input data is empty. Input name: \'", name, "\'"); } size_t dataBinSize = dataSize * data->element_size(); if (!isDynamic && dataBinSize != netReqBinSize) { - IE_THROW() << "Incorrect binary data size for " << (is_input ? "input" : "output") << - " blob with name: \'" << name << "\' " << - "Current: " << dataBinSize << " Required: " << netReqBinSize; + OPENVINO_THROW("Incorrect binary data size for ", (is_input ? "input" : "output"), + " blob with name: \'", name, "\' ", + "Current: ", dataBinSize, " Required: ", netReqBinSize); } if (is_input) { @@ -248,7 +243,7 @@ void InferRequest::set_output(const std::string& name, const Blob::Ptr& data) { } else { if (!isDynamic) { if (data->buffer() == nullptr) - IE_THROW(NotAllocated) << str_output_not_allocated << " Output name: \'" << name << "\'"; + OPENVINO_THROW(str_output_not_allocated, " Output name: \'", name, "\'"); } } _outputs[name] = data; @@ -261,16 +256,16 @@ void InferRequest::SetBlobs(const std::string& name, const std::vectorsize() == 0; }); if (empty_data) { - IE_THROW() << "At least one of the input blobs is empty. Input name: \'" << name << "\'"; + OPENVINO_THROW("At least one of the input blobs is empty. Input name: \'", name, "\'"); } bool is_buffer = std::all_of(blobs.begin(), blobs.end(), [](const Blob::Ptr& blob) { @@ -287,7 +282,7 @@ void InferRequest::SetBlobs(const std::string& name, const std::vectorgetTensorDesc(); @@ -305,8 +300,7 @@ void InferRequest::SetBlobs(const std::string& name, const std::vector()); if (dataBinSize != netReqBinSize) { - IE_THROW() << "Incorrect binary data size for input blobs with name: \'" << name << "\' " << - "Current: " << dataBinSize << " Required: " << netReqBinSize; + OPENVINO_THROW("Incorrect binary data size for input blobs with name: \'", name, "\' ", "Current: ", dataBinSize, " Required: ", netReqBinSize); } if (is_surface) { @@ -337,7 +331,7 @@ void InferRequest::checkBlobs() { if (foundInputPair != std::end(_networkInputs)) { foundInput = foundInputPair->second; } else { - IE_THROW(NotFound) << "Failed to find input with name: \'" << input.first << "\'"; + OPENVINO_THROW("Failed to find input with name: \'", input.first, "\'"); } auto node = findInputByNodeName(input.first); bool is_dynamic = (node && node->get_output_partial_shape(0).is_dynamic()); @@ -353,7 +347,7 @@ void InferRequest::checkBlobs() { if (foundOutputPair != std::end(_networkOutputs)) { foundOutput = foundOutputPair->second; } else { - IE_THROW(NotFound) << "Failed to find output with name: \'" << output.first << "\'"; + OPENVINO_THROW("Failed to find output with name: \'", output.first, "\'"); } auto node = findOutputByNodeName(output.first); bool is_dynamic = (node && node->get_output_partial_shape(0).is_dynamic()); @@ -366,9 +360,7 @@ void InferRequest::SetGraph(std::shared_ptr graph) { OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "InferRequest::SetGraph"); m_graph = graph; - if (m_graph == nullptr) { - IE_THROW(NetworkNotLoaded); - } + OPENVINO_ASSERT(m_graph != nullptr, "[GPU] Model not loaded"); allocate_inputs(); allocate_outputs(); @@ -378,7 +370,7 @@ void InferRequest::SetGraph(std::shared_ptr graph) { InferRequest::InferRequest(InputsDataMap networkInputs, OutputsDataMap networkOutputs, const CompiledModel::Ptr& execNetwork) : IInferRequestInternal(networkInputs, networkOutputs) { - IE_ASSERT(nullptr != execNetwork); + OPENVINO_ASSERT(nullptr != execNetwork); streamExecutor = dynamic_cast(execNetwork->m_taskExecutor.get()); m_context = std::dynamic_pointer_cast(execNetwork->GetContext()); OPENVINO_ASSERT(m_context != nullptr, "[GPU] Can't initialize context of InferRequest: wrong context type"); @@ -388,7 +380,7 @@ InferRequest::InferRequest(const std::vector>& i const std::vector>& outputs, const CompiledModel::Ptr& execNetwork) : IInferRequestInternal(inputs, outputs) { - IE_ASSERT(nullptr != execNetwork); + OPENVINO_ASSERT(nullptr != execNetwork); streamExecutor = dynamic_cast(execNetwork->m_taskExecutor.get()); m_context = std::dynamic_pointer_cast(execNetwork->GetContext()); OPENVINO_ASSERT(m_context != nullptr, "[GPU] Can't initialize context of InferRequest: wrong context type"); @@ -490,7 +482,7 @@ void InferRequest::wait_notify() { void InferRequest::wait() { if (internal_outputs.empty()) { - IE_THROW() << "Inference was not started!\n"; + OPENVINO_THROW("Inference was not started!\n"); } // wait for completion & collect outputs as requested by the model for (auto& no : _networkOutputs) { @@ -519,7 +511,7 @@ void InferRequest::wait() { if (static_cast(out_rank) < static_cast(dims.size())) { for (size_t i = out_rank; i < dims.size(); i++) { if (dims[i] != 1) - IE_THROW() << "[GPU] Unexpected out shape"; + OPENVINO_THROW("[GPU] Unexpected out shape"); } dims.resize(out_rank); } @@ -715,7 +707,7 @@ void InferRequest::copy_input_data(std::shared_ptr network, break; } default: - IE_THROW() << "The plugin does not support input " << inputBlob.getTensorDesc().getPrecision() << " precision"; + OPENVINO_THROW("The plugin does not support input ", inputBlob.getTensorDesc().getPrecision(), " precision"); } } @@ -820,7 +812,7 @@ void InferRequest::InferImpl() { std::map InferRequest::GetPerformanceCounts() const { OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "InferRequest::GetPerformanceCounts"); if (!m_useProfiling) { - IE_THROW() << "Performance counters were not enabled"; + OPENVINO_THROW("Performance counters were not enabled"); } else { return m_graph->GetPerformanceCounts(); } @@ -956,7 +948,7 @@ void InferRequest::prepare_input(const cldnn::primitive_id& inputName, Blob::Ptr remote_ptr : reqBlob); if (!impl->is_allocated()) { - IE_THROW() << str_input_not_allocated; + OPENVINO_THROW(str_input_not_allocated); } auto inputMem = impl->get_memory(); @@ -1001,7 +993,7 @@ void InferRequest::prepare_input(const cldnn::primitive_id& inputName, Blob::Ptr break; } default: - IE_THROW() << "Unsupported input precision " << prec; + OPENVINO_THROW("Unsupported input precision ", prec); } } @@ -1032,7 +1024,7 @@ void InferRequest::prepare_output(const cldnn::primitive_id& outputName, Blob::P : reqBlob->as(); auto impl = getBlobImpl(output_blob_ptr); if (!impl->is_allocated()) { - IE_THROW(NotAllocated) << str_output_not_allocated; + OPENVINO_THROW(str_output_not_allocated); } auto outputMem = impl->get_memory(); _nw_ptr->set_output_memory(internalName, outputMem); @@ -1080,7 +1072,7 @@ Blob::Ptr InferRequest::reinterpret_device_blob(Blob::Ptr data, const TensorDesc auto remote_blob = data->as(); if (!remote_blob) - IE_THROW() << "Invalid blob used for reinterpretation"; + OPENVINO_THROW("Invalid blob used for reinterpretation"); remote_blob->setShape(new_desc.getDims()); diff --git a/src/plugins/intel_gpu/src/plugin/legacy_api_helper.cpp b/src/plugins/intel_gpu/src/plugin/legacy_api_helper.cpp index 746f2f3126f4eb..baf564801209d6 100644 --- a/src/plugins/intel_gpu/src/plugin/legacy_api_helper.cpp +++ b/src/plugins/intel_gpu/src/plugin/legacy_api_helper.cpp @@ -3,9 +3,6 @@ // #include "intel_gpu/plugin/legacy_api_helper.hpp" -#include "ie_plugin_config.hpp" -#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp" -#include "gpu/gpu_config.hpp" namespace ov { namespace intel_gpu { @@ -247,6 +244,7 @@ std::vector LegacyAPIHelper::get_supported_configs() { } std::vector LegacyAPIHelper::get_supported_metrics() { + OPENVINO_SUPPRESS_DEPRECATED_START std::vector supported_metrics = { METRIC_KEY(AVAILABLE_DEVICES), METRIC_KEY(SUPPORTED_METRICS), @@ -265,6 +263,7 @@ std::vector LegacyAPIHelper::get_supported_metrics() { GPU_METRIC_KEY(EXECUTION_UNITS_COUNT), GPU_METRIC_KEY(MEMORY_STATISTICS), }; + OPENVINO_SUPPRESS_DEPRECATED_END return supported_metrics; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/batch_to_space.cpp b/src/plugins/intel_gpu/src/plugin/ops/batch_to_space.cpp index a664ea02ff263f..f4a881345b2c6f 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/batch_to_space.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/batch_to_space.cpp @@ -26,8 +26,7 @@ static void CreateBatchToSpaceOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(i)); - if (!inConst) - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(inConst != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); std::vector sizes = inConst->cast_vector(); int32_t default_size = i == 1 ? 1 : 0; diff --git a/src/plugins/intel_gpu/src/plugin/ops/broadcast.cpp b/src/plugins/intel_gpu/src/plugin/ops/broadcast.cpp index fc5c51b1f3816e..9be1f1f4bfadb4 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/broadcast.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/broadcast.cpp @@ -97,8 +97,7 @@ static void CreateBroadcastOp(Program& p, const std::shared_ptrget_broadcast_spec().m_type == ngraph::op::AutoBroadcastType::NONE && op->get_input_size() == 3) { auto axis_mapping_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(2)); - if (!axis_mapping_node) - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(axis_mapping_node != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); auto axis_mapping = axis_mapping_node->get_axis_set_val(); CreateCommonBroadcastOp(p, op, axis_mapping); @@ -113,8 +112,7 @@ static void CreateBroadcastOp(Program& p, const std::shared_ptrget_input_size() == 3) { auto axis_mapping_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(2)); - if (!axis_mapping_node) - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(axis_mapping_node != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); axis_mapping = axis_mapping_node->get_axis_set_val(); } diff --git a/src/plugins/intel_gpu/src/plugin/ops/constant.cpp b/src/plugins/intel_gpu/src/plugin/ops/constant.cpp index 0f966ff42d523a..55dc0084f6bd38 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/constant.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/constant.cpp @@ -55,7 +55,7 @@ static cldnn::tensor getConstTensor(const ngraph::Shape constDims) { break; case 0: constTensor = cldnn::tensor(1, 1, 1, 1); break; - default: IE_THROW() << "Invalid constant blob dimensions"; + default: OPENVINO_THROW("Invalid constant blob dimensions"); } return constTensor; } @@ -182,7 +182,7 @@ void createClDnnConstant(Program& p, const ngraph::Shape& constDims, const std:: if (props.swapOI) { size_t expected_min_rank = 2 + (props.hasGroupDimension ? 1 : 0); if (expected_min_rank > constDims.size()) - IE_THROW() << "Invalid constant properties or shape"; + OPENVINO_THROW("Invalid constant properties or shape"); if (props.hasGroupDimension) { std::swap(newDims[2], newDims[1]); diff --git a/src/plugins/intel_gpu/src/plugin/ops/convolution.cpp b/src/plugins/intel_gpu/src/plugin/ops/convolution.cpp index 0962c8ae008181..890ed5c6613c8f 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/convolution.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/convolution.cpp @@ -106,7 +106,7 @@ static void CreateConvolutionBackpropDataOp(Program& p, const std::shared_ptrget_dilations(); for (auto d : dilations) { if (d != 1) { - IE_THROW() << "Unsupported dilation in ConvolutionBackpropData " << op->get_friendly_name(); + OPENVINO_THROW("Unsupported dilation in ConvolutionBackpropData ", op->get_friendly_name()); } } @@ -194,7 +194,7 @@ static void CreateGroupConvolutionBackpropDataOp(Program& p, const std::shared_p auto dilations = op->get_dilations(); for (auto d : dilations) { if (d != 1) { - IE_THROW() << "Unsupported dilation in GroupConvolutionBackpropData " << op->get_friendly_name(); + OPENVINO_THROW("Unsupported dilation in GroupConvolutionBackpropData ", op->get_friendly_name()); } } diff --git a/src/plugins/intel_gpu/src/plugin/ops/ctc_greedy_decoder.cpp b/src/plugins/intel_gpu/src/plugin/ops/ctc_greedy_decoder.cpp index 473b0107368887..8d54300d98de4f 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/ctc_greedy_decoder.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/ctc_greedy_decoder.cpp @@ -47,11 +47,11 @@ static void CreateCommonCTCGreedyDecoderOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(2)); if (!blank_index_node) { - IE_THROW() << "Unsupported blank_index node type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported blank_index node type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } float val; if (ngraph::shape_size(blank_index_node->get_output_shape(0)) != 1 || !ov::op::util::get_single_value(blank_index_node, val)) { - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } blank_index = static_cast(val); reordered_inputs.pop_back(); diff --git a/src/plugins/intel_gpu/src/plugin/ops/cum_sum.cpp b/src/plugins/intel_gpu/src/plugin/ops/cum_sum.cpp index 267b732898912f..87678e2f36ee6e 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/cum_sum.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/cum_sum.cpp @@ -24,9 +24,7 @@ static void CreateCumSumOp(Program& p, const std::shared_ptrget_input_size() == 2) { auto axes_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!axes_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axes_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); axis = axes_constant->cast_vector()[0]; } OPENVINO_SUPPRESS_DEPRECATED_START diff --git a/src/plugins/intel_gpu/src/plugin/ops/custom.cpp b/src/plugins/intel_gpu/src/plugin/ops/custom.cpp index d2508916d33e69..6579f460726808 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/custom.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/custom.cpp @@ -44,7 +44,7 @@ class CustomLayerAttributeVisitor : public ngraph::AttributeVisitor { CustomLayerAttributeVisitor() : m_values({}) { } void on_adapter(const std::string& name, ngraph::ValueAccessor& adapter) override { - IE_THROW() << "Attribute " << name << " can't be processed\n"; + OPENVINO_THROW("Attribute ", name, " can't be processed\n"); } // The remaining adapter methods fall back on the void adapter if not implemented void on_adapter(const std::string& name, ngraph::ValueAccessor& adapter) override { @@ -165,7 +165,7 @@ void CreateCustomOp(Program& p, const std::shared_ptr& op, CustomL break; } default: - IE_THROW() << "Invalid custom layer param type: " << param.type << " in operation: " << op->get_friendly_name(); + OPENVINO_THROW("Invalid custom layer param type: ", param.type, " in operation: ", op->get_friendly_name()); } } const std::string layerTitle("\n// Layer " + op->get_friendly_name() + " using Custom Layer " + customLayer->Name() + "\n"); @@ -194,7 +194,7 @@ void CreateCustomOp(Program& p, const std::shared_ptr& op, CustomL // if input index is greater than -1, take dimension from input if (iidx >= 0) { if (static_cast(iidx) >= op->get_input_size()) - IE_THROW() << "Invalid input tensor for index: " << iidx; + OPENVINO_THROW("Invalid input tensor for index: ", iidx); auto inputDims = op->get_input_shape(iidx); xDim = static_cast(inputDims[inputDims.size() - 1]); diff --git a/src/plugins/intel_gpu/src/plugin/ops/depth_to_space.cpp b/src/plugins/intel_gpu/src/plugin/ops/depth_to_space.cpp index dbccf2e469d64d..a35dec7e273539 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/depth_to_space.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/depth_to_space.cpp @@ -18,7 +18,7 @@ static cldnn::depth_to_space_mode GetDepthMode(ngraph::op::v0::DepthToSpace::Dep return cldnn::depth_to_space_mode::blocks_first; case ngraph::op::v0::DepthToSpace::DepthToSpaceMode::DEPTH_FIRST: return cldnn::depth_to_space_mode::depth_first; - default: IE_THROW() << "Unsupported DepthToSpaceMode value: " << static_cast(mode); + default: OPENVINO_THROW("Unsupported DepthToSpaceMode value: ", static_cast(mode)); } return cldnn::depth_to_space_mode::blocks_first; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/detection_output.cpp b/src/plugins/intel_gpu/src/plugin/ops/detection_output.cpp index 542ce6e13591d4..19cdb51ebf94d7 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/detection_output.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/detection_output.cpp @@ -22,7 +22,7 @@ static cldnn::prior_box_code_type PriorBoxCodeFromString(const std::string& str) if (it != CodeNameToType.end()) { return it->second; } else { - IE_THROW() << "Unknown Prior-Box code type: " << str; + OPENVINO_THROW("Unknown Prior-Box code type: ", str); } return cldnn::prior_box_code_type::corner; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/dft.cpp b/src/plugins/intel_gpu/src/plugin/ops/dft.cpp index e084b2e125c8d3..2cd1873cc2f4a6 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/dft.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/dft.cpp @@ -25,9 +25,7 @@ void createDft(Program& p, const auto& out_shape = op->get_output_shape(0); auto axes_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!axes_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << friendly_name << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axes_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", friendly_name, " (", op->get_type_name(), ")"); auto axes = axes_constant->cast_vector(); uint8_t axis_correction = static_cast(op->get_input_shape(0).size()); if (direction != cldnn::dft_direction::forward || mode != cldnn::dft_mode::real) { @@ -40,9 +38,7 @@ void createDft(Program& p, std::vector signal_size; if (op->get_input_size() == 3) { auto signal_size_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(2)); - if (!signal_size_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << friendly_name << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(signal_size_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", friendly_name, " (", op->get_type_name(), ")"); signal_size = signal_size_constant->cast_vector(); } diff --git a/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp b/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp index 4e42706e5e0815..608938a3686f8f 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp @@ -162,7 +162,7 @@ static void CreatePowerOp(Program& p, const std::shared_ptrget_output_shape(0)) == 1) { float pow; if (!ov::op::util::get_single_value(power_node, pow)) - IE_THROW() << "Invalid parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Invalid parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); CreateUnaryEltwiseOp(p, op, cldnn::activation_func::pow, {pow}); return; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/embedding_bag.cpp b/src/plugins/intel_gpu/src/plugin/ops/embedding_bag.cpp index 52d8c719508d52..b294a1ee4106f8 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/embedding_bag.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/embedding_bag.cpp @@ -25,13 +25,11 @@ static void CreateEmbeddingBagOffsetsSumOp(Program& p, const std::shared_ptr 3) { auto index_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(3)); - if (!index_node) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(index_node != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); float val; if (ngraph::shape_size(index_node->get_output_shape(0)) != 1 || !ov::op::util::get_single_value(index_node, val)) - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); defaultIndex = static_cast(val); inputs.erase(inputs.begin() + 3); // Remove "default_index" @@ -113,13 +111,11 @@ static void CreateEmbeddingSegmentsSumOp(Program& p, const std::shared_ptr 3) { auto index_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(4)); - if (!index_node) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(index_node != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); float val; if (ngraph::shape_size(index_node->get_output_shape(0)) != 1 || !ov::op::util::get_single_value(index_node, val)) - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); defaultIndex = static_cast(val); inputs.erase(inputs.begin() + 3); // Remove "default_index" diff --git a/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_detection_output.cpp b/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_detection_output.cpp index e8d96af7d2b643..094c44e9c4b12b 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_detection_output.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_detection_output.cpp @@ -18,7 +18,7 @@ static void CreateExperimentalDetectronDetectionOutputOp( validate_inputs_count(op, {4}); if (op->get_output_size() != 3) { - IE_THROW() << "ExperimentalDetectronDetectionOutput requires 3 outputs"; + OPENVINO_THROW("ExperimentalDetectronDetectionOutput requires 3 outputs"); } auto inputs = p.GetInputInfo(op); @@ -54,7 +54,7 @@ static void CreateExperimentalDetectronDetectionOutputOp( const auto expectedPrimInputCount = 4 + 2; // 4 operation inputs plus 2 input-outputs if (inputs.size() != expectedPrimInputCount) { - IE_THROW() << "experimental_detectron_detection_output primitive requires 6 inputs"; + OPENVINO_THROW("experimental_detectron_detection_output primitive requires 6 inputs"); } const cldnn::experimental_detectron_detection_output prim{layer_name, diff --git a/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_generate_proposals_single_image.cpp b/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_generate_proposals_single_image.cpp index 18fdc1a9d9aaa6..0d7e02983f8aa9 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_generate_proposals_single_image.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/experimental_detectron_generate_proposals_single_image.cpp @@ -18,7 +18,7 @@ static void CreateExperimentalDetectronGenerateProposalsSingleImageOp( const std::shared_ptr& op) { validate_inputs_count(op, {4}); if (op->get_output_size() != 2) { - IE_THROW() << "ExperimentalDetectronGenerateProposalsSingleImage requires 2 outputs"; + OPENVINO_THROW("ExperimentalDetectronGenerateProposalsSingleImage requires 2 outputs"); } auto inputs = p.GetInputInfo(op); diff --git a/src/plugins/intel_gpu/src/plugin/ops/extract_image_patches.cpp b/src/plugins/intel_gpu/src/plugin/ops/extract_image_patches.cpp index 7e9dca2fcaf835..16988042ba4eee 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/extract_image_patches.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/extract_image_patches.cpp @@ -17,7 +17,7 @@ static inline std::string PadToString(ngraph::op::PadType pad) { case ngraph::op::PadType::SAME_UPPER: return "same_upper"; case ngraph::op::PadType::SAME_LOWER: return "same_lower"; case ngraph::op::PadType::VALID: return "valid"; - default: IE_THROW() << "Unsupported pad type in ExtractImagePatches primitive " << pad; + default: OPENVINO_THROW("Unsupported pad type in ExtractImagePatches primitive ", pad); } return ""; diff --git a/src/plugins/intel_gpu/src/plugin/ops/generate_proposals.cpp b/src/plugins/intel_gpu/src/plugin/ops/generate_proposals.cpp index d7d59342109711..b7786740de8266 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/generate_proposals.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/generate_proposals.cpp @@ -18,7 +18,7 @@ static void CreateGenerateProposalsIEInternalOp( const std::shared_ptr& op) { validate_inputs_count(op, {4}); if (op->get_output_size() != 3) { - IE_THROW() << "GenerateProposals requires 3 outputs"; + OPENVINO_THROW("GenerateProposals requires 3 outputs"); } auto inputs = p.GetInputInfo(op); diff --git a/src/plugins/intel_gpu/src/plugin/ops/loop.cpp b/src/plugins/intel_gpu/src/plugin/ops/loop.cpp index b44e16a9cb333e..fca6fd595874ae 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/loop.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/loop.cpp @@ -135,7 +135,7 @@ static void CreateLoopOp(Program& p, const std::shared_ptr& op) { const cldnn::primitive_id execution_condition_id = layer_type_name_ID(op->get_input_node_shared_ptr(1)); const int64_t num_iterations = op->get_num_iterations(); if (num_iterations < 0) { - IE_THROW() << "loop's num_iteration cannot be negative"; + OPENVINO_THROW("loop's num_iteration cannot be negative"); } const cldnn::primitive_id num_iteration_id = layerName + "_numIteration"; { diff --git a/src/plugins/intel_gpu/src/plugin/ops/lrn.cpp b/src/plugins/intel_gpu/src/plugin/ops/lrn.cpp index 71a6ced9da9ef0..3f5d244f305ca4 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/lrn.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/lrn.cpp @@ -27,9 +27,7 @@ static void CreateLRNOp(Program& p, const std::shared_ptr& std::string layerName = layer_type_name_ID(op); auto axis_const = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!axis_const) { - IE_THROW() << "Unsupported axes node type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axis_const != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); auto axis_value = axis_const->cast_vector(); auto localSize = static_cast(op->get_nsize()); diff --git a/src/plugins/intel_gpu/src/plugin/ops/matmul.cpp b/src/plugins/intel_gpu/src/plugin/ops/matmul.cpp index 7cf054e0c8689c..15522f8fb3137c 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/matmul.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/matmul.cpp @@ -62,7 +62,7 @@ static std::tuple get_aligned_shapes(const Par } } else { if (a_dim != b_dim && a_dim.get_length() > 1 && b_dim.get_length() > 1) { - IE_THROW() << "Shapes can't be aligned: " << shape_a_aligned << " " << shape_b_aligned; + OPENVINO_THROW("Shapes can't be aligned: ", shape_a_aligned, " ", shape_b_aligned); } auto max_value = std::max(a_dim.get_length(), b_dim.get_length()); shape_a_aligned[i] = shape_b_aligned[i] = max_value; @@ -96,7 +96,7 @@ static void CreateMatMulOp(Program& p, const std::shared_ptrget_friendly_name() << " shapes are inconsistent."; + OPENVINO_THROW("MatMul ", op->get_friendly_name(), " shapes are inconsistent."); } auto inputName = inputs[0].pid; diff --git a/src/plugins/intel_gpu/src/plugin/ops/multiclass_nms.cpp b/src/plugins/intel_gpu/src/plugin/ops/multiclass_nms.cpp index 7f92c8bc191afa..dfa0df468cec6b 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/multiclass_nms.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/multiclass_nms.cpp @@ -53,7 +53,7 @@ static void CreateMulticlassNmsIEInternalOp(Program& p, const std::shared_ptr& validate_inputs_count(op, {2}); auto inConst = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!inConst) - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(inConst != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); std::vector axes = inConst->cast_vector(); OPENVINO_SUPPRESS_DEPRECATED_START diff --git a/src/plugins/intel_gpu/src/plugin/ops/non_max_suppression.cpp b/src/plugins/intel_gpu/src/plugin/ops/non_max_suppression.cpp index 34b468b9c9ce5f..f4484ec345689f 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/non_max_suppression.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/non_max_suppression.cpp @@ -83,7 +83,7 @@ static void CreateNonMaxSuppressionIEInternalOp(Program& p, const std::shared_pt case 4: prim.iou_threshold = reordered_inputs[3].pid; case 3: prim.num_select_per_class = reordered_inputs[2].pid; case 2: break; - default: IE_THROW() << "Incorrect number of input primitives for layer: " << op->get_friendly_name(); + default: OPENVINO_THROW("Incorrect number of input primitives for layer: ", op->get_friendly_name()); } p.add_primitive(*op, prim); @@ -128,7 +128,7 @@ static void CreateNonMaxSuppressionIEInternalOp(Program& p, const std::shared_pt inputs.push_back(cldnn::input_info(non_max_suppression_mutable_id_w_first)); } case 1: break; - default: IE_THROW() << "Incorrect number of output for layer: " << op->get_friendly_name(); + default: OPENVINO_THROW("Incorrect number of output for layer: ", op->get_friendly_name()); } auto nonMaxSuppressionLayerName = num_outputs > 1 ? layer_type_name_ID(op) + ".out0" : layer_type_name_ID(op); @@ -150,7 +150,7 @@ static void CreateNonMaxSuppressionIEInternalOp(Program& p, const std::shared_pt case 4: prim.iou_threshold = reordered_inputs[3].pid; case 3: prim.num_select_per_class = reordered_inputs[2].pid; case 2: break; - default: IE_THROW() << "Incorrect number of input primitives for layer: " << op->get_friendly_name(); + default: OPENVINO_THROW("Incorrect number of input primitives for layer: ", op->get_friendly_name()); } switch (num_outputs) { diff --git a/src/plugins/intel_gpu/src/plugin/ops/normalize_l2.cpp b/src/plugins/intel_gpu/src/plugin/ops/normalize_l2.cpp index 7acac780544e63..6c84a0ce94fb38 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/normalize_l2.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/normalize_l2.cpp @@ -21,8 +21,7 @@ static void CreateNormalizeL2Op(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(1)); - if (!const_axis) - IE_THROW() << "Unsupported axis node type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(const_axis != nullptr, "[GPU] Unsupported axis node type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); auto axis = const_axis->cast_vector(); bool across_spatial = !(axis.size() == 1 && axis[0] == 1); @@ -42,7 +41,7 @@ static void CreateNormalizeL2Op(Program& p, const std::shared_ptrget_output_tensor(0).size(); if (bufSize != constLayout.bytes_count()) - IE_THROW() << "Invalid scales buffer in NormalizeL2 op " << op->get_friendly_name(); + OPENVINO_THROW("Invalid scales buffer in NormalizeL2 op ", op->get_friendly_name()); std::memcpy(&buf[0], scale->get_data_ptr(), bufSize); auto scalesName = layerName + "_cldnn_input_scales"; diff --git a/src/plugins/intel_gpu/src/plugin/ops/one_hot.cpp b/src/plugins/intel_gpu/src/plugin/ops/one_hot.cpp index a20881612b3129..8a0f0323fe38c1 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/one_hot.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/one_hot.cpp @@ -23,21 +23,21 @@ static void CreateOneHotOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(2)); auto off_value_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(3)); - if (on_value_node == nullptr || off_value_node == nullptr || depth_value_node == nullptr) - IE_THROW() << "Unsupported on/off/depth node type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(on_value_node != nullptr || off_value_node != nullptr || depth_value_node != nullptr, + "[GPU] Unsupported on/off/depth nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); float on_value; float off_value; if (!ov::op::util::get_single_value(on_value_node, on_value) || !ov::op::util::get_single_value(off_value_node, off_value)) { - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } auto dims = op->get_input_partial_shape(0); if (axis < -1 || axis > static_cast(dims.size())) - IE_THROW() << op->get_friendly_name() << " Incorrect OneHot axis value: " << axis << ". Should be between -1 and " << dims.size(); + OPENVINO_THROW(op->get_friendly_name(), " Incorrect OneHot axis value: ", axis, ". Should be between -1 and ", dims.size()); if (axis == -1) { axis = dims.size(); diff --git a/src/plugins/intel_gpu/src/plugin/ops/parameter.cpp b/src/plugins/intel_gpu/src/plugin/ops/parameter.cpp index a97af1da4f815b..f7455a7e1728a4 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/parameter.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/parameter.cpp @@ -21,9 +21,8 @@ namespace intel_gpu { static void CreateParameterOp(Program& p, const std::shared_ptr& op) { auto networkInputs = p.GetNetworkInputs(); - if (networkInputs.find(op->get_friendly_name()) == networkInputs.end()) { - IE_THROW() << "Can't find input " << op->get_friendly_name() << " in InputsDataMap"; - } + OPENVINO_ASSERT(networkInputs.find(op->get_friendly_name()) != networkInputs.end(), + "[GPU] Can't find input ", op->get_friendly_name(), " in InputsDataMap"); auto inputInfo = networkInputs.at(op->get_friendly_name()); // first create and add the input layout @@ -61,7 +60,7 @@ static void CreateParameterOp(Program& p, const std::shared_ptr 0) && (meanChannels != static_cast(networkInputLayout.feature()))) { - IE_THROW() << "Mismatched mean values channels in input " << inputName; + OPENVINO_THROW("Mismatched mean values channels in input ", inputName); } switch (preProcess.getMeanVariant()) { @@ -70,14 +69,14 @@ static void CreateParameterOp(Program& p, const std::shared_ptr 0) { for (size_t c = 0; c < meanChannels; c++) { if (fabs(preProcess[c]->stdScale - 1.0f) > 1e-10) - IE_THROW() << "not supporting stdScale yet in input " << inputName; + OPENVINO_THROW("not supporting stdScale yet in input ", inputName); meanValues.push_back(preProcess[c]->meanValue); } } break; } case MEAN_IMAGE: { - IE_ASSERT(meanChannels); + OPENVINO_ASSERT(meanChannels); // first merge all mean values to a single blob // todo make sure mean blob precision is the same as the input precision auto meanDims = input_pshape; @@ -86,7 +85,7 @@ static void CreateParameterOp(Program& p, const std::shared_ptr meanBlob(desc); @@ -94,7 +93,7 @@ static void CreateParameterOp(Program& p, const std::shared_ptrstdScale - 1.0f) > 1e-10) - IE_THROW() << "not supporting stdScale yet in input " << inputName; + OPENVINO_THROW("not supporting stdScale yet in input ", inputName); auto channelMeanBlob = std::dynamic_pointer_cast>(preProcess[c]->meanData); auto channelSize = channelMeanBlob->size(); auto channelBlobData = channelMeanBlob->data(); @@ -128,7 +127,7 @@ static void CreateParameterOp(Program& p, const std::shared_ptr& op) { validate_inputs_count(op, {1}); if (op->get_output_size() != 2) { - IE_THROW() << "MaxPool opset 8 requires 2 outputs"; + OPENVINO_THROW("[GPU] MaxPool opset 8 requires 2 outputs"); } auto inputs = p.GetInputInfo(op); const auto layer_type_name = layer_type_name_ID(op); diff --git a/src/plugins/intel_gpu/src/plugin/ops/prior_box.cpp b/src/plugins/intel_gpu/src/plugin/ops/prior_box.cpp index 6ca49e2d3ccdc8..72aceee5002a53 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/prior_box.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/prior_box.cpp @@ -125,9 +125,8 @@ static void CreatePriorBoxOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(0)); const auto image_size_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!(output_size_constant && image_size_constant)) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(output_size_constant && image_size_constant, + "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); const auto output_size = output_size_constant->cast_vector(); const auto width = output_size[0]; diff --git a/src/plugins/intel_gpu/src/plugin/ops/reduce.cpp b/src/plugins/intel_gpu/src/plugin/ops/reduce.cpp index c324af3d7b10ed..7eb382dee4784e 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/reduce.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/reduce.cpp @@ -31,9 +31,7 @@ static void CreateReduceOp(Program& p, const std::shared_ptr& op, int64_t rank = input_pshape.size(); auto axes_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!axes_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axes_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); std::vector axes = axes_constant->cast_vector(); for (size_t i = 0; i < axes.size(); i++) { @@ -41,7 +39,7 @@ static void CreateReduceOp(Program& p, const std::shared_ptr& op, axes[i] += rank; if (axes[i] >= static_cast(rank) || axes[i] < 0) - IE_THROW() << "Unsupported axis value in " << op->get_friendly_name() << " (" << axes[i] << ")"; + OPENVINO_THROW("[GPU] Unsupported axis value in ", op->get_friendly_name(), " (", axes[i], ")"); } auto reducePrim = cldnn::reduce(layerName, diff --git a/src/plugins/intel_gpu/src/plugin/ops/result.cpp b/src/plugins/intel_gpu/src/plugin/ops/result.cpp index 4fa67f0cf64a05..def32d1fec37cd 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/result.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/result.cpp @@ -29,9 +29,7 @@ static void CreateResultOp(Program& p, const std::shared_ptrfirst; DataPtr outputData = it->second; @@ -56,7 +54,7 @@ static void CreateResultOp(Program& p, const std::shared_ptrget_output_partial_shape(0).size(); auto out_format = cldnn::format::get_default_format(out_rank); diff --git a/src/plugins/intel_gpu/src/plugin/ops/rnn.cpp b/src/plugins/intel_gpu/src/plugin/ops/rnn.cpp index 888a1b5589ad4d..7df02077f438c6 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/rnn.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/rnn.cpp @@ -41,12 +41,11 @@ void GetLSTMActivationParams(const std::shared_ptr& op, auto op_activations = op->get_activations(); if (!op_activations.empty()) { if (op_activations.size() != 3) - IE_THROW() << "Wrong number of activations for LSTMCell op " << op->get_friendly_name(); + OPENVINO_THROW("Wrong number of activations for LSTMCell op ", op->get_friendly_name()); for (int i = 0; i < 3; i++) { auto af = GetActivationFunc(op_activations[i]); if (af == cldnn::activation_func::none) - IE_THROW() << "Wrong or unsupported activation type " << op_activations[i] - << " for LSTMCell op " << op->get_friendly_name(); + OPENVINO_THROW("Wrong or unsupported activation type ", op_activations[i], " for LSTMCell op ", op->get_friendly_name()); activations[i] = af; } } @@ -54,7 +53,7 @@ void GetLSTMActivationParams(const std::shared_ptr& op, auto op_b = op->get_activations_beta(); if (!op_a.empty()) { if (op_a.size() != 3 || op_b.size() != 3) - IE_THROW() << "Wrong number of activation parameters for LSTMCell op " << op->get_friendly_name(); + OPENVINO_THROW("Wrong number of activation parameters for LSTMCell op ", op->get_friendly_name()); for (int i = 0; i < 3; i++) { cldnn::activation_additional_params params = { op_a[i], op_b[i] }; activation_params.push_back(cldnn::activation_additional_params(params)); @@ -80,7 +79,7 @@ static void CreateLSTMCellOp(Program& p, const std::shared_ptrget_input_shape(1).size() != 2 || op->get_input_shape(2).size() != 2) - IE_THROW() << "Wrong input shapes for LSTMCell op " << op->get_friendly_name(); + OPENVINO_THROW("Wrong input shapes for LSTMCell op ", op->get_friendly_name()); lstm_input_size = static_cast(in_dims0.back()); lstm_batch_size = static_cast(in_dims0.at(in_dims0.size()-2)); @@ -175,7 +174,7 @@ static void CreateLSTMSequenceOp(Program& p, const std::shared_ptrget_input_shape(1).size() != 3 || op->get_input_shape(2).size() != 3) - IE_THROW() << "Wrong input shapes for LSTMSequence op " << op->get_friendly_name(); + OPENVINO_THROW("Wrong input shapes for LSTMSequence op ", op->get_friendly_name()); lstm_input_size = static_cast(in_dims0.back()); lstm_sequence_len = static_cast(in_dims0.at(in_dims0.size() - 2)); diff --git a/src/plugins/intel_gpu/src/plugin/ops/roll.cpp b/src/plugins/intel_gpu/src/plugin/ops/roll.cpp index a80cb0222cf12a..ea3dd22aa8b2b4 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/roll.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/roll.cpp @@ -28,15 +28,11 @@ void CreateRollOp(Program& p, const std::shared_ptr& op) { const auto default_rank = format.dimension(); auto shift_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!shift_constant) { - IE_THROW() << "Unsupported parameter node type in " << op_friendly_name << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(shift_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op_friendly_name, " (", op->get_type_name(), ")"); const auto shift_raw = shift_constant->cast_vector(); auto axes_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(2)); - if (!axes_constant) { - IE_THROW() << "Unsupported parameter node type in " << op_friendly_name << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axes_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op_friendly_name, " (", op->get_type_name(), ")"); auto axes_raw = axes_constant->cast_vector(); // Normalize axes and sum shift @@ -47,7 +43,7 @@ void CreateRollOp(Program& p, const std::shared_ptr& op) { axis += rank; } if (axis < 0 || axis >= rank) { - IE_THROW() << op_friendly_name << " Incorrect axis value: " << axis; + OPENVINO_THROW(op_friendly_name, " Incorrect axis value: ", axis); } shift[axis] += shift_raw[a]; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/scatter_update.cpp b/src/plugins/intel_gpu/src/plugin/ops/scatter_update.cpp index 50b788057743ef..46935c0db0641c 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/scatter_update.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/scatter_update.cpp @@ -19,9 +19,7 @@ static void CreateScatterUpdateOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(3)); - if (!axes_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axes_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); int64_t axis = axes_constant->cast_vector()[0]; auto primitive = cldnn::scatter_update(layerName, inputs[0], diff --git a/src/plugins/intel_gpu/src/plugin/ops/select.cpp b/src/plugins/intel_gpu/src/plugin/ops/select.cpp index e4f8853915d623..92830153f074aa 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/select.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/select.cpp @@ -26,7 +26,7 @@ static void CreateSelectOp(Program& p, const std::shared_ptrget_friendly_name(); + OPENVINO_THROW("[GPU] Unsupported broadcast type (", broadcast_type.m_type, ") in layer " + op->get_friendly_name()); } if (broadcast_type.m_type == ngraph::op::AutoBroadcastType::NUMPY) { diff --git a/src/plugins/intel_gpu/src/plugin/ops/space_to_batch.cpp b/src/plugins/intel_gpu/src/plugin/ops/space_to_batch.cpp index bbf9e0797a9442..130f27276b4b80 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/space_to_batch.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/space_to_batch.cpp @@ -26,8 +26,7 @@ static void CreateSpaceToBatchOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(i)); - if (!inConst) - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(inConst != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); std::vector sizes = inConst->cast_vector(); int32_t default_size = i == 1 ? 1 : 0; diff --git a/src/plugins/intel_gpu/src/plugin/ops/space_to_depth.cpp b/src/plugins/intel_gpu/src/plugin/ops/space_to_depth.cpp index 19aa79dbc6f102..19cbc228a73f6b 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/space_to_depth.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/space_to_depth.cpp @@ -16,7 +16,7 @@ static cldnn::space_to_depth::depth_mode GetDepthMode(ngraph::op::v0::SpaceToDep switch (mode) { case ngraph::op::v0::SpaceToDepth::SpaceToDepthMode::BLOCKS_FIRST: return cldnn::space_to_depth::blocks_first; case ngraph::op::v0::SpaceToDepth::SpaceToDepthMode::DEPTH_FIRST: return cldnn::space_to_depth::depth_first; - default: IE_THROW() << "Unsupported SpaceToDepthMode value: " << static_cast(mode); + default: OPENVINO_THROW("[GPU] Unsupported SpaceToDepthMode value: ", static_cast(mode)); } return cldnn::space_to_depth::blocks_first; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/split.cpp b/src/plugins/intel_gpu/src/plugin/ops/split.cpp index f6f493e4598dfa..6afaf96cf10cdb 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/split.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/split.cpp @@ -38,13 +38,13 @@ static void CreateCommonSplitOp(Program& p, const std::shared_ptr& const auto outPartialShape = op->get_output_partial_shape(i); NGRAPH_SUPPRESS_DEPRECATED_START if (outPartialShape.size() != start_offset.size()) { - IE_THROW() << "Invalid dimesions in split layer: " << op->get_friendly_name() - << " output: " << ov::descriptor::get_ov_tensor_legacy_name(op->get_output_tensor(i)); + OPENVINO_THROW("Invalid dimesions in split layer: ", op->get_friendly_name(), + " output: ", ov::descriptor::get_ov_tensor_legacy_name(op->get_output_tensor(i))); } for (size_t idx = 0; idx < input_pshape.size(); idx++) { if ((outPartialShape[idx].get_length() + static_cast(start_offset[idx])) > input_pshape[idx].get_length()) { - IE_THROW() << "Invalid dimesions in split layer: " << op->get_friendly_name() - << " output: " << ov::descriptor::get_ov_tensor_legacy_name(op->get_output_tensor(idx)); + OPENVINO_THROW("Invalid dimesions in split layer: ", op->get_friendly_name(), + " output: ", ov::descriptor::get_ov_tensor_legacy_name(op->get_output_tensor(idx))); } } NGRAPH_SUPPRESS_DEPRECATED_END diff --git a/src/plugins/intel_gpu/src/plugin/ops/topk.cpp b/src/plugins/intel_gpu/src/plugin/ops/topk.cpp index 8830a54915cc7e..ace774c429faae 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/topk.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/topk.cpp @@ -108,7 +108,7 @@ static void CreateTopKOp(Program& p, const std::shared_ptr p.add_primitive(*op, argmaxPrim); } else { - IE_THROW() << op->get_friendly_name() << " Incorrect TopK outputs number"; + OPENVINO_THROW(op->get_friendly_name(), " Incorrect TopK outputs number"); } } } diff --git a/src/plugins/intel_gpu/src/plugin/ops/transpose.cpp b/src/plugins/intel_gpu/src/plugin/ops/transpose.cpp index d0866b1b86c064..38454faa78ed65 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/transpose.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/transpose.cpp @@ -22,9 +22,7 @@ static void CreateTransposeOp(Program& p, const std::shared_ptr order; if (op->get_input_size() == 2) { auto order_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!order_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(order_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); order = order_constant->cast_vector(); } diff --git a/src/plugins/intel_gpu/src/plugin/ops/unary.cpp b/src/plugins/intel_gpu/src/plugin/ops/unary.cpp index 5758997c8d8190..32a3f3c7e252ab 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/unary.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/unary.cpp @@ -80,8 +80,8 @@ static void CreatePReluOp(Program& p, const std::shared_ptrget_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_ASSERT(ov::op::util::get_single_value(slope_node, slope), + "[GPU] Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); CreateUnaryEltwiseOp(p, op, cldnn::activation_func::relu_negative_slope, {slope}); } else if (out_shape.size() >= 2) { auto inputs = p.GetInputInfo(op); @@ -166,14 +166,14 @@ static void CreateHardSigmoidOp(Program& p, const std::shared_ptr(op->get_input_node_shared_ptr(1)); auto beta_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(2)); if (!alpha_node || !beta_node) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } if (ngraph::shape_size(alpha_node->get_output_shape(0)) == 1 && ngraph::shape_size(beta_node->get_output_shape(0)) == 1) { float alpha, beta; if (!ov::op::util::get_single_value(alpha_node, alpha) || !ov::op::util::get_single_value(beta_node, beta)) { - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } CreateUnaryEltwiseOp(p, op, cldnn::activation_func::hard_sigmoid, {alpha, beta}); } @@ -192,18 +192,18 @@ static void CreateSeluOp(Program& p, const std::shared_ptr auto alpha_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); auto lambda_node = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(2)); if (!alpha_node || !lambda_node) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } if (ngraph::shape_size(alpha_node->get_output_shape(0)) == 1 && ngraph::shape_size(lambda_node->get_output_shape(0)) == 1) { float alpha, lambda; if (!ov::op::util::get_single_value(alpha_node, alpha) || !ov::op::util::get_single_value(lambda_node, lambda)) { - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } CreateUnaryEltwiseOp(p, op, cldnn::activation_func::selu, {alpha, lambda}); } else { - IE_THROW() << "Unsupported shapes of parameter nodes in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported shapes of parameter nodes in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } } @@ -239,14 +239,14 @@ static void CreateSwishOp(Program& p, const std::shared_ptrget_output_shape(0)) == 1) { float beta; if (!ov::op::util::get_single_value(beta_node, beta)) { - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } CreateUnaryEltwiseOp(p, op, cldnn::activation_func::swish, {beta}); } else { - IE_THROW() << "Unsupported parameter size in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter size in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } } else { - IE_THROW() << "Unsupported parameter type in " << op->get_friendly_name() << " (" << op->get_type_name() << ")"; + OPENVINO_THROW("Unsupported parameter type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); } } else { CreateUnaryEltwiseOp(p, op, cldnn::activation_func::swish, {1.0f}); @@ -289,7 +289,7 @@ static void CreateRoundOp(Program& p, const std::shared_ptrget_mode()) { case ngraph::op::v5::Round::RoundMode::HALF_TO_EVEN : func = cldnn::activation_func::round_half_to_even; break; case ngraph::op::v5::Round::RoundMode::HALF_AWAY_FROM_ZERO : func = cldnn::activation_func::round_half_away_from_zero; break; - default: IE_THROW() << "Unsupported round mode in " << op->get_friendly_name() << ": " << static_cast(op->get_mode()); + default: OPENVINO_THROW("Unsupported round mode in ", op->get_friendly_name(), ": ", static_cast(op->get_mode())); } CreateUnaryEltwiseOp(p, op, func, {}); } diff --git a/src/plugins/intel_gpu/src/plugin/ops/unique.cpp b/src/plugins/intel_gpu/src/plugin/ops/unique.cpp index f395972bce4bb0..aa5ad4876c16ba 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/unique.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/unique.cpp @@ -19,10 +19,7 @@ void CreateUniqueOp(Program& p, const std::shared_ptr& int64_t axis{}; if (op->get_input_size() == 2) { auto axis_constant = std::dynamic_pointer_cast(op->get_input_node_shared_ptr(1)); - if (!axis_constant) { - IE_THROW() << "Unsupported parameter nodes type in " << op->get_friendly_name() << " (" - << op->get_type_name() << ")"; - } + OPENVINO_ASSERT(axis_constant != nullptr, "[GPU] Unsupported parameter nodes type in ", op->get_friendly_name(), " (", op->get_type_name(), ")"); axis = axis_constant->cast_vector().at(0); axis = ov::normalize_axis(op.get(), axis, op->get_input_partial_shape(0).rank()); flattened = false; diff --git a/src/plugins/intel_gpu/src/plugin/plugin.cpp b/src/plugins/intel_gpu/src/plugin/plugin.cpp index 698ae9868d8361..4dbc2fe2c7c931 100644 --- a/src/plugins/intel_gpu/src/plugin/plugin.cpp +++ b/src/plugins/intel_gpu/src/plugin/plugin.cpp @@ -12,11 +12,15 @@ #include #include #include -#include "ie_metric_helpers.hpp" -#include -#include + +#include "intel_gpu/plugin/legacy_api_helper.hpp" #include "openvino/runtime/intel_gpu/properties.hpp" +#include "openvino/runtime/device_id_parser.hpp" +#include "openvino/core/dimension_tracker.hpp" +#include "openvino/pass/manager.hpp" +#include "openvino/util/common_util.hpp" + #include "intel_gpu/graph/serialization/layout_serializer.hpp" #include "intel_gpu/graph/serialization/string_serializer.hpp" #include "intel_gpu/graph/serialization/utils.hpp" @@ -25,25 +29,14 @@ #include "intel_gpu/plugin/compiled_model.hpp" #include "intel_gpu/plugin/transformations_pipeline.hpp" #include "intel_gpu/runtime/itt.hpp" -#include "intel_gpu/plugin/legacy_api_helper.hpp" #include "intel_gpu/runtime/execution_config.hpp" #include "intel_gpu/runtime/device_query.hpp" #include "intel_gpu/runtime/debug_configuration.hpp" -#include "ie_plugin_config.hpp" -#include "gpu/gpu_config.hpp" -#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp" -#include "openvino/runtime/device_id_parser.hpp" -#include "ie_icore.hpp" - -#include "openvino/core/dimension_tracker.hpp" #include "transformations/init_node_info.hpp" #include "transformations/common_optimizations/dimension_tracking.hpp" -#include -#include - -#include -#include +#include "transformations/rt_info/fused_names_attribute.hpp" +#include "transformations/utils/utils.hpp" #include @@ -180,8 +173,7 @@ auto check_inputs = [](InferenceEngine::InputsDataMap _networkInputs) { input_precision != InferenceEngine::Precision::I64 && input_precision != InferenceEngine::Precision::U64 && input_precision != InferenceEngine::Precision::BOOL) { - IE_THROW(NotImplemented) - << "Input image format " << input_precision << " is not supported yet..."; + OPENVINO_THROW("Input image format ", input_precision, " is not supported yet..."); } } }; @@ -314,9 +306,7 @@ QueryNetworkResult Plugin::QueryNetwork(const CNNNetwork& network, bool dyn_shape_batch_found = false; auto model = network.getFunction(); - if (model == nullptr) { - IE_THROW() << "Only ngraph-based models are supported!"; - } + OPENVINO_ASSERT(model != nullptr, "[GPU] Only ngraph-based models are supported!"); auto supported = GetSupportedNodes(model, [&](std::shared_ptr& model) { @@ -601,6 +591,7 @@ Parameter Plugin::GetMetric(const std::string& name, const std::map Plugin::get_supported_properties() const { @@ -827,11 +820,11 @@ uint32_t Plugin::get_max_batch_size(const std::map& opti auto n_streams_str = it_streams->second.as(); if (n_streams_str != CONFIG_VALUE(GPU_THROUGHPUT_AUTO) && n_streams_str != util::to_string(ov::streams::AUTO)) { - IE_THROW() << "[GPU_MAX_BATCH_SIZE] bad casting: GPU_THROUGHPUT_STREAMS should be either of uint32_t type or \"GPU_THROUGHPUT_AUTO\""; + OPENVINO_THROW("[GPU_MAX_BATCH_SIZE] bad casting: GPU_THROUGHPUT_STREAMS should be either of uint32_t type or \"GPU_THROUGHPUT_AUTO\""); } n_streams = std::max(/* config.GetDefaultNStreamsForThroughputMode() */2u, device_info.num_ccs); } else { - IE_THROW() << "[GPU_MAX_BATCH_SIZE] bad casting: GPU_THROUGHPUT_STREAMS should be either of uint32_t type or \"GPU_THROUGHPUT_AUTO\""; + OPENVINO_THROW("[GPU_MAX_BATCH_SIZE] bad casting: GPU_THROUGHPUT_STREAMS should be either of uint32_t type or \"GPU_THROUGHPUT_AUTO\""); } } @@ -843,10 +836,10 @@ uint32_t Plugin::get_max_batch_size(const std::map& opti available_device_mem = std::min(static_cast(available_device_mem), available_device_mem_it->second.as()); GPU_DEBUG_LOG << "[GPU_MAX_BATCH_SIZE] available memory is reset by user " << available_device_mem << std::endl; } else { - IE_THROW() << "[GPU_MAX_BATCH_SIZE] bad casting: ov::intel_gpu::hint::available_device_mem should be int64_t type"; + OPENVINO_THROW("[GPU_MAX_BATCH_SIZE] bad casting: ov::intel_gpu::hint::available_device_mem should be int64_t type"); } if (available_device_mem < 0) { - IE_THROW() << "[GPU_MAX_BATCH_SIZE] ov::intel_gpu::hint::available_device_mem value should be greater than 0 for max batch size calculation"; + OPENVINO_THROW("[GPU_MAX_BATCH_SIZE] ov::intel_gpu::hint::available_device_mem value should be greater than 0 for max batch size calculation"); } } @@ -855,7 +848,7 @@ uint32_t Plugin::get_max_batch_size(const std::map& opti if (model_param.is>()) { model = model_param.as>(); } else { - IE_THROW() << "[GPU_MAX_BATCH_SIZE] ov::hint::model should be std::shared_ptr type"; + OPENVINO_THROW("[GPU_MAX_BATCH_SIZE] ov::hint::model should be std::shared_ptr type"); } InferenceEngine::CNNNetwork network(model); @@ -960,7 +953,7 @@ uint32_t Plugin::get_optimal_batch_size(const std::map& try { model = model_param->second.as>(); } catch (...) { - IE_THROW() << "[OPTIMAL_BATCH_SIZE] ov::hint::model should be std::shared_ptr type"; + OPENVINO_THROW("[OPTIMAL_BATCH_SIZE] ov::hint::model should be std::shared_ptr type"); } GPU_DEBUG_INFO << "DEVICE_INFO:" << "gfx_version.major, " << device_info.gfx_ver.major diff --git a/src/plugins/intel_gpu/src/plugin/program.cpp b/src/plugins/intel_gpu/src/plugin/program.cpp index b184fa42c0da8e..d811b6ebafd71e 100644 --- a/src/plugins/intel_gpu/src/plugin/program.cpp +++ b/src/plugins/intel_gpu/src/plugin/program.cpp @@ -6,18 +6,16 @@ #include #endif -#include "intel_gpu/plugin/program.hpp" -#include "ngraph/ops.hpp" -#include "ov_ops/nms_ie_internal.hpp" #include "openvino/core/graph_util.hpp" -#include "intel_gpu/runtime/itt.hpp" +#include "openvino/runtime/system_conf.hpp" + +#include "intel_gpu/plugin/program.hpp" #include "intel_gpu/plugin/transformations_pipeline.hpp" +#include "intel_gpu/runtime/itt.hpp" #include "intel_gpu/runtime/debug_configuration.hpp" #include "intel_gpu/primitives/mutable_data.hpp" #include "intel_gpu/primitives/data.hpp" -#include - #ifdef __linux__ # include #endif @@ -125,7 +123,7 @@ bool Program::IsDynBatchModel(const std::shared_ptr& model, Program::Program(InferenceEngine::CNNNetwork& network, cldnn::engine& engine, const ExecutionConfig& config, bool createTopologyOnly, bool partialBuild, InferenceEngine::InputsDataMap* inputs, InferenceEngine::OutputsDataMap* outputs, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor, bool innerProgram) + std::shared_ptr task_executor, bool innerProgram) : m_curBatch(-1) , m_config(config) , m_engine(engine) @@ -139,7 +137,7 @@ Program::Program(InferenceEngine::CNNNetwork& network, cldnn::engine& engine, co auto func = network.getFunction(); if (!func) { - IE_THROW() << "Function pointer inside CNNNetwork is nullptr"; + OPENVINO_THROW("Function pointer inside CNNNetwork is nullptr"); } // locate global custom kernel config @@ -337,7 +335,7 @@ int Program::GetMaxBatchSizeForSingleProgram() { std::shared_ptr Program::GetCompiledProgram(int program_id) { if (program_id >= static_cast(m_programs.size())) - IE_THROW() << "Invalid program ID"; + OPENVINO_THROW("Invalid program ID"); return m_programs[program_id]; } @@ -460,9 +458,9 @@ void Program::CreateSingleLayerPrimitive(cldnn::topology& topology, const std::s } if (!is_created) { - IE_THROW() << "Operation: " << op->get_friendly_name() - << " of type " << op->get_type_name() - << "(op::v" << op->get_type_info().version_id << ") is not supported"; + OPENVINO_THROW("Operation: ", op->get_friendly_name(), + " of type ", op->get_type_name(), + "(", op->get_type_info().version_id, ") is not supported"); } } @@ -487,7 +485,7 @@ std::vector Program::GetInputInfo(const std::shared_ptr(op->get_input_source_output(i).get_index()))); @@ -596,9 +594,9 @@ void validate_inputs_count(const std::shared_ptr& op, std::vector< } } - IE_THROW() << "Invalid inputs count (" << op->get_input_size() << ") in " - << op->get_friendly_name() << " (" << op->get_type_name() - << " op::v" << op->get_type_info().version_id << ")"; + OPENVINO_THROW("Invalid inputs count (", op->get_input_size(), ") in )", + op->get_friendly_name(), " (", op->get_type_name(), + " ", op->get_type_info().version_id, ")"); } } // namespace intel_gpu diff --git a/src/plugins/intel_gpu/src/plugin/remote_blob.cpp b/src/plugins/intel_gpu/src/plugin/remote_blob.cpp index 481dac24f30c26..ecc072a7e5bd9d 100644 --- a/src/plugins/intel_gpu/src/plugin/remote_blob.cpp +++ b/src/plugins/intel_gpu/src/plugin/remote_blob.cpp @@ -104,7 +104,7 @@ AnyMap RemoteBlobImpl::getParams() const { { GPU_PARAM_KEY(VA_PLANE), params.plane } }; default: - IE_THROW() << "Unsupported shared object type " << static_cast(m_mem_type); + OPENVINO_THROW("Unsupported shared object type ", static_cast(m_mem_type)); } } @@ -112,7 +112,7 @@ void RemoteBlobImpl::setShape(const SizeVector& dims) { if (ov::shape_size(dims) > m_memory_object->count()) { OPENVINO_ASSERT(!is_shared(), "Cannot call setShape for Blobs created on top of preallocated memory if shape was increased."); if (!deallocate()) { - IE_THROW() << "Cannot deallocate blob while an attempt to enlarge blob area in setShape."; + OPENVINO_THROW("Cannot deallocate blob while an attempt to enlarge blob area in setShape."); } m_layout.set_partial_shape(ov::PartialShape{dims}); @@ -217,7 +217,7 @@ void RemoteBlobImpl::reinterpret(const cldnn::layout& new_layout) { void RemoteBlobImpl::lock() const { if (!is_allocated()) { - IE_THROW(NotAllocated) << "[GPU] Remote blob can't be locked as it's not allocated"; + OPENVINO_THROW("[GPU] Remote blob can't be locked as it's not allocated"); } std::lock_guard locker(lockedMutex); diff --git a/src/plugins/intel_gpu/src/plugin/remote_context.cpp b/src/plugins/intel_gpu/src/plugin/remote_context.cpp index b4107bb81f3645..d571f8cf4214e6 100644 --- a/src/plugins/intel_gpu/src/plugin/remote_context.cpp +++ b/src/plugins/intel_gpu/src/plugin/remote_context.cpp @@ -58,7 +58,7 @@ RemoteContextImpl::RemoteContextImpl(const std::vector& m_va_display = _va_device = extract_object(params, GPU_PARAM_KEY(VA_DEVICE)); m_type = ContextType::DEV_SHARED; } else { - IE_THROW() << "Invalid execution context type" << contextTypeStr; + OPENVINO_THROW("Invalid execution context type", contextTypeStr); } auto tile_id_itr = params.find(GPU_PARAM_KEY(TILE_ID)); if (tile_id_itr != params.end()) { @@ -94,7 +94,7 @@ AnyMap RemoteContextImpl::get_params() const { ret[GPU_PARAM_KEY(VA_DEVICE)] = m_va_display; break; default: - IE_THROW() << "Unsupported shared context type " << m_type; + OPENVINO_THROW("Unsupported shared context type ", m_type); } return ret; diff --git a/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp b/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp index 735a1a389d8bdd..d836b8922f04e8 100644 --- a/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp +++ b/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp @@ -13,9 +13,10 @@ #include #include "intel_gpu/plugin/transformations_pipeline.hpp" +#include "intel_gpu/plugin/legacy_api_helper.hpp" + +#include -#include "ie_metric_helpers.hpp" -#include "ie_plugin_config.hpp" #include #include #include @@ -23,8 +24,6 @@ #include #include #include -#include -#include #include "transformations/einsum_decomposition.hpp" #include "transformations/convert_pooling_to_reduce.hpp" diff --git a/src/plugins/intel_gpu/src/runtime/kernels_cache.cpp b/src/plugins/intel_gpu/src/runtime/kernels_cache.cpp index ef2f46bc31a2a1..c16fb7e3e0ccd2 100644 --- a/src/plugins/intel_gpu/src/runtime/kernels_cache.cpp +++ b/src/plugins/intel_gpu/src/runtime/kernels_cache.cpp @@ -170,7 +170,7 @@ void kernels_cache::get_program_source(const kernels_code& kernels_source_code, kernels_cache::kernels_cache(engine& engine, const ExecutionConfig& config, uint32_t prog_id, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor, + std::shared_ptr task_executor, const std::vector& batch_header_str) : _engine(engine) , _task_executor(task_executor) @@ -426,7 +426,7 @@ void kernels_cache::build_all() { if (_task_executor && use_threads) { std::exception_ptr exception; - std::vector tasks; + std::vector tasks; for (size_t idx = 0; idx < batches.size(); idx++) { auto& batch = batches[idx]; tasks.push_back([this, &_build_engine, &batch, &exception] { @@ -437,7 +437,7 @@ void kernels_cache::build_all() { } }); } - _task_executor->runAndWait(tasks); + _task_executor->run_and_wait(tasks); tasks.clear(); if (exception) { @@ -583,7 +583,7 @@ void kernels_cache::load(BinaryInputBuffer& ib) { for (auto& p : err.getBuildLog()) { err_log += p.second + '\n'; } - IE_THROW() << err_log; + OPENVINO_THROW(err_log); } } diff --git a/src/plugins/intel_gpu/src/runtime/kernels_cache.hpp b/src/plugins/intel_gpu/src/runtime/kernels_cache.hpp index be1d51a770668f..3803125856aa00 100644 --- a/src/plugins/intel_gpu/src/runtime/kernels_cache.hpp +++ b/src/plugins/intel_gpu/src/runtime/kernels_cache.hpp @@ -18,7 +18,7 @@ #include #include -#include +#include "openvino/runtime/threading/cpu_streams_executor.hpp" #include "kernels_factory.hpp" #include "ocl/ocl_engine.hpp" @@ -75,7 +75,7 @@ class kernels_cache { private: static std::mutex _mutex; engine& _engine; - InferenceEngine::CPUStreamsExecutor::Ptr _task_executor; + std::shared_ptr _task_executor; ExecutionConfig _config; uint32_t _prog_id = 0; kernels_code _kernels_code; @@ -96,7 +96,7 @@ class kernels_cache { explicit kernels_cache(engine& engine, const ExecutionConfig& config, uint32_t prog_id, - InferenceEngine::CPUStreamsExecutor::Ptr task_executor = nullptr, + std::shared_ptr task_executor = nullptr, const std::vector& batch_header_str = {}); kernel::ptr get_kernel_from_cached_kernels(std::string id) const; std::vector get_kernels(kernel_impl_params params) const; diff --git a/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/roi_pooling.cpp b/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/roi_pooling.cpp index 467788035a7f78..474f74920d1775 100644 --- a/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/roi_pooling.cpp +++ b/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/roi_pooling.cpp @@ -144,7 +144,7 @@ class ROIPoolingLayerGPUTest : public testing::WithParamInterface(output_f * input_f, -1, 1); + auto weights_data_vec = rg.generate_random_1d(output_f * input_f, -1, 1); set_values(weights_data_input, weights_data_vec); cldnn::topology topology { diff --git a/src/plugins/intel_gpu/tests/unit/passes/kernels_cache_test.cpp b/src/plugins/intel_gpu/tests/unit/passes/kernels_cache_test.cpp index 547b3ac5984288..bbdb553d6098a8 100644 --- a/src/plugins/intel_gpu/tests/unit/passes/kernels_cache_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/passes/kernels_cache_test.cpp @@ -94,9 +94,9 @@ TEST(kernels_cache, reuse_kernel_for_static_model_01) { TEST(kernels_cache, sub_kernel_ordering_test) { auto& engine = get_test_engine(); ExecutionConfig config = get_test_default_config(engine); - InferenceEngine::CPUStreamsExecutor::Config task_executor_config("sub_kernel_ordering_test", 1); + ov::threading::IStreamsExecutor::Config task_executor_config("sub_kernel_ordering_test", 1); task_executor_config._streams = 2; - auto executor = std::make_shared(task_executor_config); + auto executor = std::make_shared(task_executor_config); const size_t num_kernels = 9; auto _kernels_cache = std::unique_ptr(new kernels_cache(engine, config, 0, executor)); std::vector entry_point_list; diff --git a/src/plugins/intel_gpu/tests/unit/test_cases/multiple_streams_gpu_test.cpp b/src/plugins/intel_gpu/tests/unit/test_cases/multiple_streams_gpu_test.cpp index b6374f385400f8..66af43473b73c3 100644 --- a/src/plugins/intel_gpu/tests/unit/test_cases/multiple_streams_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/test_cases/multiple_streams_gpu_test.cpp @@ -21,9 +21,9 @@ using namespace ::tests; TEST(multistream_gpu, basic) { const int num_streams = 2; - auto task_config = InferenceEngine::CPUStreamsExecutor::Config(); + auto task_config = ov::threading::IStreamsExecutor::Config(); task_config._streams = num_streams; - auto task_executor = std::make_shared(task_config); + auto task_executor = std::make_shared(task_config); auto& engine = get_test_engine(); ExecutionConfig config = get_test_default_config(engine); @@ -53,7 +53,7 @@ TEST(multistream_gpu, basic) { streams.push_back(networks[i]->get_stream_ptr()); } - std::vector tasks; + std::vector tasks; for (size_t i = 0; i < num_streams; i++) { tasks.push_back([&networks, &streams, i, &engine] { auto cfg = get_test_default_config(engine); @@ -85,7 +85,7 @@ TEST(multistream_gpu, basic) { }); } - task_executor->runAndWait(tasks); + task_executor->run_and_wait(tasks); tasks.clear(); networks.clear(); } diff --git a/src/plugins/intel_gpu/tests/unit/test_cases/scatter_nd_update_gpu_test.cpp b/src/plugins/intel_gpu/tests/unit/test_cases/scatter_nd_update_gpu_test.cpp index d02a4f9a313bff..f2e905a5ff959f 100644 --- a/src/plugins/intel_gpu/tests/unit/test_cases/scatter_nd_update_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/test_cases/scatter_nd_update_gpu_test.cpp @@ -254,7 +254,7 @@ TEST_P(scatter_nd_update_random_test, random) else if (param.input_type == data_types::f32) this->execute(param, false); else - IE_THROW() << "unidentified data type"; + OPENVINO_THROW("unidentified data type"); } INSTANTIATE_TEST_SUITE_P(scatter_nd_update_gpu_random_test_fp32_bsv32_fsv16_4d_rank_1, @@ -4588,7 +4588,7 @@ TEST_P(scatter_nd_update_random_test, random_cached) else if (param.input_type == data_types::f32) this->execute(param, true); else - IE_THROW() << "unidentified data type"; + OPENVINO_THROW("unidentified data type"); } #endif TEST(scatter_nd_update_gpu_fp16, d222222_i211111_cached) { diff --git a/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.cpp b/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.cpp index fdccc5c9d8ed89..3f359b46654a89 100644 --- a/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.cpp +++ b/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.cpp @@ -399,9 +399,9 @@ double default_tolerance(data_types dt) { case data_types::u8: return 1.5; default: - IE_THROW() << "Unknown"; + OPENVINO_THROW("Unknown"); } - IE_THROW() << "Unknown"; + OPENVINO_THROW("Unknown"); } cldnn::format generic_test::get_plain_format_for(const cldnn::format input) { diff --git a/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.h b/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.h index 18ea217f362947..76e8ff24aaca09 100644 --- a/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.h +++ b/src/plugins/intel_gpu/tests/unit/test_utils/test_utils.h @@ -528,8 +528,8 @@ std::vector get_output_values_to_float(cldnn::network& net, const cldnn:: auto ptr = output.get_memory(); cldnn::mem_lock mem(ptr, net.get_stream()); if (ptr->get_layout().data_type != cldnn::type_to_data_type::value) - IE_THROW() << "target type " << cldnn::data_type_traits::name(cldnn::type_to_data_type::value) - << " mismatched with actual type " << cldnn::data_type_traits::name(ptr->get_layout().data_type); + OPENVINO_THROW("target type ", cldnn::data_type_traits::name(cldnn::type_to_data_type::value), + " mismatched with actual type ", cldnn::data_type_traits::name(ptr->get_layout().data_type)); for (size_t i = 0; i < std::min(max_cnt, ptr->get_layout().count()); i++) ret.push_back(mem[i]); return ret; @@ -550,7 +550,7 @@ inline std::vector get_output_values_to_float(cldnn::network& net, const case cldnn::data_types::i64: return get_output_values_to_float(net, output, max_cnt); default: - IE_THROW() << "Unknown output data_type"; + OPENVINO_THROW( "Unknown output data_type"); } } diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 81dc9eb2703f9f..93b985350d2c1b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -6,6 +6,9 @@ set(IE_TESTS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) enable_testing() +ie_option(ENABLE_CONFORMANCE_PGQL "Enables support of PostgreSQL-based reporting from test tools" OFF) +mark_as_advanced(FORCE ENABLE_CONFORMANCE_PGQL) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") ie_add_compiler_flags(/wd4244) ie_add_compiler_flags(/wd4267) diff --git a/src/tests/functional/plugin/conformance/test_runner/conformance_infra/CMakeLists.txt b/src/tests/functional/plugin/conformance/test_runner/conformance_infra/CMakeLists.txt index 045e4281d8380a..e286f27b5a38ac 100644 --- a/src/tests/functional/plugin/conformance/test_runner/conformance_infra/CMakeLists.txt +++ b/src/tests/functional/plugin/conformance/test_runner/conformance_infra/CMakeLists.txt @@ -20,4 +20,8 @@ addIeTarget( funcSharedTests ) +if(ENABLE_CONFORMANCE_PGQL) + target_compile_definitions(${TARGET_NAME} PRIVATE ENABLE_CONFORMANCE_PGQL) +endif() + ie_faster_build(${TARGET_NAME} UNITY) diff --git a/src/tests/functional/plugin/conformance/test_runner/conformance_infra/src/main.cpp b/src/tests/functional/plugin/conformance/test_runner/conformance_infra/src/main.cpp index 646c7cdf93859c..3b33de517f09f4 100644 --- a/src/tests/functional/plugin/conformance/test_runner/conformance_infra/src/main.cpp +++ b/src/tests/functional/plugin/conformance/test_runner/conformance_infra/src/main.cpp @@ -15,12 +15,43 @@ #include "gflag_config.hpp" #include "conformance.hpp" - +#ifdef ENABLE_CONFORMANCE_PGQL +# include "common_test_utils/postgres_link.hpp" + +void RegisterTestCustomQueries(void) { + std::map& extTestQueries = *::PostgreSQLLink::get_ext_test_queries(); + std::map& extTestNames = *::PostgreSQLLink::get_ext_test_names(); + + std::string testName("checkPluginImplementation"); + extTestQueries[testName + "_ON_START"] = + "OpImplCheck_CheckPluginImpl($__test_id, '$opName', '$opSet', " + "'$targetDevice', '$targetDeviceArch', '$targetDeviceName', '$config', $__is_temp)"; + extTestQueries[testName + "_ON_END"] = "OpImplCheck_CheckPluginImpl($__test_ext_id, $__test_id)"; + extTestQueries[testName + "_ON_REFUSE"] = + "OpImplCheck_CheckPluginImpl($__test_id)"; // Query expected in case of a refused results + extTestNames[testName] = "$opName"; + + testName = "ReadIR"; + extTestQueries[testName + "_ON_START"] = + "ReadIRTest_ReadIR($__test_id, '$opName', '$opSet', '$Type', " + "'$targetDevice', '$targetDeviceArch', '$targetDeviceName', '$hashXml', '$pathXml', '$config', " + "'$caseType', '$irWeight', $__is_temp)"; + extTestQueries[testName + "_ON_END"] = "ReadIRTest_ReadIR($__test_ext_id, $__test_id)"; + extTestQueries[testName + "_ON_REFUSE"] = + "ReadIRTest_ReadIR($__test_id)"; // Query expected in case of a refused results + extTestNames[testName] = "$opName"; +} +#endif #include "functional_test_utils/crash_handler.hpp" using namespace ov::test::conformance; int main(int argc, char* argv[]) { +#ifdef ENABLE_CONFORMANCE_PGQL + ::PostgreSQLLink::set_manual_start(true); + RegisterTestCustomQueries(); +#endif + // Workaround for Gtest + Gflag std::vector argv_gflags_vec; int argc_gflags = 0; @@ -50,7 +81,7 @@ int main(int argc, char* argv[]) { ov::test::utils::OpSummary::setOutputFolder(FLAGS_output_folder); ov::test::utils::OpSummary::setSaveReportTimeout(FLAGS_save_report_timeout); { - auto &apiSummary = ov::test::utils::ApiSummary::getInstance(); + auto& apiSummary = ov::test::utils::ApiSummary::getInstance(); apiSummary.setDeviceName(FLAGS_device); } if (FLAGS_shape_mode == std::string("static")) { @@ -58,7 +89,9 @@ int main(int argc, char* argv[]) { } else if (FLAGS_shape_mode == std::string("dynamic")) { ov::test::conformance::shapeMode = ov::test::conformance::ShapeMode::DYNAMIC; } else if (FLAGS_shape_mode != std::string("")) { - throw std::runtime_error("Incorrect value for `--shape_mode`. Should be `dynamic`, `static` or ``. Current value is `" + FLAGS_shape_mode + "`"); + throw std::runtime_error( + "Incorrect value for `--shape_mode`. Should be `dynamic`, `static` or ``. Current value is `" + + FLAGS_shape_mode + "`"); } CommonTestUtils::CrashHandler::SetUpTimeout(FLAGS_test_timeout); @@ -72,8 +105,8 @@ int main(int argc, char* argv[]) { ov::test::conformance::targetPluginName = FLAGS_plugin_lib_name.c_str(); } if (!FLAGS_skip_config_path.empty()) { - ov::test::conformance::disabledTests = CommonTestUtils::readListFiles( - CommonTestUtils::splitStringByDelimiter(FLAGS_skip_config_path)); + ov::test::conformance::disabledTests = + CommonTestUtils::readListFiles(CommonTestUtils::splitStringByDelimiter(FLAGS_skip_config_path)); } if (!FLAGS_config_path.empty()) { ov::test::conformance::pluginConfig = ov::test::conformance::readPluginConfig(FLAGS_config_path); @@ -101,7 +134,7 @@ int main(int argc, char* argv[]) { // killed by external signal(SIGINT, exernalSignalHandler); - signal(SIGTERM , exernalSignalHandler); + signal(SIGTERM, exernalSignalHandler); signal(SIGSEGV, exernalSignalHandler); signal(SIGABRT, exernalSignalHandler); return RUN_ALL_TESTS(); diff --git a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check.cpp b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check.cpp index 42525c36e3600e..4e876974966479 100644 --- a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check.cpp +++ b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check.cpp @@ -9,6 +9,8 @@ #include "op_impl_check/op_impl_check.hpp" #include "functional_test_utils/crash_handler.hpp" +#include "common_test_utils/postgres_link.hpp" + namespace ov { namespace test { namespace subgraph { @@ -17,6 +19,29 @@ void OpImplCheckTest::SetUp() { std::pair> funcInfo; std::tie(funcInfo, targetDevice, configuration) = this->GetParam(); function = funcInfo.second; + +#ifdef ENABLE_CONFORMANCE_PGQL + // Updating data in runtime. Should be set before possible call of a first GTEST status + auto pgLink = this->GetPGLink(); + if (pgLink) { + auto devNameProperty = core->get_property(this->targetDevice, "FULL_DEVICE_NAME"); + auto devName = devNameProperty.is() ? devNameProperty.as() : ""; + pgLink->set_custom_field("targetDeviceName", devName, true); + if (this->targetDevice == "CPU") { + pgLink->set_custom_field("targetDevice", this->targetDevice, true); + pgLink->set_custom_field("targetDeviceArch", devName.find("ARM") != std::string::npos ? "arm" : "", true); + } else if (this->targetDevice == "GPU") { + if (devName.find("dGPU") != std::string::npos) { + pgLink->set_custom_field("targetDevice", "DGPU", true); + } else { + pgLink->set_custom_field("targetDevice", this->targetDevice, true); + } + } else { + pgLink->set_custom_field("targetDevice", this->targetDevice, true); + } + pgLink->manual_start(); + } +#endif } std::string OpImplCheckTest::getTestCaseName(const testing::TestParamInfo &obj) { diff --git a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir.cpp b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir.cpp index a7c58512fec26c..4275d05622dec8 100644 --- a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir.cpp +++ b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir.cpp @@ -20,6 +20,8 @@ #include "conformance.hpp" #include "read_ir_test/read_ir.hpp" +#include "common_test_utils/postgres_link.hpp" + #include namespace ov { @@ -227,6 +229,74 @@ void ReadIRTest::SetUp() { } } } + +#ifdef ENABLE_CONFORMANCE_PGQL + // Updating data in runtime. Should be set before possible call of a first GTEST status + auto pgLink = this->GetPGLink(); + if (pgLink) { + auto devNameProperty = core->get_property(this->targetDevice, "FULL_DEVICE_NAME"); + auto devName = devNameProperty.is() ? devNameProperty.as() : ""; + pgLink->set_custom_field("targetDeviceName", devName, true); + if (this->targetDevice == "CPU") { + pgLink->set_custom_field("targetDevice", this->targetDevice, true); + pgLink->set_custom_field("targetDeviceArch", devName.find("ARM") != std::string::npos ? "arm" : "", true); + } else if (this->targetDevice == "GPU") { + if (devName.find("dGPU") != std::string::npos) { + pgLink->set_custom_field("targetDevice", "DGPU", true); + } else { + pgLink->set_custom_field("targetDevice", this->targetDevice, true); + } + } else { + pgLink->set_custom_field("targetDevice", this->targetDevice, true); + } + pgLink->set_custom_field("caseType", hasDynamic ? "dynamic" : "static"); + pgLink->set_custom_field("irWeight", std::to_string(rel_influence_coef), true); + + // Do not store waste results + if (hasDynamic && ov::test::conformance::shapeMode == ov::test::conformance::ShapeMode::STATIC) { + pgLink->set_refuse_result(); + } else if (!hasDynamic && ov::test::conformance::shapeMode == ov::test::conformance::ShapeMode::DYNAMIC) { + pgLink->set_refuse_result(); + } + + auto splittedFilename = CommonTestUtils::splitStringByDelimiter(path_to_model, CommonTestUtils::FileSeparator); + std::reverse(splittedFilename.begin(), splittedFilename.end()); + + // Try to resolve missing info + if (splittedFilename.size() > 2) { + auto pos = splittedFilename[2].find('-'); + std::string op_name = "", op_version = "opset"; + if (pos != std::string::npos) { + op_name = splittedFilename[2].substr(0, pos); + op_version += splittedFilename[2].substr(pos + 1); + if (ov::test::conformance::unique_ops.find(op_name) != ov::test::conformance::unique_ops.end() && + std::find(ov::test::conformance::unique_ops[op_name].begin(), + ov::test::conformance::unique_ops[op_name].end(), + op_version) != ov::test::conformance::unique_ops[op_name].end()) { + pgLink->set_custom_field("opName", op_name, true); + pgLink->set_custom_field("opSet", op_version, true); + } + } else { + for (const auto& path_part : splittedFilename) { + if (ov::test::conformance::unique_ops.find(path_part) != ov::test::conformance::unique_ops.end()) { + op_name = path_part; + break; + } + } + if (op_name.length() > 0) { + for (const auto& node : function->get_ordered_ops()) { + if (node->get_type_name() == op_name) { + op_version = node->get_type_info().version_id; + pgLink->set_custom_field("opSet", op_version, true); + } + } + } + } + } + pgLink->manual_start(); + } +#endif + if (hasDynamic && ov::test::conformance::shapeMode == ov::test::conformance::ShapeMode::STATIC) { GTEST_SKIP() << "Dynamic cases are skipped according `shape_mode`"; } else if (!hasDynamic && ov::test::conformance::shapeMode == ov::test::conformance::ShapeMode::DYNAMIC) { diff --git a/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/run_parallel.py b/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/run_parallel.py index 2f04ef30776019..21eba795355c49 100644 --- a/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/run_parallel.py +++ b/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/run_parallel.py @@ -583,6 +583,9 @@ def __save_log(logs_dir, dir, test_name): break if not dir is None: break + # Collect PostgreSQL reporting errors and warnings + if (constants.PG_ERR in line) or (constants.PG_WARN in line): + test_log.append(line) if test_name is not None: test_log.append(line) if dir: diff --git a/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py b/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py index 798a08862cacb9..2a503977c7091f 100644 --- a/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py +++ b/src/tests/ie_test_utils/functional_test_utils/layer_tests_summary/utils/constants.py @@ -13,6 +13,8 @@ RUN = "[ RUN ]" GTEST_FILTER = "Google Test filter = " DISABLED_PREFIX = "DISABLED_" +PG_ERR = "PG ERROR" +PG_WARN = "PG WARN" REF_COEF = "[ CONFORMANCE ] Influence coefficient: " IS_WIN = "windows" in platform or "win32" in platform diff --git a/src/tests/ie_tsan.supp b/src/tests/ie_tsan.supp index b659119dffb8e6..d99d602cbecde0 100644 --- a/src/tests/ie_tsan.supp +++ b/src/tests/ie_tsan.supp @@ -14,3 +14,7 @@ race:^GNAPluginNS::supported_values[abi:cxx11]$ # Issue 91368 race:libopenvino_gapi_preproc.so + +# Issue 114114 ThreadSanitizer: signal-unsafe call inside of a signal +# Suppress it since it's caused by signal handler from tests utilities that not uses threads +signal:src/tests/ie_test_utils/functional_test_utils/src/crash_handler.cpp \ No newline at end of file diff --git a/src/tests/test_utils/common_test_utils/CMakeLists.txt b/src/tests/test_utils/common_test_utils/CMakeLists.txt index 89b2ddaac46728..9687628bec4434 100644 --- a/src/tests/test_utils/common_test_utils/CMakeLists.txt +++ b/src/tests/test_utils/common_test_utils/CMakeLists.txt @@ -3,13 +3,25 @@ # function(add_common_utils ADD_TARGET_NAME) + list(APPEND TARGET_EXCLUDED_SOURCE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/tests + ) + if(NOT ENABLE_CONFORMANCE_PGQL) + list(APPEND TARGET_EXCLUDED_SOURCE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/common_test_utils/postgres_link.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/common_test_utils/postgres_helpers.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/postgres_link.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/postgres_helpers.cpp + ) + endif() + # create target addIeTarget( NAME ${ADD_TARGET_NAME} TYPE STATIC ROOT ${CMAKE_CURRENT_SOURCE_DIR} EXCLUDED_SOURCE_PATHS - ${CMAKE_CURRENT_SOURCE_DIR}/tests + ${TARGET_EXCLUDED_SOURCE_PATHS} ADD_CPPLINT DEVELOPER_PACKAGE tests @@ -29,6 +41,10 @@ function(add_common_utils ADD_TARGET_NAME) ) + if(ENABLE_CONFORMANCE_PGQL) + target_compile_definitions(${ADD_TARGET_NAME} PUBLIC ENABLE_CONFORMANCE_PGQL) + endif() + # USE_STATIC_IE is passed if(ARGN) target_link_libraries(${ADD_TARGET_NAME} PRIVATE inference_engine_s) @@ -63,6 +79,7 @@ function(add_common_utils ADD_TARGET_NAME) target_include_directories(${ADD_TARGET_NAME} SYSTEM PUBLIC ${IE_TESTS_ROOT}/ie_test_utils) target_compile_definitions(${ADD_TARGET_NAME} PUBLIC ${ARGN}) + endfunction() # Keep old name so that library can be used from VPU repo diff --git a/src/tests/test_utils/common_test_utils/include/common_test_utils/postgres_helpers.hpp b/src/tests/test_utils/common_test_utils/include/common_test_utils/postgres_helpers.hpp new file mode 100644 index 00000000000000..257fb9fe1d88d3 --- /dev/null +++ b/src/tests/test_utils/common_test_utils/include/common_test_utils/postgres_helpers.hpp @@ -0,0 +1,278 @@ +// Copyright (C) 2022-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once +#include +#include + +#include +#include +#include +#include +#include + +namespace CommonTestUtils { + +/// \brief Enables dynamic load of libpq module +#define PGQL_DYNAMIC_LOAD +/// \brief Enables extended debug messages to the stderr +#define PGQL_DEBUG +#undef PGQL_DEBUG + +extern const char* PGQL_ENV_CONN_NAME; // Environment variable with connection settings +extern const char* PGQL_ENV_SESS_NAME; // Environment variable identifies current session +extern const char* PGQL_ENV_RUN_NAME; // Environment variable with external run id +extern const char* PGQL_ENV_RLVL_NAME; // Environment variable identifies reporting + +typedef enum { + /// \brief Most careful reporting, but slowest + REPORT_LVL_DEFAULT = 0, + /// \brief Reports less information about each test case and accumulates it in joined query which will + /// be executed on TestSuiteEnd + REPORT_LVL_FAST, + /// \brief Reports only suite states, no detailed info about test cases will be available + REPORT_LVL_SUITES_ONLY +} PostgreSQLReportingLevel; + +#if !defined(_WIN32) && !defined(__APPLE__) +# ifndef __USE_POSIX +# define __USE_POSIX +# endif +# include +# include +# include +# include +#elif defined(__APPLE__) +# include +# include +# include +# include +# include +# ifndef HOST_NAME_MAX +# define HOST_NAME_MAX MAXHOSTNAMELEN +# endif +#endif + +#ifndef PGQL_DYNAMIC_LOAD +# include "libpq-fe.h" +#else +# ifdef _WIN32 +# include +# else +# include +typedef void* HMODULE; +# endif +typedef enum { + CONNECTION_OK, + CONNECTION_BAD, + CONNECTION_STARTED, + CONNECTION_MADE, + CONNECTION_AWAITING_RESPONSE, + CONNECTION_AUTH_OK, + CONNECTION_SETENV, + CONNECTION_SSL_STARTUP, + CONNECTION_NEEDED, + CONNECTION_CHECK_WRITABLE, + CONNECTION_CONSUME, + CONNECTION_GSS_STARTUP, + CONNECTION_CHECK_TARGET, + CONNECTION_CHECK_STANDBY +} ConnStatusType; + +typedef enum { + PGRES_EMPTY_QUERY = 0, + PGRES_COMMAND_OK, + PGRES_TUPLES_OK, + PGRES_COPY_OUT, + PGRES_COPY_IN, + PGRES_BAD_RESPONSE, + PGRES_NONFATAL_ERROR, + PGRES_FATAL_ERROR, + PGRES_COPY_BOTH, + PGRES_SINGLE_TUPLE, + PGRES_PIPELINE_SYNC, + PGRES_PIPELINE_ABORTED +} ExecStatusType; + +struct PGconn; +struct PGresult; + +typedef PGconn* (*fnPQconnectdb)(const char* conninfo); +typedef ConnStatusType (*fnPQstatus)(const PGconn* conn); +typedef size_t (*fnPQescapeStringConn)(PGconn* conn, char* to, const char* from, size_t length, int* error); +typedef void (*fnPQfinish)(PGconn* conn); +typedef char* (*fnPQerrorMessage)(const PGconn* conn); + +typedef PGresult* (*fnPQexec)(PGconn* conn, const char* query); +typedef ExecStatusType (*fnPQresultStatus)(const PGresult* res); +typedef char* (*fnPQgetvalue)(const PGresult* res, int tup_num, int field_num); +typedef int (*fnPQgetisnull)(const PGresult* res, int row_number, int column_number); +typedef void (*fnPQclear)(PGresult* res); +typedef char* (*fnPQresultErrorMessage)(const PGresult* res); + +extern fnPQconnectdb PQconnectdb; +extern fnPQescapeStringConn PQescapeStringConn; +extern fnPQstatus PQstatus; +extern fnPQfinish PQfinish; +extern fnPQerrorMessage PQerrorMessage; + +extern fnPQexec PQexec; +extern fnPQresultStatus PQresultStatus; +extern fnPQgetvalue PQgetvalue; +extern fnPQgetisnull PQgetisnull; +extern fnPQclear PQclear; +extern fnPQresultErrorMessage PQresultErrorMessage; +#endif + +extern char* PGPrefix(const char* text, ::testing::internal::GTestColor color); + +#define PG_ERR PGPrefix("[ PG ERROR ] ", ::testing::internal::COLOR_RED) +#define PG_WRN PGPrefix("[ PG WARN ] ", ::testing::internal::COLOR_YELLOW) +#define PG_INF PGPrefix("[ PG INFO ] ", ::testing::internal::COLOR_GREEN) + +/// \brief Count of tries when serialization error is detected after query +const uint8_t serializationTriesCount = 30; // Pause between each attempt is not less than 50ms + +/* + PostgreSQL Handler class members +*/ +/// \brief This manager is using for a making correct removal of PGresult object. +/// shared/unique_ptr cannot be used due to incomplete type of PGresult. +/// It is minimal implementatio which is compatible with shared/uinque_ptr +/// interface usage (reset, get) +class PGresultHolder { + PGresult* _ptr; + volatile uint32_t* refCounter; + + inline void decRefCounter(void) { + if (_ptr != nullptr && refCounter != nullptr) { + if (*refCounter > 0) { + --*refCounter; + } + if (*refCounter == 0) { + delete refCounter; + PQclear(_ptr); + _ptr = nullptr; + refCounter = nullptr; + } + } + } + +public: + PGresultHolder(void) : _ptr(nullptr), refCounter(nullptr) {} + PGresultHolder(PGresult* ptr) : _ptr(ptr), refCounter(new uint32_t()) { + *refCounter = 1; + } + PGresultHolder(const PGresultHolder& object) { + _ptr = object._ptr; + refCounter = object.refCounter; + ++*refCounter; + } + PGresultHolder& operator=(const PGresultHolder& object) { + if (_ptr != object._ptr) { + decRefCounter(); + _ptr = object._ptr; + refCounter = object.refCounter; + ++*refCounter; + } + return *this; + } + void reset(PGresult* ptr) { + if (_ptr != ptr) { + decRefCounter(); + refCounter = new uint32_t(); + *refCounter = 1; + _ptr = ptr; + } + } + PGresult* get(void) { + return _ptr; + } + ~PGresultHolder(void) { + decRefCounter(); + _ptr = nullptr; + refCounter = nullptr; + } +}; + +/// \briaf This class implements singleton which operates with a connection to PostgreSQL server. +class PostgreSQLConnection { +#ifdef PGQL_DYNAMIC_LOAD + std::shared_ptr modLibPQ; + bool load_libpq(void); +#endif + PGconn* m_active_connection; + + PostgreSQLConnection(void) : m_active_connection(nullptr), m_is_connected(false) {} + + /// \brief Prohobit creation outsize of class, need to make a Singleton + PostgreSQLConnection(const PostgreSQLConnection&) = delete; + PostgreSQLConnection& operator=(const PostgreSQLConnection&) = delete; + +public: + bool m_is_connected; + + static std::shared_ptr get_instance(void); + bool initialize(void); + /// \brief Make a common query to a server. Result will be returned as self-desctructable pointer. But application + /// should check result pointer isn't a nullptr. And result status by itself. \param[in] query SQL query to a server + /// \returns Object which keep pointer on received PGresult. It contains nullptr in case of any error. + PGresultHolder common_query(const char* query); + + /// \brief Queries a server. Result will be returned as self-desctructable pointer. But application should check + /// result pointer isn't a nullptr. + /// \param[in] query SQL query to a server + /// \param[in] expectedStatus Query result will be checked for passed status, if it isn't equal - result pointer + /// \param[in] smartRetry Useful for transactional queries, allows to call non-transactional part in case + /// of transactional errors + /// will be nullptr. \returns Object which keep pointer on received PGresult. It contains nullptr in case of any + /// error. + PGresultHolder query(const char* query, + const ExecStatusType expectedStatus = PGRES_TUPLES_OK, + const bool smartRetry = false); + + /// \brief Tries to reconnect in case of connection issues (usual usage - connection timeout). + void try_reconnect(void); + + PGconn* get_connection(void) const { + return this->m_active_connection; + } + ~PostgreSQLConnection(void); +}; +extern std::shared_ptr connection; + +namespace PostgreSQLHelpers { +/// \brief This method is used for parsing serialized value_param string. +/// Known limitations: +/// It doesn't read values in inner tuples/arrays/etc. +std::vector parse_value_param(std::string text); + +/// \brief Function returns OS version in runtime. +/// \returns String which contains OS version +std::string get_os_version(void); + +/// \brief Function returns executable name of current application. +/// \returs File name as a std::string +std::string get_executable_name(void); + +/// \brief Cross-platform implementation of getting host name +/// \returns String with host name or "NOT_FOUND" in case of error +std::string get_hostname(void); + +// Procedure uses for possible customization of addint key=value pairs +void add_pair(std::map& keyValues, const std::string& key, const std::string& value); + +// Function parses test name for key=value pairs +bool parse_test_name(const char* line, std::map& keyValues); + +/// \brief Compiles string and replaces variables defined as $[0-9A-Za-z-_] by values from +/// provided key=value map. Replaces by blank in case of key isn't found in the map. +/// \param[in] srcStr String contains variables +/// \param[in] keyValue Key=value map with variable values +/// \param[out] result String for result +/// \returns Returns true if all input string was compiled, false in case of any compilation error +bool compile_string(const std::string& srcStr, const std::map& keyValue, std::string& result); +} // namespace PostgreSQLHelpers + +} // namespace CommonTestUtils diff --git a/src/tests/test_utils/common_test_utils/include/common_test_utils/postgres_link.hpp b/src/tests/test_utils/common_test_utils/include/common_test_utils/postgres_link.hpp new file mode 100644 index 00000000000000..cfa8ea2c1f9909 --- /dev/null +++ b/src/tests/test_utils/common_test_utils/include/common_test_utils/postgres_link.hpp @@ -0,0 +1,99 @@ +// Copyright (C) 2022-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include +#include + +namespace CommonTestUtils { + +/// \brief Class-container for PostgreSQLLink-specific data, declared and implemented +/// out of header. Definition mustn't be a part of this header. +class PostgreSQLCustomData; + +/// \brief Class incapsulates logic for communication with PostgreSQL from test-side +/// Most logic should be implemented in corresponding postgres_link.cpp +class PostgreSQLLink { + /// \brief parentObject should store pointer to a parent object to be able + /// access to some specific parent's fields, if needed. Isn't mandatory. + void* parentObject; + /// \brief customData contains internal object state. It mustn't be accessible + /// from outside. + PostgreSQLCustomData* customData; + +public: + /// \brief Simple constructor + PostgreSQLLink(void); + /// \brief Constructor allows to store unsafe pointer to parent object. Might be user + /// as external identifier. + /// \param[in] ptrParentObject Unsafe pointer to a parent object + PostgreSQLLink(void* ptrParentObject); + /// \brief Simple destructor + ~PostgreSQLLink(void); + + /// \brief Returns pointer to stored parentObject. + /// \returns Unsafe pointer to parent object. + void* get_parent_object(void) { + return this->parentObject; + } + /// \brief Replaces stored pointer on parent object. Might be nullptr to reset stored pointer. + /// \param[in] ptrParentObject Unsafe pointer to a parent object + void set_parent_object(void* ptrParentObject) { + this->parentObject = ptrParentObject; + } + /// \brief Sets custom field for current test instance + /// \param[in] fieldName Field name, any applicable string + /// \param[in] fieldValue Value to store as field value, any applicable string + /// \param[in] rewrite Flag defines behaviour in case field already exists. Rewrites if true. + /// \returns True if value has been stored, false otherwise. + bool set_custom_field(const std::string fieldName, const std::string fieldValue, const bool rewrite = false) const; + /// \brief Gets custom field value for current test instance + /// \param[in] fieldName Field name, any applicable string + /// \param[in] defaultValue Value should be returned in case of value wasn't stored, any applicable string + /// \returns Stored value or defaultValue otherwise. + std::string get_custom_field(const std::string fieldName, const std::string defaultValue) const; + /// \brief Removes custom field for current test instance + /// \param[in] fieldName Field name, any applicable string + /// \returns True if value has been removed, false otherwise. + bool remove_custom_field(const std::string fieldName) const; + /// \brief Sets waste result flag which means do not store results + /// \param[in] value Value should be set, true is default + void set_refuse_result(bool value = true) const; + /// \brief Sets manual start flag which allows initiate storing results manually + /// IMPORTANT: It cannot change workflow of current execution, only for + /// further calls. + /// \param[in] value Value should be set, true is default + void set_manual_start(bool value = true) const; + /// \brief Initiate a TestCase start procedure which puts information into the table + /// Works only if previously called set_manual_start() + void manual_start(void) const; +}; + +} // namespace CommonTestUtils + +#ifdef ENABLE_CONFORMANCE_PGQL +namespace PostgreSQLLink { +/// \brief Returns pointer on a global map which contains pairs of Extended Test Queries +/// Each pair has test name as a key and SQL-query as a value. +/// Query can contain a variables started with $ and be replaced by an actual values +/// Variables are parsed from test name. +extern std::map* get_ext_test_queries(void); +/// \brief Returns pointer on a global map which contains pairs of Extended Test Names +/// Each pair has test name as a key and string as a value. +/// Query can contain a variables started with $ and be replaced by an actual values +/// Variables are parsed from test name. +extern std::map* get_ext_test_names(void); +/// \brief Sets manual start flag which allows initiate storing results manually. +/// It may affect workflow of further execution if called before OnStartTestCase event +/// will be called. +/// \param[in] value Value should be set, true is default +extern void set_manual_start(bool value = true); +/// \brief Initiate a TestCase start procedure which puts information into the table +/// Works only if previously called set_manual_start() +void manual_start(void); +}; // namespace PostgreSQLLink +#endif diff --git a/src/tests/test_utils/common_test_utils/include/common_test_utils/test_common.hpp b/src/tests/test_utils/common_test_utils/include/common_test_utils/test_common.hpp index 5663be01db5553..eaff54c451361a 100644 --- a/src/tests/test_utils/common_test_utils/include/common_test_utils/test_common.hpp +++ b/src/tests/test_utils/common_test_utils/include/common_test_utils/test_common.hpp @@ -10,8 +10,18 @@ #include "common_test_utils/test_assertions.hpp" namespace CommonTestUtils { +class PostgreSQLLink; class TestsCommon : virtual public ::testing::Test { + /// \brief Holds a pointer on PostgreSQL interface implementation (see postgres_link.hpp). + /// + /// Better to keep it without #ifdef condition to prevent complex issues with + /// unexpected stack corruptions/segmentation faults in case this header + /// uses in a project, which doesn't define expected definition. + /// But if no handler of the variable is linked to a final runtime, then it + /// will show an assert if some code tries to use it by a corresponding getter. + PostgreSQLLink* PGLink; + protected: TestsCommon(); ~TestsCommon() override; @@ -19,6 +29,23 @@ class TestsCommon : virtual public ::testing::Test { static std::string GetTimestamp(); std::string GetTestName() const; std::string GetFullTestName() const; + + /// \brief Returns a pointer on a PostgreSQL interface implementation (use postgres_link.hpp to + /// get an access to a interface properties). + /// + /// If project supported it - it should be mandatory available. Otherwise assert will + /// show an error. If project doesn't support it - it just will return a nullptr. + /// Behaviour might be carefully changed by removing #ifdef condition. + /// A removing the condition might be useful to find where GetPGLink is used + /// by a wrong behaviour. + /// \returns If object supports PostgreSQL reporting, then the method returns a pointer on + /// PostgreSQL interface implementation, otherwise - shows an assert or return a nullptr. + PostgreSQLLink* GetPGLink() { +#ifdef ENABLE_CONFORMANCE_PGQL + assert(this->PGLink != nullptr); +#endif + return this->PGLink; + } }; } // namespace CommonTestUtils diff --git a/src/tests/test_utils/common_test_utils/src/postgres_helpers.cpp b/src/tests/test_utils/common_test_utils/src/postgres_helpers.cpp new file mode 100644 index 00000000000000..783553af1982cd --- /dev/null +++ b/src/tests/test_utils/common_test_utils/src/postgres_helpers.cpp @@ -0,0 +1,628 @@ +// Copyright (C) 2022-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "common_test_utils/postgres_helpers.hpp" + +namespace CommonTestUtils { + +const char* PGQL_ENV_CONN_NAME = "OV_POSTGRES_CONN"; // Environment variable with connection settings +const char* PGQL_ENV_SESS_NAME = "OV_TEST_SESSION_ID"; // Environment variable identifies current session +const char* PGQL_ENV_RUN_NAME = "OV_TEST_RUN_ID"; // Environment variable with external run id +const char* PGQL_ENV_RLVL_NAME = "OV_TEST_REPORT_LVL"; // Environment variable identifies reporting + // level: default ("", empty), "fast", "suite" +fnPQconnectdb PQconnectdb; +fnPQescapeStringConn PQescapeStringConn; +fnPQstatus PQstatus; +fnPQfinish PQfinish; +fnPQerrorMessage PQerrorMessage; + +fnPQexec PQexec; +fnPQresultStatus PQresultStatus; +fnPQgetvalue PQgetvalue; +fnPQgetisnull PQgetisnull; +fnPQclear PQclear; +fnPQresultErrorMessage PQresultErrorMessage; + +char* PGPrefix(const char* text, ::testing::internal::GTestColor color) { + ::testing::internal::ColoredPrintf(color, text); + return ""; +} + +PGresultHolder PostgreSQLConnection::common_query(const char* query) { +#ifdef PGQL_DEBUG + std::cerr << query << std::endl; +#endif + if (!m_is_connected) + return PGresultHolder(); + PGresultHolder result(PQexec(this->m_active_connection, query)); + // Connection could be closed by a timeout, we may try to reconnect once. + // We don't reconnect on each call because it may make testing significantly slow in + // case of connection issues. Better to finish testing with incomplete results and + // free a machine. Otherwise we will lose all results. + if (result.get() == nullptr) { + try_reconnect(); + // If reconnection attempt was successfull - let's try to set new query + if (m_is_connected) { + result.reset(PQexec(this->m_active_connection, query)); + } + } + if (result.get() == nullptr) { + std::cerr << PG_ERR << "Error while querying PostgreSQL\n"; + } + return result; +} + +PGresultHolder PostgreSQLConnection::query(const char* query, + const ExecStatusType expectedStatus, + const bool smartRetry) { + PGresultHolder result = common_query(query); + uint8_t queryCounter = 1; + size_t selectPos = smartRetry ? std::string::npos : std::string(query).find("SELECT"); + + while (result.get() != nullptr && queryCounter < serializationTriesCount) { + ExecStatusType execStatus = PQresultStatus(result.get()); + if (execStatus == expectedStatus) { + break; + } + std::string errStr = PQresultErrorMessage(result.get()); + std::cerr << PG_WRN << "Received unexpected result (" << static_cast(execStatus) + << ") from PostgreSQL, expected: " << static_cast(expectedStatus) << std::endl; + + // After transactional queries were introduced - we need to check error message and try + // do a query again if it is expected serialization error. + // More about serialization: https://www.postgresql.org/docs/9.5/transaction-iso.html + if (errStr.find("could not serialize access") != std::string::npos || + errStr.find("current transaction is aborted") != std::string::npos) { + std::cerr << PG_WRN << "Serialization error: " << errStr + << "\nTrying again, try attempt: " << static_cast(queryCounter++) << std::endl; + uint32_t waitTime = 50 + static_cast(std::rand()) % 150; +#ifdef _WIN32 + Sleep(waitTime); // Wait some time for the next attempt +#else + struct timespec waitTimeTS = {0, waitTime * 1000}; + if (nanosleep(&waitTimeTS, &waitTimeTS) != 0) { + std::cerr << PG_WRN << "nanosleep returned value != 0\n"; + } +#endif + // We may have some connection issues, each tenth step try to reconnect + if (smartRetry && (queryCounter % 10) == 0) { + try_reconnect(); + } + // Each fifth step it tries to call non-transactional part of query + if (smartRetry && selectPos != std::string::npos && (queryCounter % 5) == 0) { + std::cerr << PG_WRN << "Sending a request with no transactional part\n"; + result = common_query(query + selectPos); + continue; + } + result = common_query(query); + } else { + std::cerr << PG_ERR << "Error message: " << errStr << std::endl; + result.reset(nullptr); + } + } + if (queryCounter >= serializationTriesCount) { + std::cerr << PG_ERR << "Cannot execute query due to serialization error, failing" << std::endl; + result.reset(nullptr); + } + return result; +} + +/// \brief Tries to reconnect in case of connection issues (usual usage - connection timeout). +void PostgreSQLConnection::try_reconnect(void) { + if (!m_is_connected) { + return; + } + if (m_active_connection != nullptr) { + try { + PQfinish(m_active_connection); + } catch (...) { + std::cerr << PG_ERR << "An exception while finishing PostgreSQL connection\n"; + } + this->m_active_connection = nullptr; + this->m_is_connected = false; + } + std::cerr << PG_INF << "Reconnecting to the PostgreSQL server...\n"; + initialize(); +} + +std::shared_ptr connection(nullptr); +std::shared_ptr PostgreSQLConnection::get_instance(void) { + if (connection.get() == nullptr) { + connection.reset(new PostgreSQLConnection()); + } + return connection; +} + +PostgreSQLConnection::~PostgreSQLConnection(void) { + if (m_active_connection) { + PQfinish(this->m_active_connection); + this->m_active_connection = nullptr; + this->m_is_connected = false; + } +} + +/// \brief Initialization of exact object. Uses environment variable PGQL_ENV_CONN_NAME for making a connection. +/// \returns Returns false in case of failure or absence of ENV-variable. +/// Returns true in case of connection has been succesfully established. +bool PostgreSQLConnection::initialize(void) { + if (this->m_active_connection != nullptr) { + std::cerr << PG_WRN << "PostgreSQL connection is already established.\n"; + return true; + } + +#ifdef PGQL_DYNAMIC_LOAD + if (!load_libpq()) { + return false; + } +#endif + + const char* envConnString = nullptr; + envConnString = std::getenv(PGQL_ENV_CONN_NAME); + + if (envConnString == nullptr) { + std::cerr << PG_WRN << "PostgreSQL connection string isn't found in Environment (" << PGQL_ENV_CONN_NAME + << ")\n"; + return false; + } else { + std::cerr << PG_INF << "PostgreSQL connection string:\n"; + std::cerr << PG_INF << envConnString << std::endl; + } + + this->m_active_connection = PQconnectdb(envConnString); + + ConnStatusType connStatus = PQstatus(this->m_active_connection); + + if (connStatus != CONNECTION_OK) { + std::cerr << PG_ERR << "Cannot connect to PostgreSQL: " << static_cast(connStatus) << std::endl; + return false; + } else { + std::cerr << PG_INF << "Connected to PostgreSQL successfully\n"; + } + + this->m_is_connected = true; + + return true; +} + +#ifdef PGQL_DYNAMIC_LOAD +/// \brief Loads libpq module in runtime +bool PostgreSQLConnection::load_libpq(void) { +# ifdef _WIN32 + modLibPQ = std::shared_ptr(new HMODULE(LoadLibrary("libpq.dll")), [](HMODULE* ptr) { + if (*ptr != (HMODULE)0) { + std::cerr << PG_INF << "Freeing libPQ.dll handle\n"; + try { + FreeLibrary(*ptr); + } catch (...) { + } + } + }); +# else + modLibPQ = std::shared_ptr(new HMODULE(dlopen("libpq.so", RTLD_LAZY)), [](HMODULE* ptr) { + if (*ptr != (HMODULE)0) { + std::cerr << PG_INF << "Freeing libPQ.so handle\n"; + try { + dlclose(*ptr); + } catch (...) { + } + } + }); + if (*modLibPQ == (HMODULE)0) { + modLibPQ = std::shared_ptr(new HMODULE(dlopen("libpq.so.5", RTLD_LAZY)), [](HMODULE* ptr) { + if (*ptr != (HMODULE)0) { + std::cerr << PG_INF << "Freeing libPQ.so.5 handle\n"; + try { + dlclose(*ptr); + } catch (...) { + } + } + }); + } + if (*modLibPQ == (HMODULE)0) { + modLibPQ = std::shared_ptr(new HMODULE(dlopen("libpq.dylib", RTLD_LAZY)), [](HMODULE* ptr) { + if (*ptr != (HMODULE)0) { + std::cerr << PG_INF << "Freeing libPQ.dylib handle\n"; + try { + dlclose(*ptr); + } catch (...) { + } + } + }); + } + if (*modLibPQ == (HMODULE)0) { + modLibPQ = std::shared_ptr(new HMODULE(dlopen("libpq.5.dylib", RTLD_LAZY)), [](HMODULE* ptr) { + if (*ptr != (HMODULE)0) { + std::cerr << PG_INF << "Freeing libPQ.5.dylib handle\n"; + try { + dlclose(*ptr); + } catch (...) { + } + } + }); + } + if (*modLibPQ == (HMODULE)0) { + modLibPQ = std::shared_ptr(new HMODULE(dlopen("/opt/homebrew/opt/libpq/lib/libpq.dylib", RTLD_LAZY)), [](HMODULE* ptr) { + if (*ptr != (HMODULE)0) { + std::cerr << PG_INF << "Freeing /opt/homebrew/opt/libpq/lib/libPQ.dylib handle\n"; + try { + dlclose(*ptr); + } catch (...) { + } + } + }); + } +# endif + if (*modLibPQ == (HMODULE)0) { + std::cerr << PG_WRN << "Cannot load PostgreSQL client module libPQ, reporting is unavailable\n"; + return false; + } else { + std::cerr << PG_INF << "PostgreSQL client module libPQ has been loaded\n"; + } + +# ifdef _WIN32 +# define GETPROC(name) \ + name = (fn##name)GetProcAddress(*modLibPQ, #name); \ + if (name == nullptr) { \ + std::cerr << PG_ERR << "Couldn't load procedure " << #name << " from libPQ\n"; \ + return false; \ + } +# else +# define GETPROC(name) \ + name = (fn##name)dlsym(*modLibPQ, #name); \ + if (name == nullptr) { \ + std::cerr << PG_ERR << "Couldn't load symbol " << #name << " from libPQ\n"; \ + return false; \ + } +# endif + + GETPROC(PQconnectdb); + GETPROC(PQstatus); + GETPROC(PQescapeStringConn); + GETPROC(PQfinish); + GETPROC(PQerrorMessage); + GETPROC(PQexec); + GETPROC(PQresultStatus); + GETPROC(PQgetvalue); + GETPROC(PQgetisnull); + GETPROC(PQclear); + GETPROC(PQresultErrorMessage); + + return true; +} +#endif + +namespace PostgreSQLHelpers { + +std::vector parse_value_param(std::string text) { + std::vector results; + size_t beginning = 0; + size_t chrPos = 0; + char pairingChar = 0; + for (auto it = text.begin(); it != text.end(); ++it, ++chrPos) { + if (pairingChar == 0) { // Looking for opening char + switch (*it) { + case '"': + case '\'': + pairingChar = *it; + break; + case '{': + pairingChar = '}'; + break; + } + beginning = chrPos + 1; + } else if (*it != pairingChar) { // Skip while don't face with paring char + continue; + } else { + if (chrPos < 3 || (text[chrPos - 1] != '\\' && text[chrPos - 2] != '\\')) { + size_t substrLength = chrPos - beginning; + if (substrLength > 0 && (beginning + substrLength) < text.length()) { + results.push_back(text.substr(beginning, chrPos - beginning)); + } + pairingChar = 0; + } + } + } + return results; +} + +std::string get_os_version(void) { +#ifndef _WIN32 + struct utsname uts; + uname(&uts); + return uts.sysname; +#else + OSVERSIONINFOEXW osVersionInfo = {}; + + // Extended OS detection. We need it because of changed OS detection + // mechanism on Windows 11 + // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlgetversion + HMODULE hNTOSKRNL = LoadLibrary("ntoskrnl.exe"); + typedef NTSTATUS (*fnRtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation); + fnRtlGetVersion RtlGetVersion = nullptr; + if (hNTOSKRNL) { + RtlGetVersion = (fnRtlGetVersion)GetProcAddress(hNTOSKRNL, "RtlGetVersion"); + } + + ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX)); + osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); + + std::stringstream winVersion; + winVersion << "Windows "; + +# pragma warning(push) +# pragma warning(disable : 4996) + if (FAILED(GetVersionExW((LPOSVERSIONINFOW)&osVersionInfo))) { + return "Unknown Windows OS"; + } +# pragma warning(pop) + + // On Windows 11 GetVersionExW returns wrong information (like a Windows 8, build 9200) + // Because of that we update inplace information if RtlGetVersion is available + osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + if (RtlGetVersion && SUCCEEDED(RtlGetVersion((PRTL_OSVERSIONINFOW)&osVersionInfo))) { + if (osVersionInfo.dwBuildNumber >= 22000) + winVersion << "11"; + } + + DWORD encodedVersion = (osVersionInfo.dwMajorVersion << 8) | osVersionInfo.dwMinorVersion; + switch (encodedVersion) { + case 0x0A00: + if (osVersionInfo.dwBuildNumber < 22000) + winVersion << ((osVersionInfo.wProductType == VER_NT_WORKSTATION) ? "10" : "2016"); + break; + case 0x0603: + winVersion << ((osVersionInfo.wProductType == VER_NT_WORKSTATION) ? "8.1" : "2012 R2"); + break; + case 0x0602: + winVersion << ((osVersionInfo.wProductType == VER_NT_WORKSTATION) ? "8" : "2012"); + break; + case 0x0601: + winVersion << ((osVersionInfo.wProductType == VER_NT_WORKSTATION) ? "7" : "2008 R2"); + break; + case 0x0600: + winVersion << ((osVersionInfo.wProductType == VER_NT_WORKSTATION) ? "Vista" : "2008"); + break; + default: + winVersion << osVersionInfo.dwMajorVersion << "." << osVersionInfo.dwMinorVersion; + break; + } + if (osVersionInfo.wSuiteMask & VER_SUITE_BACKOFFICE) + winVersion << " BackOffice"; + if (osVersionInfo.wSuiteMask & VER_SUITE_BLADE) + winVersion << " Web Edition"; + if (osVersionInfo.wSuiteMask & VER_SUITE_COMPUTE_SERVER) + winVersion << " Compute Cluster Edition"; + if (osVersionInfo.wSuiteMask & VER_SUITE_DATACENTER) + winVersion << " Datacenter Edition"; + if (osVersionInfo.wSuiteMask & VER_SUITE_ENTERPRISE) + winVersion << " Enterprise Edition"; + if (osVersionInfo.wSuiteMask & VER_SUITE_EMBEDDEDNT) + winVersion << " Embedded"; + if (osVersionInfo.wSuiteMask & VER_SUITE_PERSONAL) + winVersion << " Home"; + if (osVersionInfo.wSuiteMask & VER_SUITE_SMALLBUSINESS) + winVersion << " Small Business"; + + winVersion << " Build: " << osVersionInfo.dwBuildNumber; + + return winVersion.str(); +#endif +} + +std::string get_executable_name(void) { +#ifdef _WIN32 + char cFilePath[MAX_PATH] = {}; + GetModuleFileName(nullptr, cFilePath, MAX_PATH); + std::string filePath(cFilePath); +#elif !defined(__APPLE__) + std::string filePath; + std::ifstream("/proc/self/comm") >> filePath; + return filePath; +#else + uint32_t cFilePathSize = MAXPATHLEN; + std::vector cFilePath(static_cast(cFilePathSize)); + if (_NSGetExecutablePath(cFilePath.data(), &cFilePathSize) == -1) { + // Trying to reallocate, once + cFilePath.reserve(cFilePathSize + 1); + if (_NSGetExecutablePath(cFilePath.data(), &cFilePathSize) == -1) { + return "macos_failed"; + } + } + std::string filePath(cFilePath.data()); +#endif + return filePath.substr(filePath.find_last_of("/\\") + 1); +} + +std::string get_hostname(void) { +#ifdef _WIN32 + DWORD szHostName = MAX_COMPUTERNAME_LENGTH; + char cHostName[MAX_COMPUTERNAME_LENGTH + 1] = {}; + if (FAILED(GetComputerName(cHostName, &szHostName))) { + std::cerr << PG_ERR << "Cannot get a host name\n"; +#else + char cHostName[HOST_NAME_MAX]; + if (gethostname(cHostName, HOST_NAME_MAX)) { + std::cerr << PG_ERR << "Cannot get a host name\n"; + return "NOT_FOUND"; +#endif + } + return cHostName; +} + +void add_pair(std::map& keyValues, const std::string& key, const std::string& value) { + size_t dPos; + // Parse IR_name for opName and hash + if (key == "IR_name" && (dPos = value.find('_')) != std::string::npos) { + keyValues["opName"] = value.substr(0, dPos); + keyValues["opSet"] = "unknown"; // Need to set + keyValues["hashXml"] = value.substr(dPos + 1); + keyValues["pathXml"] = value; + return; + } + if (key == "Op") { + if ((dPos = value.find('.')) == std::string::npos) { + keyValues["opName"] = value.substr(0, dPos); + keyValues["opSet"] = "unknown"; // Need to set later + } else { + keyValues["opName"] = value.substr(0, dPos); + keyValues["opSet"] = value.substr(dPos + 1); + } + } + // Parse IR for opName and hash + if (key == "IR") { + keyValues["hashXml"] = value; + keyValues["pathXml"] = value + ".xml"; + return; + } + // Parse Function for opName and opSet + if (key == "Function" && (dPos = value.find('_')) != std::string::npos) { + keyValues["opName"] = value.substr(0, dPos); + keyValues["opSet"] = value.substr(dPos + 6); // Skipping "opset" + return; + } + // Normalize target devices + if (key == "target_device" || key == "TargetDevice" || key == "Device" || key == "targetDevice") { + if (value == "CPU") { +// see https://sourceforge.net/p/predef/wiki/Architectures/ +#if defined(__arm__) || defined(_M_ARM) || defined(__ARMEL__) + keyValues["targetDeviceArch"] = "arm"; +#elif defined(__aarch64__) || defined(_M_ARM64) + keyValues["targetDeviceArch"] = "arm64"; +#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(__IA32__) || defined(_M_I86) || \ + defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__I86__) || defined(__386) || \ + defined(__ILP32__) || defined(_ILP32) || defined(__wasm32__) || defined(__wasm32) + keyValues["targetDeviceArch"] = "x86"; +#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || \ + defined(_M_AMD64) + keyValues["targetDeviceArch"] = "x64"; +#elif defined(__riscv) + keyValues["targetDeviceArch"] = "riskv64"; +#endif + } + keyValues["targetDevice"] = value; + return; + } + std::string lKey = key; + std::transform(lKey.begin(), lKey.end(), lKey.begin(), [](unsigned char c) { + return std::tolower(c); + }); + if (lKey == "config") { + keyValues[lKey] = value; + return; + } + keyValues[key] = value; +} + +bool parse_test_name(const char* line, std::map& keyValues) { + const std::vector knownExceptions = {"target_device", "IR_name"}; + + std::string paramName; + + // Looking for '/' as a delimeter between group name and parameters + const char *ptr = line, *grpNameEnd = nullptr; + while (*ptr != 0 && *ptr != '/') + ++ptr; + if (*ptr == 0) { + return false; // group name isn't identified, wrong line on input + } + keyValues["__groupName__"] = std::string(line, ptr - line); + grpNameEnd = ptr + 1; + + // Try to parse param1=value1_param2=(paramX=valueX_)... as a key=value + const char *paramNameStart = ptr + 1, *paramValueStart = nullptr; + // Brakets counter to be able catch inherited values like ((paramX=valueX)(paramY=valueY)) + unsigned int bkt = 0; + + while (*ptr != 0) { // Do until line ends + while (*ptr != 0 && *ptr != '=') + ++ptr; // find key=value delimeter or EOL + if (paramNameStart == ptr) + break; // break if nothing found + paramName = std::string(paramNameStart, ptr - paramNameStart); // store parameter name + if (*ptr == '=') { // if we found a key=value delimeter (not EOL) + paramValueStart = ++ptr; // start looking for value after '=' char + while (*ptr != 0) { // try to find a value end + if (*ptr == '(') // braket found - ignores key=value delimeter until string end or all closing braket + // will be found + ++bkt; + else if (*ptr == ')') // closing braket found - decrease breaket counter + --bkt; + else if (*ptr == '=' && bkt == 0) // stop on key=value delimeter only outside of brakets + break; + ++ptr; + } + if (*ptr == 0) { // if we stopped at the end of line + // Removing trailing underscore and non-printed symbols + while (ptr > paramValueStart && (*(ptr - 1) == '_' || *(ptr - 1) < 0x20)) + --ptr; + add_pair(keyValues, std::string(paramName), std::string(paramValueStart, ptr - paramValueStart)); + } else if (*ptr == '=') { // if we stopped by item's delimeter (paramN=valueN_paramN+1=valueN+1) + // Because we have params which contains underscore, this algorithm may interpret '_' wrong. Best way - + // prohibit usage of '_' in param names, or change item's delimeter '_' to another one. In such case + // this part of code should be removed + auto excCheckLambda = [ptr, paramValueStart](const std::string& exc) { + size_t len = exc.length(); + if ((ptr - len) < paramValueStart) + return false; + return exc == std::string(ptr - len, len); + }; + auto found = std::find_if(knownExceptions.begin(), knownExceptions.end(), excCheckLambda); + if (found != knownExceptions.end()) { + ptr -= found->length(); + paramNameStart = ptr; + --ptr; + } else { // in case no underscores are found (param1=value1_param2=value2) + while (ptr > paramValueStart && *ptr != '_') + --ptr; // we /\ will stop here, but we need to rewind until '_' to get a valueN + paramNameStart = ptr + 1; + } + add_pair(keyValues, std::string(paramName), std::string(paramValueStart, ptr - paramValueStart)); + } + } + } + // If we found no key_value parameters - just store whole line after group name as a pseudo-__name__ element + if (keyValues.size() == 1) { + ptr = grpNameEnd; + while (*ptr >= 0x20) + ++ptr; + keyValues["__name__"] = std::string(grpNameEnd, ptr - grpNameEnd); + } + return true; +} + +bool compile_string(const std::string& srcStr, + const std::map& keyValue, + std::string& result) { + size_t varPos = std::string::npos; + size_t readPos = 0; + std::string varName; + result.clear(); + varName.reserve(srcStr.length()); + result.reserve(srcStr.length()); + while (readPos < srcStr.length()) { + varPos = srcStr.find('$', readPos); + if (varPos == std::string::npos) { + result += srcStr.substr(readPos, srcStr.length() - readPos); + return true; + } + if (varPos > readPos) + result += srcStr.substr(readPos, varPos - readPos); + const char *ptr = srcStr.c_str() + varPos + 1, *varNamePtr = ptr; + while (*ptr > 0x20 && ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z') || + (*ptr >= '0' && *ptr <= '9') || (*ptr == '-') || (*ptr == '_'))) + ++ptr; + varName = std::string(varNamePtr, ptr - varNamePtr); + auto val = keyValue.find(varName); + if (val != keyValue.end()) + result += val->second; + readPos = varPos + (ptr - varNamePtr) + 1; + } + // Trim right + while (result.length() > 1 && result[result.length() - 1] == ' ') + result.resize(result.length() - 1); + return readPos = srcStr.length(); +} +} // namespace PostgreSQLHelpers + +} // namespace CommonTestUtils diff --git a/src/tests/test_utils/common_test_utils/src/postgres_link.cpp b/src/tests/test_utils/common_test_utils/src/postgres_link.cpp new file mode 100644 index 00000000000000..60792cf74387fe --- /dev/null +++ b/src/tests/test_utils/common_test_utils/src/postgres_link.cpp @@ -0,0 +1,834 @@ +// Copyright (C) 2022-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "common_test_utils/postgres_link.hpp" + +#include "common_test_utils/postgres_helpers.hpp" +#include "openvino/core/version.hpp" + +static std::map + ExtTestQueries; // Map of extended test queries. It is used for do a custom query after inserting mandatory row +static std::map + ExtTestNames; // Map of extended test name convertors. It is used to change a test name automatically. + +namespace CommonTestUtils { + +using namespace PostgreSQLHelpers; + +/// \brief Helper for checking PostgreSQL results +#define CHECK_PGRESULT(var_name, error_message, action) \ + if (var_name.get() == nullptr) { \ + std::cerr << PG_ERR << error_message << std::endl; \ + action; \ + } +/// \brief Helper for registering ID-retrieval functions +#define GET_PG_IDENTIFIER(funcDefinition, sqlQuery, varName, fieldName) \ + bool funcDefinition { \ + std::stringstream sstr; \ + sstr << sqlQuery; \ + return _internal_request_id(sstr.str(), #fieldName, varName); \ + } + +/// \brief Class which handles gtest keypoints and send data to PostgreSQL database. +/// May be separated for several source files in case it'll become to huge. +class PostgreSQLEventListener : public ::testing::EmptyTestEventListener { + std::shared_ptr connectionKeeper; + + std::string bin_version; + std::string lib_version; + + const char* session_id = nullptr; // String value of session id, it will be converted to sessinoId + const char* run_id = nullptr; // String value of run (might be char[33]), it will be converted to testRunId + bool isPostgresEnabled = false; + PostgreSQLReportingLevel reportingLevel = REPORT_LVL_DEFAULT; + + /* Dynamic information about current session*/ + uint64_t sessionId = 0; + uint64_t appId = 0; + uint64_t hostId = 0; + uint64_t testIterationId = 0; + uint64_t testSuiteNameId = 0; + uint64_t testNameId = 0; + uint64_t testSuiteId = 0; + uint64_t testId = 0; + uint64_t testRunId = 0; + uint64_t testExtId = 0; + + size_t jqLastCommandOffset; // Stores offset of beginning of a last command, to be able to rewind + std::stringstream joinedQuery; + bool isRefusedResult = false; // Signals test result is a waste and shouldn't be stored in DB + bool isManualStart = false; // Signals test case start will be called manually + + /* Test name parsing */ + std::map + testDictionary; // Contains key=value pairs which should be used while constructing queries and names + std::map::iterator grpName; + std::string testName, fullTestName; + bool isTestNameParsed = false; // Signals test name was successfully parsed to the testDictionary pairs + bool isFieldsUpdated = false; // Signals testDictionary was updated between OnTestStart and OnTestEnd + + // Unused event handlers, kept here for possible use in the future + /* + void OnTestProgramStart(const ::testing::UnitTest& unit_test) override {} + void OnTestIterationStart(const ::testing::UnitTest& unit_test, int iteration) override {} + void OnEnvironmentsSetUpStart(const ::testing::UnitTest& unit_test) override {} + void OnEnvironmentsSetUpEnd(const ::testing::UnitTest& unit_test) override {} + void OnEnvironmentsTearDownStart(const ::testing::UnitTest& unit_test) override {} + void OnEnvironmentsTearDownEnd(const ::testing::UnitTest& unit_test) override {} + void OnTestIterationEnd(const ::testing::UnitTest& unit_test, int iteration) override {} + void OnTestProgramEnd(const ::testing::UnitTest& unit_test) override {} + */ + + /* + Transaction-optimized ID retrieval. + If string doesn't begin with "BEGIN" and contain "SELECT" regular flow is used. + Otherwise - tries to move pointer to start of "SELECT" part of query and queries ID first. + In case query has returned NULL - means no corresponding data found in database. + If no information found - calls transactional insert and retrieve. + sqlQuery = "BEGIN TRANSACTION ... COMMIT; SELECT QUERY"; + ^ full query will be executed ^ only if this part has returned NULL + Using described approach we do transactional queries only in case we don't + retrieve correct data from database. Otherwise it will use fast path without + transaction. + */ + bool _internal_request_id(const std::string& sqlQuery, const char* fieldName, uint64_t& result) { + auto selectPos = sqlQuery.find("SELECT"); + const char *query = sqlQuery.c_str(), *query_start = query; + bool isTransactionalQuery = (selectPos != std::string::npos) && (sqlQuery.find("BEGIN") == 0); + if (isTransactionalQuery) { + query += selectPos; + } +#ifdef PGQL_DEBUG + std::cout << "Query: " << query << std::endl; +#endif + auto pgresult = connectionKeeper->query(query); + CHECK_PGRESULT(pgresult, "Cannot retrieve a correct " << fieldName, return false); + + bool isNull = PQgetisnull(pgresult.get(), 0, 0) != 0; + if (isNull && isTransactionalQuery) { +#ifdef PGQL_DEBUG + std::cout << "Transactional query: " << query << std::endl; +#endif + pgresult = connectionKeeper->query(query_start, PGRES_TUPLES_OK, true); + CHECK_PGRESULT(pgresult, "Cannot retrieve a correct transactional " << fieldName, return false); + isNull = PQgetisnull(pgresult.get(), 0, 0) != 0; + } + + if (!isNull && (result = std::atoi(PQgetvalue(pgresult.get(), 0, 0))) == 0) { + std::cerr << PG_ERR << "Cannot interpret a returned " << fieldName + << ", value : " << (!isNull ? PQgetvalue(pgresult.get(), 0, 0) : "NULL") << std::endl; + return false; + } + return true; + } + + /// \brief Escapes control symbols in a string by using PostgreSQL escapeStringConn function + /// \returns Return escaped string or throws an error in case of any error + std::string escape_string(const std::string& sourceString) const { + if (sourceString.length() == 0) { + return std::string(""); + } + + std::vector escapedString; + escapedString.resize(sourceString.length() * 2); // Doc requires to allocate two times more than initial length + escapedString[0] = 0; + int errCode = 0; + size_t writtenSize = 0; + writtenSize = PQescapeStringConn(connectionKeeper->get_connection(), + escapedString.data(), + sourceString.c_str(), + sourceString.length(), + &errCode); + if (errCode == 0 && writtenSize >= sourceString.length()) { + return std::string(escapedString.data()); + } else { + throw std::runtime_error("Error while escaping string"); + } + } + + GET_PG_IDENTIFIER(request_application_id(void), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_APPLICATION('" << get_executable_name() << "');" + << "COMMIT; " + << "SELECT GET_APPLICATION('" << get_executable_name() << "');", + appId, + app_id) + GET_PG_IDENTIFIER(request_run_id(void), + "SELECT GET_RUN('" << this->run_id << "', " << this->appId << ", " << this->sessionId << ", " + << this->hostId << ", " << static_cast(this->reportingLevel) + << "::smallint);", + testRunId, + run_id) + GET_PG_IDENTIFIER(request_host_id(void), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_HOST('" << get_hostname() << "', '" << get_os_version() << "');" + << "COMMIT; " + << "SELECT GET_HOST('" << get_hostname() << "', '" << get_os_version() << "');", + hostId, + host_id) + GET_PG_IDENTIFIER(request_session_id(void), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_SESSION('" << this->session_id << "', '" << this->bin_version << "', '" + << this->lib_version << "');" + << "COMMIT;" + << "SELECT GET_SESSION('" << this->session_id << "', '" << this->bin_version << "', '" + << this->lib_version << "');", + sessionId, + session_id) + GET_PG_IDENTIFIER(request_suite_name_id(const char* test_suite_name), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_TEST_SUITE('" << test_suite_name << "', " << this->appId << ");" + << "COMMIT; " + << "SELECT GET_TEST_SUITE('" << test_suite_name << "', " << this->appId << ");", + testSuiteNameId, + sn_id) + GET_PG_IDENTIFIER(request_test_name_id(std::string query), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_" << query << "; COMMIT;" + << "SELECT GET_" << query, + testNameId, + tn_id) + GET_PG_IDENTIFIER(request_suite_id(void), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_SUITE_ID(" << this->testSuiteNameId << ", " << this->sessionId << ", " + << this->testRunId << ");" + << "COMMIT; " + << "SELECT GET_SUITE_ID(" << this->testSuiteNameId << ", " << this->sessionId << ", " + << this->testRunId << ");", + testSuiteId, + sr_id) + GET_PG_IDENTIFIER(request_suite_id(std::string query), query, testSuiteId, sr_id) + GET_PG_IDENTIFIER(request_test_id(std::string query), query, testId, tr_id) + GET_PG_IDENTIFIER(request_test_ext_id(std::string query), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_MISS_" << query << "; COMMIT;" + << "SELECT ON_START_" << query, + testExtId, + t_id) + GET_PG_IDENTIFIER(update_test_ext_id(std::string query), + "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; " + << "CALL ON_END_MISS_" << query << "; COMMIT;" + << "SELECT ON_END_" << query, + testExtId, + t_id) + + /// \brief Send an update query. Depends on mode in calls specific UPDATE query in case of default reporting + /// and regular ON_START query in case of fast reporting. + /// In such case UPDATE query is used only for updating changed values in runtime, when + /// ON_START query in this place already has all updated data, that's why UPDATE query is skipping + void update_test_results(const ::testing::TestInfo* test_info = nullptr) { + auto grpName = testDictionary.end(); + + if (isTestNameParsed == true && (reportingLevel == REPORT_LVL_FAST || isFieldsUpdated == true) && + (grpName = testDictionary.find("__groupName__")) != testDictionary.end()) { + auto extQuery = ExtTestQueries.end(); + if (reportingLevel == REPORT_LVL_DEFAULT) { + // Looks query with GroupName + "_ON_END", "ReadIR_ON_END" as example + extQuery = ExtTestQueries.find(grpName->second + "_ON_END"); + } else if (reportingLevel == REPORT_LVL_FAST) { + // Looks query with GroupName + "_ON_START", "ReadIR_ON_START" as example + extQuery = ExtTestQueries.find(grpName->second + "_ON_START"); + } + if (extQuery != ExtTestQueries.end()) { + std::string query; + if (compile_string(extQuery->second, testDictionary, query)) { + if (reportingLevel == REPORT_LVL_DEFAULT) { + if (!update_test_ext_id(query)) { + std::cerr << PG_WRN << "Failed extended update query: " << query << std::endl; + } else { + isFieldsUpdated = false; + } + } else if (reportingLevel == REPORT_LVL_FAST) { + size_t jqLen = joinedQuery.tellp(); + std::vector addQuery(jqLen - jqLastCommandOffset); + joinedQuery.seekg(jqLastCommandOffset); + joinedQuery.read(addQuery.data(), + jqLen - jqLastCommandOffset - 3); // Ignores ");\n" at the end + joinedQuery.seekp(jqLastCommandOffset); + joinedQuery << "WITH rows AS (" << addQuery.data() << ") AS test_id) SELECT ON_START_" << query + << " FROM rows;\n"; + } + } else { + std::cerr << PG_WRN << "Preparing extended update query is failed: " + << (test_info != nullptr ? test_info->name() : "[no test info]") << std::endl; + } + } + } + } + + /// \brief Internal call of delayed start process which puts information about + /// TestCase start into the table + void _internal_start(void) { + // In case of results will be refused - do not do anything + if (!this->isPostgresEnabled || !this->testRunId || !this->sessionId || !this->testSuiteNameId || + !this->testSuiteId || isRefusedResult) { + return; + } + + std::stringstream sstr; + + if (!isManualStart) { + // Creates temporary record + sstr << "INSERT INTO test_results_temp (tr_id, session_id, suite_id, run_id, app_id, test_id, test_result) " + << "VALUES (DEFAULT, " << this->sessionId << ", " << this->testSuiteId << ", " << this->testRunId + << ", " << this->appId << ", " << this->testNameId << ", 0::smallint) RETURNING tr_id"; + } else { + // Creates record + sstr << "INSERT INTO test_results (tr_id, session_id, suite_id, run_id, app_id, test_id, test_result) " + << "VALUES (DEFAULT, " << this->sessionId << ", " << this->testSuiteId << ", " << this->testRunId + << ", " << this->appId << ", " << this->testNameId << ", 0::smallint) RETURNING tr_id"; + } + + if (!request_test_id(sstr.str())) + return; + + if (grpName != testDictionary.end()) { + // Looks query with GroupName + "_ON_START", "ReadIR_ON_START" as example + auto extQuery = ExtTestQueries.find(grpName->second + "_ON_START"); + if (extQuery != ExtTestQueries.end()) { + std::string query; + testDictionary["__test_id"] = std::to_string(this->testId); + if (compile_string(extQuery->second, testDictionary, query)) { + if (!request_test_ext_id(query)) { + std::cerr << PG_WRN << "Failed extended query: " << query << std::endl; + } else { + testDictionary["__test_ext_id"] = std::to_string(this->testExtId); + } + } else { + std::cerr << PG_WRN << "Preparing extended query is failed: " << fullTestName << std::endl; + } + } + } + } + + void OnTestSuiteStart(const ::testing::TestSuite& test_suite) override { + if (!this->isPostgresEnabled || !this->testRunId || !this->sessionId) + return; + try { + if (!request_suite_name_id(escape_string(test_suite.name()).c_str())) + return; + } catch (const std::exception& e) { + std::cerr << PG_ERR << "Requesting suite name is failed with exception: " << e.what() << std::endl; + return; + } + /* + // This part of code left because it is preferred way, but incompatible with external parallel running + std::stringstream sstr; + sstr << "INSERT INTO suite_results (sr_id, session_id, run_id, suite_id) VALUES (DEFAULT, " << this->sessionId + << ", " << this->testRunId << ", " << this->testSuiteNameId << ") RETURNING sr_id"; + if (!RequestSuiteId(sstr.str())) + return; + */ + if (!request_suite_id()) + return; + + // Cleanup accumulator for quieries + if (reportingLevel == REPORT_LVL_FAST) { + jqLastCommandOffset = 0; + joinedQuery.str(""); + joinedQuery.clear(); + } + } + +// Legacy API is deprecated but still available +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseStart(const ::testing::TestCase& test_case) override { + if (this->testSuiteNameId == 0) + OnTestSuiteStart(test_case); + } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + void OnTestStart(const ::testing::TestInfo& test_info) override { + if (!this->isPostgresEnabled || !this->testRunId || !this->sessionId || !this->testSuiteNameId || + !this->testSuiteId) + return; + + if (reportingLevel == REPORT_LVL_SUITES_ONLY) { + // Do not report per-case results + return; + } + + this->testId = 0; + this->testExtId = 0; + isRefusedResult = false; + testDictionary.clear(); + + grpName = testDictionary.end(); + testName = test_info.name(); // Could be changed later + fullTestName = testName; // Shouldn't be changed, used as global identifier + + if ((isTestNameParsed = parse_test_name(fullTestName.c_str(), testDictionary)) == true && + (grpName = testDictionary.find("__groupName__")) != testDictionary.end()) { + auto nameConvertStr = ExtTestNames.find(grpName->second); + if (nameConvertStr != ExtTestNames.end()) { + if (!compile_string(nameConvertStr->second, testDictionary, testName)) { + std::cerr << PG_WRN << "Error compiling test name: " << fullTestName << std::endl; + testName = grpName->second; + } + } else { + testName = grpName->second; + } + } else { + std::cerr << PG_WRN << "Error parsing test name: " << fullTestName << std::endl; + } + + std::stringstream sstr; + try { + if (reportingLevel == REPORT_LVL_DEFAULT) { + sstr << "TEST_NAME(" << this->testSuiteNameId << ", '" << escape_string(testName) << "'"; + } else if (reportingLevel == REPORT_LVL_FAST) { + sstr << "SELECT ADD_TEST_RESULT(" << this->appId << ", " << this->sessionId << ", " << this->testRunId + << ", " << this->testSuiteId << ", " << this->testSuiteNameId << ", '" << escape_string(testName) + << "'"; + } + } catch (std::exception& e) { + std::cerr << PG_ERR << "Query building is failed with exception: " << e.what() << std::endl; + return; + } + + { + /* If we need a query customization - it could be done here. */ + sstr << ", NULL"; + } + + testDictionary["__suite_id"] = std::to_string(this->testSuiteId); + testDictionary["__suite_name_id"] = std::to_string(this->testSuiteNameId); + testDictionary["__session_id"] = std::to_string(this->sessionId); + testDictionary["__run_id"] = std::to_string(this->testRunId); + testDictionary["__is_temp"] = + (reportingLevel == REPORT_LVL_DEFAULT && !isManualStart ? "1::boolean" : "0::boolean"); + isFieldsUpdated = false; + + if (reportingLevel == REPORT_LVL_DEFAULT) { + sstr << ")"; + } else if (reportingLevel == REPORT_LVL_FAST) { + jqLastCommandOffset = joinedQuery.tellp(); + joinedQuery << sstr.str(); + // This will allow to pass checks later, but this values isn't expected to see in real + this->testNameId = ~0; + this->testId = ~0; + // In case of fast reporting __test_id will be unset because of lazy execution. + // It should be replaced in WITH ... AS (... AS test_id) SELECT ... construction to test_id + testDictionary["__test_id"] = "test_id"; + testDictionary["__test_ext_id"] = "test_id"; + return; + } + + if (!request_test_name_id(sstr.str())) + return; + + // If manual start isn't requested - push information immediately to the table + if (!isManualStart) + _internal_start(); + } + + void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { + if (!this->isPostgresEnabled || !this->testRunId || !this->sessionId || !this->testSuiteNameId || + !this->testSuiteId || !this->testNameId || !this->testId) + return; + + if (reportingLevel == REPORT_LVL_SUITES_ONLY) { + return; + } + + if (isRefusedResult) { + return; + } + } + + void OnTestEnd(const ::testing::TestInfo& test_info) override { + if (!this->isPostgresEnabled || !this->testRunId || !this->sessionId || !this->testSuiteNameId || + !this->testSuiteId || !this->testNameId || !this->testId) + return; + + if (reportingLevel == REPORT_LVL_SUITES_ONLY) { + return; + } + + if (isRefusedResult) { + if (reportingLevel == REPORT_LVL_DEFAULT) { + auto grpName = testDictionary.end(); + + if (isTestNameParsed == true && isFieldsUpdated == true && + (grpName = testDictionary.find("__groupName__")) != testDictionary.end()) { + // Looks query with GroupName + "_ON_REFUSE", "ReadIR_ON_REFUSE" as example + auto extQuery = ExtTestQueries.find(grpName->second + "_ON_REFUSE"); + if (extQuery != ExtTestQueries.end()) { + std::string query; + if (compile_string(extQuery->second, testDictionary, query)) { + auto pgresult = connectionKeeper->query((std::string("CALL ON_REFUSE_") + query).c_str(), + PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot remove extended waste results", /* no return */); + } else { + std::cerr << PG_WRN + << "Preparing extended waste cleanup query is failed: " << test_info.name() + << std::endl; + } + } + } + + // Remove temporary record + std::stringstream sstr; + sstr << "DELETE FROM test_results_temp WHERE tr_id=" << this->testId; + auto pgresult = connectionKeeper->query(sstr.str().c_str(), PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot remove waste results", return); + + this->testId = 0; + testDictionary.clear(); + } else if (reportingLevel == REPORT_LVL_FAST) { + // Rewind to a last command + std::string tmp = joinedQuery.str(); + tmp.resize(jqLastCommandOffset); + joinedQuery.str(tmp); + } + return; + } + + // Need to use such order to be able simplify queries to database + // State 0 - Incomplete state, worst possible + uint32_t testResult = 32; // Failed state + if (test_info.result()->Passed()) + testResult = 128; + else if (test_info.result()->Skipped()) + testResult = 64; + + if (reportingLevel == REPORT_LVL_DEFAULT) { + std::stringstream sstr; + uint64_t testTempId = this->testId; + if (!isManualStart) { + sstr << "INSERT INTO test_results (session_id, suite_id, run_id, app_id, test_id, started_at, " + "finished_at, duration, test_result) " + << "(SELECT session_id, suite_id, run_id, app_id, test_id, started_at, NOW(), " + << test_info.result()->elapsed_time() << ", " << testResult << "::smallint FROM test_results_temp " + << "WHERE tr_id=" << this->testId << ") RETURNING tr_id"; + if (!request_test_id(sstr.str())) { + return; + } else { + sstr.str(""); + sstr.clear(); + sstr << "DELETE FROM test_results_temp WHERE tr_id=" << testTempId; + auto pgresult = connectionKeeper->query(sstr.str().c_str(), PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot remove temporary test results", /* no return */); + + // Set correct information about + set_custom_field("__test_ext_id", std::to_string(this->testId), true); + set_custom_field("__test_id", std::to_string(testTempId), true); + // Force updating fields because in some conditions IDs might be equal + isFieldsUpdated = true; + } + } else { + sstr << "UPDATE test_results SET duration = " << test_info.result()->elapsed_time() + << ", test_result = " << testResult << "::smallint, finished_at = NOW() " + << "WHERE tr_id=" << this->testId; + auto pgresult = connectionKeeper->query(sstr.str().c_str(), PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot update test results", /* no return */); + + // Set correct information about + set_custom_field("__test_ext_id", std::to_string(this->testId), true); + set_custom_field("__test_id", std::to_string(this->testId), true); + // Force updating fields because in some conditions IDs might be equal + isFieldsUpdated = true; + } + } else if (reportingLevel == REPORT_LVL_FAST) { + joinedQuery << ", " << testResult << "::smallint, " << test_info.result()->elapsed_time() << ");\n"; + } + + update_test_results(&test_info); + + this->testId = 0; + testDictionary.clear(); + } + + void OnTestSuiteEnd(const ::testing::TestSuite& test_suite) override { + if (!this->isPostgresEnabled || !this->testRunId || !this->sessionId || !this->testSuiteNameId || + !this->testSuiteId) + return; + + std::stringstream sstr; + sstr << "UPDATE suite_results SET finished_at=NOW(), duration=" << test_suite.elapsed_time() + << ", suite_result=" << (test_suite.Passed() ? 1 : 0) + << ", successful_count=" << test_suite.successful_test_count() + << ", skipped_count=" << test_suite.skipped_test_count() + << ", failed_count=" << test_suite.failed_test_count() + << ", disabled_count=" << test_suite.disabled_test_count() + << ", run_count=" << test_suite.test_to_run_count() << ", total_count=" << test_suite.total_test_count() + << " WHERE sr_id=" << this->testSuiteId; + auto pgresult = connectionKeeper->query(sstr.str().c_str(), PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot update test suite results", return); + this->testSuiteId = 0; + + if (reportingLevel == REPORT_LVL_FAST) { + pgresult = connectionKeeper->query(joinedQuery.str().c_str()); + CHECK_PGRESULT(pgresult, "Cannot update test cases results", return); + } + } +#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + void OnTestCaseEnd(const ::testing::TestCase& test_case) override { + if (this->testSuiteId != 0) + OnTestSuiteEnd(test_case); + } +#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ + + /* Do nothing here. If you need to do anything on creation - it should be fully undersandable. */ + PostgreSQLEventListener() { + this->session_id = std::getenv(PGQL_ENV_SESS_NAME); + if (this->session_id != nullptr) { + isPostgresEnabled = false; + + char* env_report_lvl = std::getenv(PGQL_ENV_RLVL_NAME); + if (env_report_lvl == nullptr) { + reportingLevel = REPORT_LVL_DEFAULT; + std::cerr << PG_INF << "Default reporting level is using\n"; + } else if (strcmp(env_report_lvl, "fast") == 0) { + reportingLevel = REPORT_LVL_FAST; + std::cerr << PG_INF << "Fast reporting level is using\n"; + } else if (strcmp(env_report_lvl, "suite") == 0) { + reportingLevel = REPORT_LVL_SUITES_ONLY; + std::cerr << PG_INF << "Suites-only reporting level is using\n"; + } else { + reportingLevel = REPORT_LVL_DEFAULT; + std::cerr << PG_WRN << "Wrong reporting level is passed, default reporting level is using\n"; + } + + this->run_id = std::getenv(PGQL_ENV_RUN_NAME); + if (this->run_id != nullptr) { + std::cerr << PG_INF << "External Run ID is provided: " << this->run_id << std::endl; + } else { + // Run id will be generated on database side, each run unique + this->run_id = ""; + } + + std::cerr << PG_INF << "Test session ID has been found\n"; + connectionKeeper = PostgreSQLConnection::get_instance(); + bool connInitResult = connectionKeeper->initialize(); + + if (!connInitResult) + return; + + bin_version = std::to_string(OPENVINO_VERSION_MAJOR) + "." + std::to_string(OPENVINO_VERSION_MINOR) + "." + + std::to_string(OPENVINO_VERSION_PATCH); + { + ov::Version version = ov::get_openvino_version(); + lib_version = version.buildNumber; + } + + isPostgresEnabled = connInitResult; + + if (isPostgresEnabled) + isPostgresEnabled &= request_application_id(); + if (isPostgresEnabled) + isPostgresEnabled &= request_host_id(); + if (isPostgresEnabled) + isPostgresEnabled &= request_session_id(); + if (isPostgresEnabled) + isPostgresEnabled &= request_run_id(); + + if (isPostgresEnabled) { + connectionKeeper = connection; + } + } else { + std::cerr << PG_ERR << "Test session ID hasn't been found, continues without database reporting\n"; + } + } + + ~PostgreSQLEventListener(void) { + if (!this->isPostgresEnabled) + return; + + std::stringstream sstr; + sstr << "UPDATE runs SET end_time=NOW() WHERE run_id=" << this->testRunId << " AND end_timequery(sstr.str().c_str(), PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot update run finish info", return); + + sstr.str(""); + sstr.clear(); + sstr << "UPDATE sessions SET end_time=NOW() WHERE session_id=" << this->sessionId << " AND end_timequery(sstr.str().c_str(), PGRES_COMMAND_OK); + CHECK_PGRESULT(pgresult, "Cannot update session finish info", return); + } + + /* Prohobit creation outsize of class, need to make a Singleton */ + PostgreSQLEventListener(const PostgreSQLEventListener&) = delete; + PostgreSQLEventListener& operator=(const PostgreSQLEventListener&) = delete; + + friend class PostgreSQLEnvironment; + +public: + void manual_start(void) { + if (isManualStart && this->testId == 0 && reportingLevel == REPORT_LVL_DEFAULT) { + _internal_start(); + } + } + + void set_refuse_result(bool value = true) { + isRefusedResult = value; + } + + void set_manual_start(bool value = true) { + isManualStart = value; + } + + bool set_custom_field(const std::string fieldName, const std::string fieldValue, const bool rewrite) { + auto field = this->testDictionary.find(fieldName); + if (rewrite || field == this->testDictionary.end()) { + isFieldsUpdated |= (field == this->testDictionary.end()) || + (field->second != fieldValue); // Signals only in case value not equal with existing + // Some plugins may return corrupted strings with zero-character at the end, it may + // corrupt queries + size_t zero_pos = fieldValue.find_first_of('\0'); + this->testDictionary[fieldName] = + zero_pos == std::string::npos ? fieldValue : fieldValue.substr(0, zero_pos); + return true; + } + return false; + } + + std::string get_custom_field(const std::string fieldName, const std::string defaultValue) const { + auto field = this->testDictionary.find(fieldName); + if (field != this->testDictionary.end()) { + return field->second; + } + return defaultValue; + } + + bool remove_custom_field(const std::string fieldName) { + auto field = this->testDictionary.find(fieldName); + if (field != this->testDictionary.end()) { + this->testDictionary.erase(field); + isFieldsUpdated = true; + return true; + } + return false; + } +}; + +/// \brief Global variable (scoped only to this file) which contains pointer to PostgreSQLEventListener +/// Might be replaced by a bool, but left as is for possible future use. +static PostgreSQLEventListener* pgEventListener = nullptr; +/// \brief Used for lazy set_manual_start call +static bool pgEventListenerInitialManualStart = false; + +/// \brief Class is used for registering environment handler in gtest. It prepares in-time set up +/// for registering PostgreSQLEventListener +class PostgreSQLEnvironment : public ::testing::Environment { +public: + PostgreSQLEnvironment(void) {} + ~PostgreSQLEnvironment(void) {} + void SetUp(void) override { + if (std::getenv(PGQL_ENV_SESS_NAME) != nullptr && std::getenv(PGQL_ENV_CONN_NAME) != nullptr) { + if (pgEventListener == nullptr) { + pgEventListener = new PostgreSQLEventListener(); + ::testing::UnitTest::GetInstance()->listeners().Append(pgEventListener); + pgEventListener->set_manual_start(pgEventListenerInitialManualStart); + } + } else { + std::cerr << PG_INF << "PostgreSQL Reporting is disabled due to missing environment settings\n"; + } + } + void TearDown(void) override { + // Don't see any reason to do additional tear down + } +}; + +/// \brief Global variable which stores a pointer to active instance (only one is expected) of +/// PostgreSQLEnvironment. +::testing::Environment* PostgreSQLEnvironment_Reg = ::testing::AddGlobalTestEnvironment(new PostgreSQLEnvironment()); + +/// \brief This class is for internal usage, don't need to move it to the header. It holds an internal state of +/// PostgreSQLLink instance. Introduced to simplify header. +class PostgreSQLCustomData { + // Reserved place for storing temporary data +}; + +PostgreSQLLink::PostgreSQLLink() : parentObject(nullptr), customData(new PostgreSQLCustomData()) { +#ifdef PGQL_DEBUG + std::cout << PG_INF << "PostgreSQLLink Started\n"; +#endif +} + +PostgreSQLLink::PostgreSQLLink(void* ptrParentObject) + : parentObject(ptrParentObject), + customData(new PostgreSQLCustomData()) { +#ifdef PGQL_DEBUG + std::cout << PG_INF << "PostgreSQLLink with parentObject Started\n"; +#endif +} + +PostgreSQLLink::~PostgreSQLLink(void) { + if (this->customData) { + delete this->customData; + this->customData = nullptr; + } + + this->parentObject = nullptr; +#ifdef PGQL_DEBUG + std::cout << PG_INF << "PostgreSQLLink Finished\n"; +#endif +} + +void PostgreSQLLink::set_refuse_result(bool value) const { + if (pgEventListener) { + pgEventListener->set_refuse_result(value); + } +} + +void PostgreSQLLink::set_manual_start(bool value) const { + if (pgEventListener) { + pgEventListener->set_manual_start(value); + } +} + +void PostgreSQLLink::manual_start(void) const { + if (pgEventListener) { + pgEventListener->manual_start(); + } +} + +bool PostgreSQLLink::set_custom_field(const std::string fieldName, + const std::string fieldValue, + const bool rewrite) const { + if (pgEventListener) { + return pgEventListener->set_custom_field(fieldName, fieldValue, rewrite); + } + return false; +} + +std::string PostgreSQLLink::get_custom_field(const std::string fieldName, const std::string defaultValue) const { + if (pgEventListener) { + return pgEventListener->get_custom_field(fieldName, defaultValue); + } + return defaultValue; +} + +bool PostgreSQLLink::remove_custom_field(const std::string fieldName) const { + if (pgEventListener) { + pgEventListener->remove_custom_field(fieldName); + } + return false; +} + +} // namespace CommonTestUtils +namespace PostgreSQLLink { +std::map* get_ext_test_queries(void) { + return &ExtTestQueries; +} + +std::map* get_ext_test_names(void) { + return &ExtTestNames; +} + +void set_manual_start(bool value) { + if (::CommonTestUtils::pgEventListener) { + ::CommonTestUtils::pgEventListener->set_manual_start(value); + } else { + ::CommonTestUtils::pgEventListenerInitialManualStart = value; + } +} + +void manual_start(void) { + if (::CommonTestUtils::pgEventListener) { + ::CommonTestUtils::pgEventListener->manual_start(); + } +} +} // namespace PostgreSQLLink diff --git a/src/tests/test_utils/common_test_utils/src/test_common.cpp b/src/tests/test_utils/common_test_utils/src/test_common.cpp index ce5ee43aebb3a6..4a70d488105d59 100644 --- a/src/tests/test_utils/common_test_utils/src/test_common.cpp +++ b/src/tests/test_utils/common_test_utils/src/test_common.cpp @@ -23,6 +23,10 @@ #include "psapi.h" #endif +#ifdef ENABLE_CONFORMANCE_PGQL +# include "common_test_utils/postgres_link.hpp" +#endif + namespace CommonTestUtils { inline size_t getVmSizeInKB() { @@ -61,9 +65,18 @@ inline size_t getVmSizeInKB() { TestsCommon::~TestsCommon() { InferenceEngine::executorManager()->clear(); + +#ifdef ENABLE_CONFORMANCE_PGQL + delete PGLink; + PGLink = nullptr; +#endif } -TestsCommon::TestsCommon() { +TestsCommon::TestsCommon() +#ifdef ENABLE_CONFORMANCE_PGQL + : PGLink(new PostgreSQLLink(this)) +#endif +{ auto memsize = getVmSizeInKB(); if (memsize != 0) { std::cout << "\nMEM_USAGE=" << memsize << "KB\n"; diff --git a/tests/layer_tests/common/utils/tf_utils.py b/tests/layer_tests/common/utils/tf_utils.py index 4cb8e80f828fe0..ee7ef8dc2a8224 100644 --- a/tests/layer_tests/common/utils/tf_utils.py +++ b/tests/layer_tests/common/utils/tf_utils.py @@ -82,12 +82,24 @@ def children(op, graph): return set(op for out in op.outputs for op in out.consumers()) +def collect_control_dependencies(graph): + control_dependents_map = {} + for op in graph.get_operations(): + for control_input in op.control_inputs: + if control_input.name not in control_dependents_map: + control_dependents_map[control_input.name] = [op] + else: + control_dependents_map[control_input.name].append(op) + return control_dependents_map + + def summarize_graph(model_path, output_nodes_for_freeze=None, reshape_net=None): placeholders = dict() variables = list() outputs = list() graph = load_graph(model_path, output_nodes_for_freeze) unlikely_output_types = ['Const', 'Assign', 'NoOp', 'Placeholder', 'Assert', 'switch_t', 'switch_f'] + control_dependents_map = collect_control_dependencies(graph) for node in graph.as_graph_def().node: if node.op == 'Placeholder': node_dict = dict() @@ -98,7 +110,7 @@ def summarize_graph(model_path, output_nodes_for_freeze=None, reshape_net=None): placeholders[node.name] = node_dict if node.op == "Variable" or node.op == "VariableV2": variables.append(node.name) - if len(children(node.name, graph)) == 0: + if len(children(node.name, graph)) == 0 and node.name not in control_dependents_map: if node.op not in unlikely_output_types and node.name.split('/')[-1] not in unlikely_output_types: outputs.append(node.name) result = dict() diff --git a/tests/layer_tests/mo_python_api_tests/test_mo_convert_tf.py b/tests/layer_tests/mo_python_api_tests/test_mo_convert_tf.py index f83b75a78e7e9c..b7747f066cf3b5 100644 --- a/tests/layer_tests/mo_python_api_tests/test_mo_convert_tf.py +++ b/tests/layer_tests/mo_python_api_tests/test_mo_convert_tf.py @@ -587,6 +587,29 @@ def __call__(self, input1): return model, model_ref, {'example_input': example_input} +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 @@ -608,6 +631,7 @@ class TestMoConvertTF(CommonMOConvertTest): create_keras_layer_with_tf_function_call, 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, diff --git a/tests/layer_tests/pytorch_tests/test_min_max.py b/tests/layer_tests/pytorch_tests/test_min_max.py index e962b48b72b3ab..211cf76d06a472 100644 --- a/tests/layer_tests/pytorch_tests/test_min_max.py +++ b/tests/layer_tests/pytorch_tests/test_min_max.py @@ -123,13 +123,9 @@ def forward(self, x: float, y: float): {"first_input": 0, "second_input": 1, "dtype": "int"}, {"first_input": 1, "second_input": 1, "dtype": "int"}, {"first_input": 2, "second_input": 1, "dtype": "int"}, - # is not supported by OV - pytest.param({"first_input": 0, "second_input": 1, - "dtype": "bool"}, marks=pytest.mark.xfail), - pytest.param({"first_input": 1, "second_input": 1, - "dtype": "bool"}, marks=pytest.mark.xfail), - pytest.param({"first_input": 2, "second_input": 1, - "dtype": "bool"}, marks=pytest.mark.xfail), + {"first_input": 0, "second_input": 1, "dtype": "bool"}, + {"first_input": 1, "second_input": 1, "dtype": "bool"}, + {"first_input": 2, "second_input": 1, "dtype": "bool"}, ]) @pytest.mark.nightly @pytest.mark.precommit @@ -187,13 +183,9 @@ def forward(self, x: float, y: float): {"first_input": 0, "second_input": 1, "dtype": "int"}, {"first_input": 1, "second_input": 1, "dtype": "int"}, {"first_input": 2, "second_input": 1, "dtype": "int"}, - # is not supported by OV - pytest.param({"first_input": 0, "second_input": 1, - "dtype": "bool"}, marks=pytest.mark.xfail), - pytest.param({"first_input": 1, "second_input": 1, - "dtype": "bool"}, marks=pytest.mark.xfail), - pytest.param({"first_input": 2, "second_input": 1, - "dtype": "bool"}, marks=pytest.mark.xfail), + {"first_input": 0, "second_input": 1, "dtype": "bool"}, + {"first_input": 1, "second_input": 1, "dtype": "bool"}, + {"first_input": 2, "second_input": 1, "dtype": "bool"}, ]) @pytest.mark.nightly @pytest.mark.precommit diff --git a/tests/layer_tests/tensorflow_tests/test_tf_If.py b/tests/layer_tests/tensorflow_tests/test_tf_If.py index 7bf40b2b41833f..0e4e7a6fb249e5 100644 --- a/tests/layer_tests/tensorflow_tests/test_tf_If.py +++ b/tests/layer_tests/tensorflow_tests/test_tf_If.py @@ -59,9 +59,9 @@ def else_branch(): test_data_basic = [ dict(x_shape=[3], y_shape=[2, 3], lower_control_flow=False), + dict(x_shape=[3], y_shape=[2, 3], lower_control_flow=True), dict(x_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=False), - pytest.param(dict(x_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=True), - marks=pytest.mark.xfail(reason="92632")) + dict(x_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=True) ] @pytest.mark.parametrize("params", test_data_basic) @@ -129,10 +129,87 @@ def else_branch(): test_data_basic = [ dict(ind_shape=[3], y_shape=[2, 3], lower_control_flow=False), + dict(ind_shape=[3], y_shape=[2, 3], lower_control_flow=True), dict(ind_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=False), - pytest.param(dict(ind_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=True), - marks=pytest.mark.xfail(reason="92632")) + dict(ind_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=True) + ] + + @pytest.mark.parametrize("params", test_data_basic) + @pytest.mark.precommit_tf_fe + @pytest.mark.nightly + def test_if_basic(self, params, ie_device, precision, ir_version, temp_dir, + use_new_frontend, use_old_api): + if ie_device == 'GPU': + pytest.xfail('104855') + self._test(*self.create_if_net(**params), + ie_device, precision, ir_version, temp_dir=temp_dir, + use_new_frontend=use_new_frontend, use_old_api=use_old_api) + + +class TestNestedIf(CommonTFLayerTest): + def _prepare_input(self, inputs_info): + assert 'x' in inputs_info, "Test error: inputs_info must contain `cond`" + assert 'y' in inputs_info, "Test error: inputs_info must contain `x`" + assert 'z' in inputs_info, "Test error: inputs_info must contain `y`" + x_shape = inputs_info['x'] + y_shape = inputs_info['y'] + z_shape = inputs_info['z'] + inputs_data = {} + inputs_data['x'] = np.random.randint(0, 6, x_shape).astype(np.int32) + inputs_data['y'] = np.random.randint(1, 10, y_shape).astype(np.float32) + inputs_data['z'] = np.random.randint(-50, 50, z_shape).astype(np.float32) + return inputs_data + + def create_if_net(self, y_shape, z_shape, lower_control_flow): + from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2 + def if_function(x, y, z): + def nested_then_branch(): + add = tf.add(y, z) + return add + + def nested_else_branch(): + mul = tf.multiply(y, z) + return mul + + def then_branch(): + output1 = tf.cond(x > 4, nested_then_branch, nested_else_branch) + output2 = tf.multiply(y, z) + output3 = tf.subtract(y, z) + return output1, output2, output3 + + def else_branch(): + const_two = tf.constant(2.0, dtype=tf.float32) + output1 = tf.add(y, const_two) + output1 = tf.add(output1, z) + output2 = tf.multiply(z, y) + output3 = z - y + const_two + return output1, output2, output3 + + if_output = tf.cond(x < 2, then_branch, else_branch) + output1 = tf.identity(if_output[0], name='output1') + output2 = tf.identity(if_output[1], name='output2') + output3 = tf.identity(if_output[2], name='output3') + return output1, output2, output3 + + tf_if_graph = tf.function(if_function) + x = np.random.randint(0, 8, []).astype(np.int32) + y = np.random.randint(1, 10, y_shape).astype(np.float32) + z = np.random.randint(-50, 50, z_shape).astype(np.float32) + concrete_func = tf_if_graph.get_concrete_function(x, y, z) + + # lower_control_flow defines representation of If operation + # in case of lower_control_flow=True it is decomposed into Switch and Merge nodes + frozen_func = convert_variables_to_constants_v2(concrete_func, + lower_control_flow=lower_control_flow) + tf_net = frozen_func.graph.as_graph_def(add_shapes=True) + return tf_net, None + + test_data_basic = [ + dict(y_shape=[3], z_shape=[2, 3], lower_control_flow=False), + dict(y_shape=[3], z_shape=[2, 3], lower_control_flow=True), + dict(y_shape=[2, 1, 4], z_shape=[2, 1, 4], lower_control_flow=False), + dict(y_shape=[2, 1, 4], z_shape=[2, 1, 4], lower_control_flow=True) ] @pytest.mark.parametrize("params", test_data_basic) @@ -145,3 +222,93 @@ def test_if_basic(self, params, ie_device, precision, ir_version, temp_dir, self._test(*self.create_if_net(**params), ie_device, precision, ir_version, temp_dir=temp_dir, use_new_frontend=use_new_frontend, use_old_api=use_old_api) + + +class TestSequantialIfs(CommonTFLayerTest): + def _prepare_input(self, inputs_info): + assert 'cond' in inputs_info, "Test error: inputs_info must contain `cond`" + assert 'x' in inputs_info, "Test error: inputs_info must contain `x`" + assert 'y' in inputs_info, "Test error: inputs_info must contain `y`" + cond_shape = inputs_info['cond'] + x_shape = inputs_info['x'] + y_shape = inputs_info['y'] + inputs_data = {} + inputs_data['cond'] = np.random.randint(0, 2, cond_shape).astype(bool) + inputs_data['x'] = np.random.randint(1, 10, x_shape).astype(np.float32) + inputs_data['y'] = np.random.randint(-50, 50, y_shape).astype(np.float32) + return inputs_data + + def create_sequential_ifs_net(self, x_shape, y_shape, lower_control_flow): + from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2 + def sequential_ifs(cond, x, y): + def if1(cond1, x1, y1): + def then_branch(): + add = tf.add(x1, y1) + mul = tf.multiply(x1, y1) + return add, mul + + def else_branch(): + const_two = tf.constant(2.0, dtype=tf.float32) + add = tf.add(y1, const_two) + mul = tf.multiply(const_two, y1) + return add, mul + + if1_op = tf.cond(cond1, then_branch, else_branch) + output1 = tf.identity(if1_op[0], name='output1') + output2 = tf.identity(if1_op[1], name='output2') + return output1, output2 + + def if2(cond1, x2, y2): + def then_branch(): + const_two = tf.constant(2.0, dtype=tf.float32) + add = tf.add(y2, const_two) + mul = tf.multiply(const_two, y2) + return add, mul + + def else_branch(): + add = tf.add(x2, y2) + mul = tf.multiply(x2, y2) + return add, mul + + if2_op = tf.cond(cond1, then_branch, else_branch) + output1 = tf.identity(if2_op[0], name='output1') + output2 = tf.identity(if2_op[1], name='output2') + return output1, output2 + + output1, output2 = if1(cond, x, y) + const_ten = tf.constant(10.0, dtype=tf.float32) + output1 = tf.add(output1, const_ten) + output1, output2 = if2(cond, output1, output2) + return output1, output2 + + tf_if_graph = tf.function(sequential_ifs) + cond = np.random.randint(0, 2, []).astype(bool) + x = np.random.randint(1, 10, x_shape).astype(np.float32) + y = np.random.randint(-50, 50, y_shape).astype(np.float32) + concrete_func = tf_if_graph.get_concrete_function(cond, x, y) + + # lower_control_flow defines representation of If operation + # in case of lower_control_flow=True it is decomposed into Switch and Merge nodes + frozen_func = convert_variables_to_constants_v2(concrete_func, + lower_control_flow=lower_control_flow) + + tf_net = frozen_func.graph.as_graph_def(add_shapes=True) + return tf_net, None + + test_data_basic = [ + dict(x_shape=[3], y_shape=[2, 3], lower_control_flow=False), + dict(x_shape=[3], y_shape=[2, 3], lower_control_flow=True), + dict(x_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=False), + dict(x_shape=[2, 1, 4], y_shape=[2, 1, 4], lower_control_flow=True) + ] + + @pytest.mark.parametrize("params", test_data_basic) + @pytest.mark.precommit_tf_fe + @pytest.mark.nightly + def test_if_basic(self, params, ie_device, precision, ir_version, temp_dir, + use_new_frontend, use_old_api): + if ie_device == 'GPU': + pytest.xfail('104855') + self._test(*self.create_sequential_ifs_net(**params), + ie_device, precision, ir_version, temp_dir=temp_dir, + use_new_frontend=use_new_frontend, use_old_api=use_old_api) diff --git a/tools/benchmark_tool/openvino/tools/benchmark/main.py b/tools/benchmark_tool/openvino/tools/benchmark/main.py index 821e81b97d0511..47dbd8d9b09b12 100644 --- a/tools/benchmark_tool/openvino/tools/benchmark/main.py +++ b/tools/benchmark_tool/openvino/tools/benchmark/main.py @@ -487,8 +487,8 @@ def set_nthreads_pin(property_name, property_value): static_mode = check_for_static(app_inputs_info) allow_inference_only_or_sync = can_measure_as_static(app_inputs_info) if not allow_inference_only_or_sync and benchmark.api_type == 'sync': - raise Exception("Benchmarking of the model with dynamic shapes is available for async API only." - "Please use -api async -nstreams 1 -nireq 1 to emulate sync behavior.") + raise Exception("Benchmarking of the model with dynamic shapes is available for async API only. " + "Please use -api async -hint latency -nireq 1 to emulate sync behavior.") if benchmark.inference_only == None: if static_mode: @@ -499,7 +499,7 @@ def set_nthreads_pin(property_name, property_value): raise Exception("Benchmarking dynamic model available with input filling in measurement loop only!") # update batch size in case dynamic network with one data_shape - if benchmark.inference_only and batch_size.is_dynamic: + if allow_inference_only_or_sync and batch_size.is_dynamic: batch_size = Dimension(data_queue.batch_sizes[data_queue.current_group_id]) benchmark.latency_groups = get_latency_groups(app_inputs_info) diff --git a/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py b/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py index d4925a7b2701aa..51f88ab9751d1e 100644 --- a/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py +++ b/tools/benchmark_tool/openvino/tools/benchmark/utils/utils.py @@ -78,19 +78,10 @@ def get_element_type(precision): def fuse_mean_scale(preproc: PrePostProcessor, app_inputs_info): - # TODO: remove warning after 23.3 release - warned = False - warn_msg = 'Mean/scale values are fused into the model. This slows down performance compared to --imean and --iscale which existed before' for input_info in app_inputs_info: if input_info.mean.size: - if not warned: - logger.warning(warn_msg) - warned = True preproc.input(input_info.name).preprocess().convert_element_type(Type.f32).mean(input_info.mean) if input_info.scale.size: - if not warned: - logger.warning(warn_msg) - warned = True preproc.input(input_info.name).preprocess().convert_element_type(Type.f32).scale(input_info.scale) @@ -272,7 +263,7 @@ def check_for_static(app_input_info): def can_measure_as_static(app_input_info): for info in app_input_info: - if info.is_dynamic and (len(info.shapes) > 1 or info.original_shape.is_static): + if len(info.shapes) > 1: return False return True @@ -559,7 +550,6 @@ class AppInputInfo: def __init__(self): self.element_type = None self.layout = Layout() - self.original_shape = None self.partial_shape = None self.data_shapes = [] self.scale = np.empty([0]) @@ -650,7 +640,6 @@ def get_inputs_info(shape_string, data_shape_string, layout_string, batch_size, # Input precision info.element_type = inputs[i].element_type # Shape - info.original_shape = inputs[i].partial_shape if info.name in shape_map: info.partial_shape = PartialShape(shape_map[info.name]) reshape = True diff --git a/tools/benchmark_tool/requirements.txt b/tools/benchmark_tool/requirements.txt index 690121c422363b..27c8e198ca9b78 100644 --- a/tools/benchmark_tool/requirements.txt +++ b/tools/benchmark_tool/requirements.txt @@ -1,3 +1,2 @@ -c ../constraints.txt numpy>=1.16.6 -opencv-python diff --git a/tools/constraints.txt b/tools/constraints.txt index d068998dce4435..aefb57a31ce3a9 100644 --- a/tools/constraints.txt +++ b/tools/constraints.txt @@ -19,4 +19,3 @@ test-generator==0.1.1 py>=1.9.0 urllib3>=1.26.4 openvino-telemetry>=2022.1.0 -opencv-python>=4.5 \ No newline at end of file diff --git a/tools/mo/openvino/tools/mo/convert_impl.py b/tools/mo/openvino/tools/mo/convert_impl.py index 53f085cf47c668..40f4d2145f8206 100644 --- a/tools/mo/openvino/tools/mo/convert_impl.py +++ b/tools/mo/openvino/tools/mo/convert_impl.py @@ -314,8 +314,6 @@ def update_fallback_with_conversion_error(use_new_frontend: bool, is_tf: bool, e # corresponds to TF1 While operation "TensorArrayScatterV3", "TensorArrayV3", "TensorArraySizeV3", "TensorArrayGatherV3", "LoopCond", "Enter", "NextIteration", "Exit", - # corresponds to TF1 If and TF1 While operations - "Switch", "Merge", # corresponds to operations with complex tensors "FFT", "FFT2D", "FFT3D", "IFFT", "IFFT2D", "IFFT3D", "RFFT", "RFFT2D", "RFFT3D", "IRFFT", "IRFFT2D", "IRFFT3D", diff --git a/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py b/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py index 554740094d0165..8d458e3a899f23 100644 --- a/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py +++ b/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py @@ -98,7 +98,7 @@ def test_tf_fe_message_fallback(self, mock_argparse): main(argparse.ArgumentParser()) std_out = f.getvalue() tf_fe_message_found = get_tf_fe_message() in std_out - assert not tf_fe_message_found, 'TF FE Info message is found for the fallback case' + assert tf_fe_message_found, 'TF FE Info message is found for the fallback case' class TestInfoMessagesCompressFP16(unittest.TestCase): diff --git a/tools/ovc/openvino/tools/ovc/convert_impl.py b/tools/ovc/openvino/tools/ovc/convert_impl.py index 46b898042b0484..d89d248d7179a7 100644 --- a/tools/ovc/openvino/tools/ovc/convert_impl.py +++ b/tools/ovc/openvino/tools/ovc/convert_impl.py @@ -269,8 +269,6 @@ def update_fallback_with_conversion_error(use_new_frontend: bool, is_tf: bool, e # corresponds to TF1 While operation "TensorArrayScatterV3", "TensorArrayV3", "TensorArraySizeV3", "TensorArrayGatherV3", "LoopCond", "Enter", "NextIteration", "Exit", - # corresponds to TF1 If and TF1 While operations - "Switch", "Merge", # corresponds to operations with complex tensors "FFT", "FFT2D", "FFT3D", "IFFT", "IFFT2D", "IFFT3D", "RFFT", "RFFT2D", "RFFT3D", "IRFFT", "IRFFT2D", "IRFFT3D", diff --git a/tools/ovc/unit_tests/moc_tf_fe/check_info_messages_test.py b/tools/ovc/unit_tests/moc_tf_fe/check_info_messages_test.py index 9b08d9d35ef24c..8926d22f1342d1 100644 --- a/tools/ovc/unit_tests/moc_tf_fe/check_info_messages_test.py +++ b/tools/ovc/unit_tests/moc_tf_fe/check_info_messages_test.py @@ -100,7 +100,7 @@ def test_tf_fe_message_fallback(self, mock_argparse): main() std_out = f.getvalue() tf_fe_message_found = get_try_legacy_fe_message() in std_out - assert not tf_fe_message_found, 'TF FE Info message is found for the fallback case' + assert tf_fe_message_found, 'TF FE Info message is found for the fallback case' @patch('argparse.ArgumentParser.parse_args', return_value=arg_parse_helper(input_model="model_int32.pbtxt",