diff --git a/.ci/azure/linux.yml b/.ci/azure/linux.yml index 2c20f894ba8ca4..7d7454f8794849 100644 --- a/.ci/azure/linux.yml +++ b/.ci/azure/linux.yml @@ -64,7 +64,7 @@ jobs: Static: CMAKE_BUILD_SHARED_LIBS: 'OFF' PYTHON_STATIC_ARGS: -m "not dynamic_library" - CMAKE_CPACK_GENERATOR: + CMAKE_CPACK_GENERATOR: "TGZ" SAMPLES_INSTALL_DIR: $(INSTALL_DIR)/samples PYTHON_SAMPLES_INSTALL_DIR: $(SAMPLES_INSTALL_DIR)/python RUN_PREFIX: . $(SETUPVARS) && diff --git a/CMakeLists.txt b/CMakeLists.txt index fad19139a1de77..461f1a209cb1c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ message (STATUS "CMAKE_VERSION ......................... " ${CMAKE_VERSION}) message (STATUS "OpenVINO_SOURCE_DIR ................... " ${OpenVINO_SOURCE_DIR}) message (STATUS "OpenVINO_BINARY_DIR ................... " ${OpenVINO_BINARY_DIR}) message (STATUS "CMAKE_GENERATOR ....................... " ${CMAKE_GENERATOR}) +message (STATUS "CPACK_GENERATOR ....................... " ${CPACK_GENERATOR}) message (STATUS "CMAKE_C_COMPILER_ID ................... " ${CMAKE_C_COMPILER_ID}) message (STATUS "CMAKE_CXX_COMPILER_ID ................. " ${CMAKE_CXX_COMPILER_ID}) if(OV_GENERATOR_MULTI_CONFIG) diff --git a/cmake/developer_package/packaging/archive.cmake b/cmake/developer_package/packaging/archive.cmake new file mode 100644 index 00000000000000..7513a72f880f96 --- /dev/null +++ b/cmake/developer_package/packaging/archive.cmake @@ -0,0 +1,90 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +include(GNUInstallDirs) + +# +# ov_archive_cpack_set_dirs() +# +# Set directories for ARCHIVE cpack +# +macro(ov_archive_cpack_set_dirs) + # common "archive" package locations + # TODO: move current variables to OpenVINO specific locations + set(OV_CPACK_INCLUDEDIR runtime/include) + set(OV_CPACK_IE_CMAKEDIR runtime/cmake) + set(OV_CPACK_NGRAPH_CMAKEDIR runtime/cmake) + set(OV_CPACK_OPENVINO_CMAKEDIR runtime/cmake) + set(OV_CPACK_DOCDIR docs) + set(OV_CPACK_LICENSESDIR licenses) + set(OV_CPACK_SAMPLESDIR samples) + set(OV_CPACK_WHEELSDIR tools) + set(OV_CPACK_TOOLSDIR tools) + set(OV_CPACK_DEVREQDIR tools) + set(OV_CPACK_PYTHONDIR python) + + if(WIN32) + set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_CPACK_RUNTIMEDIR runtime/bin/${ARCH_FOLDER}/$) + set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_WHEEL_RUNTIMEDIR runtime/bin/${ARCH_FOLDER}/Release) + elseif(APPLE) + set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_CPACK_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_WHEEL_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}/Release) + else() + set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}) + set(OV_CPACK_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}) + set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}) + set(OV_WHEEL_RUNTIMEDIR ${OV_CPACK_RUNTIMEDIR}) + endif() + set(OV_CPACK_PLUGINSDIR ${OV_CPACK_RUNTIMEDIR}) + + # for BW compatibility + set(IE_CPACK_LIBRARY_PATH ${OV_CPACK_LIBRARYDIR}) + set(IE_CPACK_RUNTIME_PATH ${OV_CPACK_RUNTIMEDIR}) + set(IE_CPACK_ARCHIVE_PATH ${OV_CPACK_ARCHIVEDIR}) +endmacro() + +ov_archive_cpack_set_dirs() + +# +# Override include / exclude rules for components +# This is required to exclude some files from installation +# (e.g. archive packages don't require python_package component) +# + +macro(ov_define_component_include_rules) + # core components + unset(OV_CPACK_COMP_CORE_EXCLUDE_ALL) + unset(OV_CPACK_COMP_CORE_C_EXCLUDE_ALL) + unset(OV_CPACK_COMP_CORE_DEV_EXCLUDE_ALL) + unset(OV_CPACK_COMP_CORE_C_DEV_EXCLUDE_ALL) + # licensing + unset(OV_CPACK_COMP_LICENSING_EXCLUDE_ALL) + # samples + unset(OV_CPACK_COMP_CPP_SAMPLES_EXCLUDE_ALL) + unset(OV_CPACK_COMP_C_SAMPLES_EXCLUDE_ALL) + unset(OV_CPACK_COMP_PYTHON_SAMPLES_EXCLUDE_ALL) + # python + unset(OV_CPACK_COMP_PYTHON_OPENVINO_EXCLUDE_ALL) + unset(OV_CPACK_COMP_BENCHMARK_APP_EXCLUDE_ALL) + unset(OV_CPACK_COMP_OVC_EXCLUDE_ALL) + set(OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE_EXCLUDE_ALL EXCLUDE_FROM_ALL) + unset(OV_CPACK_COMP_PYTHON_WHEELS_EXCLUDE_ALL) + # tools + set(OV_CPACK_COMP_OPENVINO_DEV_REQ_FILES_EXCLUDE_ALL EXCLUDE_FROM_ALL) + unset(OV_CPACK_COMP_DEPLOYMENT_MANAGER_EXCLUDE_ALL) + # scripts + unset(OV_CPACK_COMP_INSTALL_DEPENDENCIES_EXCLUDE_ALL) + unset(OV_CPACK_COMP_SETUPVARS_EXCLUDE_ALL) +endmacro() + +ov_define_component_include_rules() + +# New in version 3.18 +set(CPACK_ARCHIVE_THREADS 8) +# multiple packages are generated +set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) diff --git a/cmake/developer_package/packaging/nsis.cmake b/cmake/developer_package/packaging/nsis.cmake index 1a89f39344016c..f5393357d0ab51 100644 --- a/cmake/developer_package/packaging/nsis.cmake +++ b/cmake/developer_package/packaging/nsis.cmake @@ -43,6 +43,52 @@ endmacro() ov_nsis_specific_settings() +# +# ov_nsis_cpack_set_dirs() +# +# Set directories for ARCHIVE cpack +# +macro(ov_archive_cpack_set_dirs) + # common "archive" package locations + # TODO: move current variables to OpenVINO specific locations + set(OV_CPACK_INCLUDEDIR runtime/include) + set(OV_CPACK_IE_CMAKEDIR runtime/cmake) + set(OV_CPACK_NGRAPH_CMAKEDIR runtime/cmake) + set(OV_CPACK_OPENVINO_CMAKEDIR runtime/cmake) + set(OV_CPACK_DOCDIR docs) + set(OV_CPACK_LICENSESDIR licenses) + set(OV_CPACK_SAMPLESDIR samples) + set(OV_CPACK_WHEELSDIR tools) + set(OV_CPACK_TOOLSDIR tools) + set(OV_CPACK_DEVREQDIR tools) + set(OV_CPACK_PYTHONDIR python) + + if(WIN32) + set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_CPACK_RUNTIMEDIR runtime/bin/${ARCH_FOLDER}/$) + set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_WHEEL_RUNTIMEDIR runtime/bin/${ARCH_FOLDER}/Release) + elseif(APPLE) + set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_CPACK_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}/$) + set(OV_WHEEL_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}/Release) + else() + set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}) + set(OV_CPACK_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}) + set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}) + set(OV_WHEEL_RUNTIMEDIR ${OV_CPACK_RUNTIMEDIR}) + endif() + set(OV_CPACK_PLUGINSDIR ${OV_CPACK_RUNTIMEDIR}) + + # for BW compatibility + set(IE_CPACK_LIBRARY_PATH ${OV_CPACK_LIBRARYDIR}) + set(IE_CPACK_RUNTIME_PATH ${OV_CPACK_RUNTIMEDIR}) + set(IE_CPACK_ARCHIVE_PATH ${OV_CPACK_ARCHIVEDIR}) +endmacro() + +ov_nsis_cpack_set_dirs() + # # Override include / exclude rules for components # This is required to exclude some files from installation diff --git a/cmake/developer_package/packaging/packaging.cmake b/cmake/developer_package/packaging/packaging.cmake index e1d9b60f6079de..50a9d14e2e5d40 100644 --- a/cmake/developer_package/packaging/packaging.cmake +++ b/cmake/developer_package/packaging/packaging.cmake @@ -39,52 +39,6 @@ function(ov_get_pyversion pyversion) endif() endfunction() -# -# ov_cpack_set_dirs() -# -# Set directories for cpack -# -macro(ov_cpack_set_dirs) - # common IRC package locations - # TODO: move current variables to OpenVINO specific locations - set(OV_CPACK_INCLUDEDIR runtime/include) - set(OV_CPACK_IE_CMAKEDIR runtime/cmake) - set(OV_CPACK_NGRAPH_CMAKEDIR runtime/cmake) - set(OV_CPACK_OPENVINO_CMAKEDIR runtime/cmake) - set(OV_CPACK_DOCDIR docs) - set(OV_CPACK_LICENSESDIR licenses) - set(OV_CPACK_SAMPLESDIR samples) - set(OV_CPACK_WHEELSDIR tools) - set(OV_CPACK_TOOLSDIR tools) - set(OV_CPACK_DEVREQDIR tools) - set(OV_CPACK_PYTHONDIR python) - - if(WIN32) - set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}/$) - set(OV_CPACK_RUNTIMEDIR runtime/bin/${ARCH_FOLDER}/$) - set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}/$) - set(OV_WHEEL_RUNTIMEDIR runtime/bin/${ARCH_FOLDER}/Release) - elseif(APPLE) - set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}/$) - set(OV_CPACK_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}/$) - set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}/$) - set(OV_WHEEL_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}/Release) - else() - set(OV_CPACK_LIBRARYDIR runtime/lib/${ARCH_FOLDER}) - set(OV_CPACK_RUNTIMEDIR runtime/lib/${ARCH_FOLDER}) - set(OV_CPACK_ARCHIVEDIR runtime/lib/${ARCH_FOLDER}) - set(OV_WHEEL_RUNTIMEDIR ${OV_CPACK_RUNTIMEDIR}) - endif() - set(OV_CPACK_PLUGINSDIR ${OV_CPACK_RUNTIMEDIR}) - - # for BW compatibility - set(IE_CPACK_LIBRARY_PATH ${OV_CPACK_LIBRARYDIR}) - set(IE_CPACK_RUNTIME_PATH ${OV_CPACK_RUNTIMEDIR}) - set(IE_CPACK_ARCHIVE_PATH ${OV_CPACK_ARCHIVEDIR}) -endmacro() - -ov_cpack_set_dirs() - # # ov_cpack_add_component(NAME ...) # @@ -169,38 +123,15 @@ endmacro() ov_define_component_names() -# default components for case when CPACK_GENERATOR is not set (i.e. default open source user) -macro(ov_define_component_include_rules) - # core components - unset(OV_CPACK_COMP_CORE_EXCLUDE_ALL) - unset(OV_CPACK_COMP_CORE_C_EXCLUDE_ALL) - unset(OV_CPACK_COMP_CORE_DEV_EXCLUDE_ALL) - unset(OV_CPACK_COMP_CORE_C_DEV_EXCLUDE_ALL) - # licensing - unset(OV_CPACK_COMP_LICENSING_EXCLUDE_ALL) - # samples - unset(OV_CPACK_COMP_CPP_SAMPLES_EXCLUDE_ALL) - unset(OV_CPACK_COMP_C_SAMPLES_EXCLUDE_ALL) - unset(OV_CPACK_COMP_PYTHON_SAMPLES_EXCLUDE_ALL) - # python - unset(OV_CPACK_COMP_PYTHON_OPENVINO_EXCLUDE_ALL) - unset(OV_CPACK_COMP_BENCHMARK_APP_EXCLUDE_ALL) - unset(OV_CPACK_COMP_OVC_EXCLUDE_ALL) - set(OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE_EXCLUDE_ALL EXCLUDE_FROM_ALL) - unset(OV_CPACK_COMP_PYTHON_WHEELS_EXCLUDE_ALL) - # tools - set(OV_CPACK_COMP_OPENVINO_DEV_REQ_FILES_EXCLUDE_ALL EXCLUDE_FROM_ALL) - unset(OV_CPACK_COMP_DEPLOYMENT_MANAGER_EXCLUDE_ALL) - # scripts - unset(OV_CPACK_COMP_INSTALL_DEPENDENCIES_EXCLUDE_ALL) - unset(OV_CPACK_COMP_SETUPVARS_EXCLUDE_ALL) -endmacro() - -ov_define_component_include_rules() +if(NOT DEFINED CPACK_GENERATOR) + set(CPACK_GENERATOR "TGZ") +elseif(NOT CPACK_GENERATOR) + message(FATAL_ERROR "CPACK_GENERATOR cannot contain an empty value") +endif() # # Include generator specific configuration file: -# 1. Overrides directories set by ov__cpack_set_dirs() +# 1. Overrides directories set by ov__cpack_set_dirs() # This is requried, because different generator use different locations for installed files # 2. Merges some components using ov_override_component_names() # This is required, because different generators have different set of components @@ -230,12 +161,11 @@ elseif(CPACK_GENERATOR STREQUAL "NSIS") include(packaging/nsis) elseif(CPACK_GENERATOR MATCHES "^(CONDA-FORGE|BREW|CONAN|VCPKG)$") include(packaging/common-libraries) +elseif(CPACK_GENERATOR MATCHES "^(7Z|TBZ2|TGZ|TXZ|TZ|TZST|ZIP)$") + include(packaging/archive) endif() macro(ie_cpack) - if(NOT DEFINED CPACK_GENERATOR) - set(CPACK_GENERATOR "TGZ") - endif() set(CPACK_SOURCE_GENERATOR "") # not used set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenVINO™ Toolkit") set(CPACK_COMPONENT_UNSPECIFIED_REQUIRED OFF) @@ -287,18 +217,10 @@ macro(ie_cpack) # include GENERATOR dedicated per-component configuration file # NOTE: private modules need to define ov_cpack_settings macro - # for custom packages configuration + # for custom packages configuration if(COMMAND ov_cpack_settings) ov_cpack_settings() endif() - # generator specific variables - if(CPACK_GENERATOR MATCHES "^(7Z|TBZ2|TGZ|TXZ|TZ|ZIP)$") - # New in version 3.18 - set(CPACK_ARCHIVE_THREADS 8) - # multiple packages are generated - set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) - endif() - include(CPack) endmacro() diff --git a/cmake/packaging/archive.cmake b/cmake/packaging/archive.cmake new file mode 100644 index 00000000000000..59bdc01eb0427b --- /dev/null +++ b/cmake/packaging/archive.cmake @@ -0,0 +1,23 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +# +# OpenVINO Core components including frontends, plugins, etc +# +macro(ov_cpack_settings) + # fill a list of components which are part of conda + set(cpack_components_all ${CPACK_COMPONENTS_ALL}) + unset(CPACK_COMPONENTS_ALL) + foreach(item IN LISTS cpack_components_all) + string(TOUPPER ${item} UPPER_COMP) + # filter out some components, which are not needed to be wrapped to conda-forge | brew | conan | vcpkg + if(NOT OV_CPACK_COMP_${UPPER_COMP}_EXCLUDE_ALL AND + # python_package is not needed in case of archives, because components like pyopenvino are used, as well as wheels + NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_python.*") + list(APPEND CPACK_COMPONENTS_ALL ${item}) + endif() + endforeach() + unset(cpack_components_all) + list(REMOVE_DUPLICATES CPACK_COMPONENTS_ALL) +endmacro() diff --git a/cmake/packaging/common-libraries.cmake b/cmake/packaging/common-libraries.cmake index 5d2f7bd79e9e89..9b96ed528609df 100644 --- a/cmake/packaging/common-libraries.cmake +++ b/cmake/packaging/common-libraries.cmake @@ -13,6 +13,8 @@ macro(ov_cpack_settings) string(TOUPPER ${item} UPPER_COMP) # filter out some components, which are not needed to be wrapped to conda-forge | brew | conan | vcpkg if(NOT OV_CPACK_COMP_${UPPER_COMP}_EXCLUDE_ALL AND + # because in case of VCPKG | CONAN | BREW | CONDA-FORGE distributions, python is either not needed or installed separately + (NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_python.*" OR ENABLE_PYTHON_PACKAGING) AND # even for case of system TBB we have installation rules for wheels packages # so, need to skip this explicitly since they are installed in `host` section NOT item MATCHES "^tbb(_dev)?$" AND @@ -21,6 +23,7 @@ macro(ov_cpack_settings) list(APPEND CPACK_COMPONENTS_ALL ${item}) endif() endforeach() + unset(cpack_components_all) list(REMOVE_DUPLICATES CPACK_COMPONENTS_ALL) # override generator diff --git a/cmake/packaging/debian.cmake b/cmake/packaging/debian.cmake index 49a1ad9fe08d36..766209977340bb 100644 --- a/cmake/packaging/debian.cmake +++ b/cmake/packaging/debian.cmake @@ -47,7 +47,7 @@ macro(ov_cpack_settings) string(TOUPPER ${item} UPPER_COMP) # filter out some components, which are not needed to be wrapped to .deb package if(NOT OV_CPACK_COMP_${UPPER_COMP}_EXCLUDE_ALL AND - # skip OpenVINO Python API (pattern in form of "_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") + # skip OpenVINO Python API (pattern in form of "pyopenvino_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO}_python.*" AND # because in case of .deb package, pyopenvino_package_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR} is installed (NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_python.*" OR ENABLE_PYTHON_PACKAGING) AND @@ -65,6 +65,7 @@ macro(ov_cpack_settings) list(APPEND CPACK_COMPONENTS_ALL ${item}) endif() endforeach() + unset(cpack_components_all) list(REMOVE_DUPLICATES CPACK_COMPONENTS_ALL) # version with 3 components diff --git a/cmake/packaging/nsis.cmake b/cmake/packaging/nsis.cmake index b6e809514ca713..e5467ee5afedec 100644 --- a/cmake/packaging/nsis.cmake +++ b/cmake/packaging/nsis.cmake @@ -15,6 +15,7 @@ macro(ov_cpack_settings) list(APPEND CPACK_COMPONENTS_ALL ${item}) endif() endforeach() + unset(cpack_components_all) # restore the components settings diff --git a/cmake/packaging/packaging.cmake b/cmake/packaging/packaging.cmake index a4e165d615d310..7d685f43143de0 100644 --- a/cmake/packaging/packaging.cmake +++ b/cmake/packaging/packaging.cmake @@ -3,11 +3,13 @@ # if(CPACK_GENERATOR STREQUAL "DEB") - include(cmake/packaging/debian.cmake) + include("${OpenVINO_SOURCE_DIR}/cmake/packaging/debian.cmake") elseif(CPACK_GENERATOR STREQUAL "RPM") - include(cmake/packaging/rpm.cmake) + include("${OpenVINO_SOURCE_DIR}/cmake/packaging/rpm.cmake") elseif(CPACK_GENERATOR MATCHES "^(CONDA-FORGE|BREW|CONAN|VCPKG)$") - include(cmake/packaging/common-libraries.cmake) + include("${OpenVINO_SOURCE_DIR}/cmake/packaging/common-libraries.cmake") +elseif(CPACK_GENERATOR MATCHES "^(7Z|TBZ2|TGZ|TXZ|TZ|TZST|ZIP)$") + include("${OpenVINO_SOURCE_DIR}/cmake/packaging/archive.cmake") elseif(CPACK_GENERATOR STREQUAL "NSIS") - include(cmake/packaging/nsis.cmake) + include("${OpenVINO_SOURCE_DIR}/cmake/packaging/nsis.cmake") endif() diff --git a/cmake/packaging/rpm.cmake b/cmake/packaging/rpm.cmake index 24ce1b2cb0696b..d3dd22bcdbd195 100644 --- a/cmake/packaging/rpm.cmake +++ b/cmake/packaging/rpm.cmake @@ -33,7 +33,7 @@ macro(ov_cpack_settings) string(TOUPPER ${item} UPPER_COMP) # filter out some components, which are not needed to be wrapped to .rpm package if(NOT OV_CPACK_COMP_${UPPER_COMP}_EXCLUDE_ALL AND - # skip OpenVINO Python API (pattern in form of "_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") + # skip OpenVINO Python API (pattern in form of "pyopenvino_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO}_python.*" AND # because in case of .rpm package, pyopenvino_package_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR} is installed (NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_python.*" OR ENABLE_PYTHON_PACKAGING) AND @@ -51,6 +51,7 @@ macro(ov_cpack_settings) list(APPEND CPACK_COMPONENTS_ALL ${item}) endif() endforeach() + unset(cpack_components_all) list(REMOVE_DUPLICATES CPACK_COMPONENTS_ALL) # version with 3 components diff --git a/docs/snippets/CMakeLists.txt b/docs/snippets/CMakeLists.txt index c2712751e0d91c..38567b063f35a9 100644 --- a/docs/snippets/CMakeLists.txt +++ b/docs/snippets/CMakeLists.txt @@ -111,7 +111,6 @@ if(ENABLE_PYTHON) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${PYTHON_SNIPPETS_OUTPUT_DIR}" output_file ${python_snippet}) set(output_file "${PYTHON_SNIPPETS_OUTPUT_DIR}/${output_file}.txt") add_custom_command(OUTPUT ${output_file} - COMMAND ${PYTHON_EXECUTABLE} -m py_compile ${python_snippet} COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHON_BRIDGE_OUTPUT_DIRECTORY} ${PYTHON_EXECUTABLE} ${python_snippet} COMMAND ${CMAKE_COMMAND} -E touch ${output_file} @@ -122,6 +121,8 @@ if(ENABLE_PYTHON) list(APPEND outputs ${output_file}) endforeach() + message(WARNING "!!!!!!!!!!! ${outputs}") + add_custom_target(${TARGET_NAME}_python DEPENDS ${outputs}) endif() diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index facfb2218312e6..2e41c7e7802fbd 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -364,5 +364,8 @@ if(ENABLE_TESTS) endif() if(OpenVINODeveloperPackage_FOUND) + # provides a callback function to describe each component in repo + include("${OpenVINO_SOURCE_DIR}/cmake/packaging/packaging.cmake") + ie_cpack(${IE_CPACK_COMPONENTS_ALL}) endif() diff --git a/src/bindings/python/src/openvino/frontend/pytorch/ts_decoder.py b/src/bindings/python/src/openvino/frontend/pytorch/ts_decoder.py index ce8c60c864dbaf..e07a23dc5cccc1 100644 --- a/src/bindings/python/src/openvino/frontend/pytorch/ts_decoder.py +++ b/src/bindings/python/src/openvino/frontend/pytorch/ts_decoder.py @@ -58,8 +58,15 @@ def __init__(self, pt_module, graph_element=None, example_input=None, alias_db=N self.pt_module = pt_module self.raw_inputs = list(self.graph_element.inputs()) self.raw_outputs = list(self.graph_element.outputs()) - if self._input_signature is not None and "self" in self.raw_inputs[0].debugName(): - self._input_signature.insert(0, "self") + if self._input_signature is not None: + if "self" in self.raw_inputs[0].debugName(): + self._input_signature.insert(0, "self") + if 0 < len(self._input_signature) < len(self.raw_inputs): + # last input is args input, we need to multiply that name by number of extra inputs + self._input_signature = self._input_signature[:-1] + n = len(self._input_signature) + for i in range(len(self.raw_inputs) - n): + self._input_signature.append(self.raw_inputs[i + n].debugName()) if isinstance(self.graph_element, torch.Graph): self._transform_tensor_list_constants_to_listconstruct(self.graph_element) diff --git a/src/frontends/pytorch/src/utils_quantize.cpp b/src/frontends/pytorch/src/utils_quantize.cpp index a8820b8ffe473d..aee7d74eca9c51 100644 --- a/src/frontends/pytorch/src/utils_quantize.cpp +++ b/src/frontends/pytorch/src/utils_quantize.cpp @@ -156,8 +156,8 @@ Output quantize(const NodeContext& context, FRONT_END_OP_CONVERSION_CHECK(false, "Failed to convert a node to QuantizedPtNode"); } -std::shared_ptr cast_quantized_fw_node(Output node) { - auto quant_node = std::dynamic_pointer_cast(node.get_node_shared_ptr()); +std::shared_ptr cast_quantized_fw_node(std::shared_ptr node) { + auto quant_node = std::dynamic_pointer_cast(node); if (!quant_node) { return nullptr; } @@ -168,19 +168,6 @@ std::shared_ptr cast_quantized_fw_node(Output node) { return quant_node; } -std::shared_ptr cast_quantized_fw_node(Output node, const std::string& type) { - auto quant_node = std::dynamic_pointer_cast(node.get_node_shared_ptr()); - if (!quant_node) { - return nullptr; - } - const auto& attrs = quant_node->get_attrs(); - if (attrs.find(QuantizedPtNode::quantized_node_type_key) == attrs.end() || - attrs.at(QuantizedPtNode::quantized_node_type_key) != type) { - return nullptr; - } - return quant_node; -} - } // namespace pytorch } // namespace frontend } // namespace ov diff --git a/src/frontends/pytorch/src/utils_quantize.hpp b/src/frontends/pytorch/src/utils_quantize.hpp index a78855ca2b3eb5..0d5219f00885f7 100644 --- a/src/frontends/pytorch/src/utils_quantize.hpp +++ b/src/frontends/pytorch/src/utils_quantize.hpp @@ -140,8 +140,7 @@ Output quantize(const NodeContext& context, const Output& zero_point, const Output& quantized_node); -std::shared_ptr cast_quantized_fw_node(Output node); -std::shared_ptr cast_quantized_fw_node(Output node, const std::string& type); +std::shared_ptr cast_quantized_fw_node(std::shared_ptr node); namespace op { /** diff --git a/src/frontends/tensorflow/src/op_table.cpp b/src/frontends/tensorflow/src/op_table.cpp index c7cf8ff6195933..08abacac63cfdd 100644 --- a/src/frontends/tensorflow/src/op_table.cpp +++ b/src/frontends/tensorflow/src/op_table.cpp @@ -190,6 +190,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)}, + {"MaxPoolWithArgmax", CreatorFunction(translate_max_pool_op)}, {"Merge", CreatorFunction(translate_merge_op)}, {"MirrorPad", CreatorFunction(translate_mirror_pad_op)}, {"MutableHashTable", CreatorFunction(translate_hash_table_op)}, diff --git a/src/frontends/tensorflow_common/src/op/interpolate.cpp b/src/frontends/tensorflow_common/src/op/interpolate.cpp index c2c09295e4a024..a46acf773e5376 100644 --- a/src/frontends/tensorflow_common/src/op/interpolate.cpp +++ b/src/frontends/tensorflow_common/src/op/interpolate.cpp @@ -2,12 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 // +#include "openvino/op/interpolate.hpp" + #include "common_op_table.hpp" -#include "openvino/opsets/opset8.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/convert.hpp" +#include "openvino/op/divide.hpp" +#include "openvino/op/shape_of.hpp" +#include "openvino/op/slice.hpp" using namespace std; using namespace ov; -using namespace ov::opset8; +using namespace ov::op; namespace ov { namespace frontend { @@ -30,58 +36,48 @@ OutputVector translate_interpolate_op(const NodeContext& node) { " is True, the attribute align_corners must be False."); // prepare attributes for OpenVINO Interpolate operation - Interpolate::InterpolateAttrs interpolate_attrs; - interpolate_attrs.shape_calculation_mode = Interpolate::ShapeCalcMode::SIZES; + v11::Interpolate::InterpolateAttrs interpolate_attrs; + interpolate_attrs.shape_calculation_mode = v11::Interpolate::ShapeCalcMode::SIZES; if (op_type == "ResizeNearestNeighbor") { - interpolate_attrs.mode = Interpolate::InterpolateMode::NEAREST; - interpolate_attrs.nearest_mode = Interpolate::NearestMode::FLOOR; + interpolate_attrs.mode = v11::Interpolate::InterpolateMode::NEAREST; + interpolate_attrs.nearest_mode = v11::Interpolate::NearestMode::FLOOR; } else if (op_type == "ResizeBilinear") { auto input_rank = images.get_partial_shape().rank(); if (input_rank.is_static() && input_rank.get_length() == 4) { - interpolate_attrs.mode = Interpolate::InterpolateMode::LINEAR_ONNX; + interpolate_attrs.mode = v11::Interpolate::InterpolateMode::LINEAR_ONNX; } else { - interpolate_attrs.mode = Interpolate::InterpolateMode::LINEAR; + interpolate_attrs.mode = v11::Interpolate::InterpolateMode::LINEAR; } - interpolate_attrs.nearest_mode = Interpolate::NearestMode::ROUND_PREFER_FLOOR; + interpolate_attrs.nearest_mode = v11::Interpolate::NearestMode::ROUND_PREFER_FLOOR; } if (tf_align_corners) { - interpolate_attrs.coordinate_transformation_mode = Interpolate::CoordinateTransformMode::ALIGN_CORNERS; - if (interpolate_attrs.mode == Interpolate::InterpolateMode::NEAREST) { - interpolate_attrs.nearest_mode = Interpolate::NearestMode::ROUND_PREFER_CEIL; + interpolate_attrs.coordinate_transformation_mode = v11::Interpolate::CoordinateTransformMode::ALIGN_CORNERS; + if (interpolate_attrs.mode == v11::Interpolate::InterpolateMode::NEAREST) { + interpolate_attrs.nearest_mode = v11::Interpolate::NearestMode::ROUND_PREFER_CEIL; } } else if (tf_half_pixel_centers) { - if (interpolate_attrs.mode == Interpolate::InterpolateMode::NEAREST) { + if (interpolate_attrs.mode == v11::Interpolate::InterpolateMode::NEAREST) { interpolate_attrs.coordinate_transformation_mode = - Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN; + v11::Interpolate::CoordinateTransformMode::TF_HALF_PIXEL_FOR_NN; } else { - interpolate_attrs.coordinate_transformation_mode = Interpolate::CoordinateTransformMode::HALF_PIXEL; + interpolate_attrs.coordinate_transformation_mode = v11::Interpolate::CoordinateTransformMode::HALF_PIXEL; } } else { - interpolate_attrs.coordinate_transformation_mode = Interpolate::CoordinateTransformMode::ASYMMETRIC; + interpolate_attrs.coordinate_transformation_mode = v11::Interpolate::CoordinateTransformMode::ASYMMETRIC; } - // prepare scales input - auto images_shape = make_shared(images, element::i32); - auto spatial_shape = make_shared(images_shape, - make_shared(element::i64, Shape{1}, std::vector{1}), - make_shared(element::i64, Shape{1}, std::vector{3}), - make_shared(element::i64, Shape{1}, std::vector{1}), - make_shared(element::i64, Shape{1}, std::vector{0})); - auto scales = make_shared(make_shared(size, element::f32), - make_shared(spatial_shape, element::f32)); - // since Interpolate is layout agnostic // we can avoid Transpose operation by specifying axes = {1, 2} for original NHWC layout - auto axes = make_shared(element::i32, Shape{2}, std::vector({1, 2})); + auto axes = make_shared(element::i32, Shape{2}, std::vector({1, 2})); // according to the specification of ResizeBilinear, // it always returns FP32 output type so we immediately align input type for it if (op_type == "ResizeBilinear") { - images = make_shared(images, element::f32); + images = make_shared(images, element::f32); } - auto interpolate = make_shared(images, size, scales, axes, interpolate_attrs); + auto interpolate = make_shared(images, size, axes, interpolate_attrs); set_node_name(node.get_name(), interpolate); return {interpolate}; } diff --git a/src/frontends/tensorflow_common/src/op/max_pool.cpp b/src/frontends/tensorflow_common/src/op/max_pool.cpp index b2a4520249eb78..d64ac1a17fbafe 100644 --- a/src/frontends/tensorflow_common/src/op/max_pool.cpp +++ b/src/frontends/tensorflow_common/src/op/max_pool.cpp @@ -2,12 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 // +#include "openvino/op/max_pool.hpp" + #include "common_op_table.hpp" -#include "openvino/opsets/opset8.hpp" +#include "openvino/op/add.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/divide.hpp" +#include "openvino/op/gather.hpp" +#include "openvino/op/multiply.hpp" +#include "openvino/op/shape_of.hpp" +#include "openvino/op/subtract.hpp" #include "utils.hpp" using namespace std; using namespace ov; +using namespace ov::op; using namespace ov::frontend::tensorflow; namespace ov { @@ -17,21 +26,25 @@ namespace op { OutputVector translate_max_pool_util(const NodeContext& node, size_t spatial_dims_num, - const std::vector& tf_kernel_sizes, - const std::vector& tf_strides) { - default_op_checks(node, 1, {"MaxPool", "MaxPoolV2", "MaxPool3D"}); + const vector& tf_kernel_sizes, + const vector& tf_strides, + element::Type indices_element_type = element::i64, + int64_t axis = 0, + bool set_friendly_name = true, + bool with_indices = false) { + default_op_checks(node, 1, {"MaxPool", "MaxPoolV2", "MaxPool3D", "MaxPoolWithArgmax"}); TENSORFLOW_OP_VALIDATION(node, spatial_dims_num == 2 || spatial_dims_num == 3, - "Only MaxPool, MaxPoolV2 and MaxPool3D are supported."); + "Only MaxPool, MaxPoolV2, MaxPool3D and MaxPoolWithArgmax are supported."); auto input = node.get_input(0); - auto tf_padding_type = node.get_attribute("padding"); - ov::op::PadType auto_pad = convert_tf_padding(node, tf_padding_type); - auto tf_data_format = node.get_attribute("data_format", spatial_dims_num == 2 ? "NHWC" : "NDHWC"); + auto tf_padding_type = node.get_attribute("padding"); + PadType auto_pad = convert_tf_padding(node, tf_padding_type); + auto tf_data_format = node.get_attribute("data_format", spatial_dims_num == 2 ? "NHWC" : "NDHWC"); - auto tf_explicit_paddings = std::vector{}; - if (auto_pad == ov::op::PadType::EXPLICIT) { - tf_explicit_paddings = node.get_attribute>("explicit_paddings", {}); + auto tf_explicit_paddings = vector{}; + if (auto_pad == PadType::EXPLICIT) { + tf_explicit_paddings = node.get_attribute>("explicit_paddings", {}); } bool is_nhwc = true; @@ -48,40 +61,51 @@ OutputVector translate_max_pool_util(const NodeContext& node, } // prepare attributes for OpenVINO MaxPool operation - ov::Strides strides(spatial_dims_num); - ov::Strides dilations = (spatial_dims_num == 2 ? ov::Strides({1, 1}) : ov::Strides({1, 1, 1})); - ov::Shape kernel_sizes(spatial_dims_num); - ov::frontend::tensorflow::convert_nhwc_to_hw(is_nhwc, tf_strides, strides); - ov::frontend::tensorflow::convert_nhwc_to_hw(is_nhwc, tf_kernel_sizes, kernel_sizes); - - ov::CoordinateDiff pads_begin; - ov::CoordinateDiff pads_end; - if (auto_pad == ov::op::PadType::EXPLICIT) { + Strides strides(spatial_dims_num); + Strides dilations = (spatial_dims_num == 2 ? Strides({1, 1}) : Strides({1, 1, 1})); + Shape kernel_sizes(spatial_dims_num); + convert_nhwc_to_hw(is_nhwc, tf_strides, strides); + convert_nhwc_to_hw(is_nhwc, tf_kernel_sizes, kernel_sizes); + + CoordinateDiff pads_begin; + CoordinateDiff pads_end; + if (auto_pad == PadType::EXPLICIT) { fill_explicit_pads_vectors(node, is_nhwc, spatial_dims_num, tf_explicit_paddings, pads_begin, pads_end); } // prepare input to MaxPool - convert_nhwc_to_nchw(is_nhwc, input, ov::Rank(spatial_dims_num + 2)); - - auto max_pool_node = std::make_shared(input, - strides, - dilations, - ov::Shape(pads_begin.begin(), pads_begin.end()), - ov::Shape(pads_end.begin(), pads_end.end()), - kernel_sizes, - ov::op::RoundingType::FLOOR, - auto_pad); + convert_nhwc_to_nchw(is_nhwc, input, Rank(spatial_dims_num + 2)); + + auto max_pool_node = make_shared(input, + strides, + dilations, + Shape(pads_begin.begin(), pads_begin.end()), + Shape(pads_end.begin(), pads_end.end()), + kernel_sizes, + RoundingType::FLOOR, + auto_pad, + indices_element_type, + axis); auto max_pool = max_pool_node->output(0); - ov::frontend::tensorflow::convert_nchw_to_nhwc(is_nhwc, max_pool, ov::Rank(spatial_dims_num + 2)); - ov::frontend::tensorflow::set_node_name(node.get_name(), max_pool.get_node_shared_ptr()); + convert_nchw_to_nhwc(is_nhwc, max_pool, Rank(spatial_dims_num + 2)); + if (set_friendly_name) { + set_node_name(node.get_name(), max_pool.get_node_shared_ptr()); + } else { + set_out_name(node.get_name() + ":0", max_pool); + } + + if (with_indices) { + auto output_indices = max_pool_node->output(1); + return OutputVector{max_pool, output_indices}; + } return {max_pool}; } OutputVector translate_max_pool(const NodeContext& node, size_t spatial_dims_num) { // MaxPool2D and MaxPool3D have ksize and strides as attributes // retrieve attributes - auto strides = node.get_attribute>("strides"); - auto kernel_sizes = node.get_attribute>("ksize"); + auto strides = node.get_attribute>("strides"); + auto kernel_sizes = node.get_attribute>("ksize"); return translate_max_pool_util(node, spatial_dims_num, kernel_sizes, strides); } @@ -104,6 +128,81 @@ OutputVector translate_max_pool_v2(const NodeContext& node) { return translate_max_pool_util(node, 2, ksize_vector, strides_vector); } +OutputVector translate_max_pool_with_argmax(const NodeContext& node) { + // MaxPoolWithArgmax has just one input. ksize and strides are attributes + TENSORFLOW_OP_VALIDATION(node, + node.get_input_size() > 0, + "MaxPoolWithArgmax operation must have at least one input."); + auto include_batch_in_index = node.get_attribute("include_batch_in_index", false); + auto targmax = node.get_attribute("Targmax", element::i64); + auto ksize = node.get_attribute>("ksize"); + auto strides = node.get_attribute>("ksize"); + auto images = node.get_input(0); + auto node_name = node.get_name(); + + // indices from which dimension to count output indices + int64_t axis = include_batch_in_index ? 0 : 1; + + auto max_pool_with_indices = translate_max_pool_util(node, 2, ksize, strides, targmax, axis, false, true); + TENSORFLOW_OP_VALIDATION(node, + max_pool_with_indices.size() == 2, + "[TensorFlow Frontend] internal error: expect two outputs for MaxPoolWithArgmax."); + auto max_pool = max_pool_with_indices[0]; + auto output_indices_nchw = max_pool_with_indices[1]; + + auto tf_data_format = node.get_attribute("data_format", "NHWC"); + Output output_indices; + if (tf_data_format != "NHWC") { + output_indices = output_indices_nchw; + } else { + output_indices = output_indices_nchw; + // adjust output indices to have them for NHWC layout + // now it is computed for NCHW layout + // 1. compute all dimensions N, H, W, C + auto images_shape = make_shared(images, targmax); + auto const_zero = make_shared(element::i32, Shape{1}, 0); + auto const_one = make_shared(element::i32, Shape{1}, 1); + auto const_two = make_shared(element::i32, Shape{1}, 2); + auto const_three = make_shared(element::i32, Shape{1}, 3); + auto N = make_shared(images_shape, const_zero, const_zero); + auto H = make_shared(images_shape, const_one, const_zero); + auto W = make_shared(images_shape, const_two, const_zero); + auto C = make_shared(images_shape, const_three, const_zero); + + // 2. compute complex index for NCHW layout, i.e. n, h, w, c + auto HW = make_shared(H, W); + Output n; + if (include_batch_in_index) { + auto CHW = make_shared(C, HW); + n = make_shared(output_indices_nchw, CHW); + auto nCHW = make_shared(n, CHW); + output_indices_nchw = make_shared(output_indices_nchw, nCHW); + } else { + n = make_shared(targmax, Shape{1}, 0); + } + auto c = make_shared(output_indices_nchw, HW); + auto cHW = make_shared(c, HW); + output_indices_nchw = make_shared(output_indices_nchw, cHW); + auto h = make_shared(output_indices_nchw, W); + auto hW = make_shared(h, W); + auto w = make_shared(output_indices_nchw, hW); + + // transform them into flatten form for NHWC layout + auto WC = make_shared(W, C); + auto HWC = make_shared(H, WC); + output_indices = make_shared(n, HWC); + auto hWC = make_shared(h, WC); + output_indices = make_shared(output_indices, hWC); + auto wC = make_shared(w, C); + output_indices = make_shared(output_indices, wC); + output_indices = make_shared(output_indices, c); + convert_nchw_to_nhwc(true, output_indices, 4); + } + + set_out_name(node_name + ":1", output_indices); + return {max_pool, output_indices}; +} + OutputVector translate_max_pool_op(const NodeContext& node) { if (node.get_op_type() == "MaxPool") { return translate_max_pool(node, 2); @@ -111,6 +210,8 @@ OutputVector translate_max_pool_op(const NodeContext& node) { return translate_max_pool_v2(node); } else if (node.get_op_type() == "MaxPool3D") { return translate_max_pool(node, 3); + } else if (node.get_op_type() == "MaxPoolWithArgmax") { + return translate_max_pool_with_argmax(node); } else { TENSORFLOW_OP_VALIDATION(node, false, "Only MaxPool2D, MaxPoolV2 and MaxPool3D are supported."); } diff --git a/src/frontends/tensorflow_common/src/utils.cpp b/src/frontends/tensorflow_common/src/utils.cpp index 05aca5ad9ba6c6..83c2f6e8796471 100644 --- a/src/frontends/tensorflow_common/src/utils.cpp +++ b/src/frontends/tensorflow_common/src/utils.cpp @@ -42,6 +42,7 @@ PadType convert_tf_padding(const frontend::NodeContext& node, const string& tf_p "MaxPool", "MaxPoolV2", "MaxPool3D", + "MaxPoolWithArgmax", "ExtractImagePatches", "DepthwiseConv2dNative", "AvgPool", @@ -68,8 +69,8 @@ PadType convert_tf_padding(const frontend::NodeContext& node, const string& tf_p return PadType::SAME_LOWER; } } else if (op_type == "Conv2D" || op_type == "Conv3D" || op_type == "MaxPool" || op_type == "MaxPoolV2" || - op_type == "MaxPool3D" || op_type == "ExtractImagePatches" || op_type == "DepthwiseConv2dNative" || - op_type == "AvgPool" || op_type == "AvgPool3D") { + op_type == "MaxPool3D" || op_type == "MaxPoolWithArgmax" || op_type == "ExtractImagePatches" || + op_type == "DepthwiseConv2dNative" || op_type == "AvgPool" || op_type == "AvgPool3D") { if (tf_padding == "SAME") { // According to the formulas for calculating auto_pad values of the // Conv layer in the Operation specification, diff --git a/src/plugins/hetero/src/compiled_model.cpp b/src/plugins/hetero/src/compiled_model.cpp index 46e2419fd44b7a..7b8bf399286a8b 100644 --- a/src/plugins/hetero/src/compiled_model.cpp +++ b/src/plugins/hetero/src/compiled_model.cpp @@ -11,10 +11,13 @@ #include "ie_plugin_config.hpp" #include "itt.hpp" #include "openvino/op/util/op_types.hpp" +#include "openvino/pass/constant_folding.hpp" +#include "openvino/pass/manager.hpp" #include "openvino/runtime/internal_properties.hpp" #include "openvino/runtime/properties.hpp" #include "openvino/util/common_util.hpp" #include "plugin.hpp" +#include "properties.hpp" #include "xml_parse_utils.h" template @@ -55,6 +58,14 @@ ov::hetero::CompiledModel::CompiledModel(const std::shared_ptr& model if (std::getenv("OPENVINO_HETERO_VISUALIZE")) dumpDotFile = true; + // Calling of ConstantFolding in HETERO plugin is required because + // in some cases topology split is happening after constant subgraph. + // It may cause replacement of Constant by Parameter in such operations + // like Reshape/Transpose/Gather and lead to unexpected dynamism or exception + ov::pass::Manager manager; + manager.register_pass(); + manager.run_passes(model); + ov::SupportedOpsMap queryNetworkResult; auto orderedOps = model->get_ordered_ops(); @@ -664,7 +675,8 @@ ov::Any ov::hetero::CompiledModel::get_property(const std::string& name) const { std::vector ro_properties{ov::model_name, ov::optimal_number_of_infer_requests, ov::execution_devices, - ov::loaded_from_cache}; + ov::loaded_from_cache, + ov::hetero::number_of_submodels}; return ro_properties; }; const auto& to_string_vector = [](const std::vector& properties) { @@ -723,6 +735,8 @@ ov::Any ov::hetero::CompiledModel::get_property(const std::string& name) const { device_names.push_back(comp_model_desc.device); } return decltype(ov::execution_devices)::value_type{device_names}; + } else if (ov::hetero::number_of_submodels == name) { + return decltype(ov::hetero::number_of_submodels)::value_type{m_compiled_submodels.size()}; } return m_cfg.get(name); OPENVINO_SUPPRESS_DEPRECATED_END diff --git a/src/plugins/hetero/src/properties.hpp b/src/plugins/hetero/src/properties.hpp index 799d07dbe7be1a..8ecd488bff98ca 100644 --- a/src/plugins/hetero/src/properties.hpp +++ b/src/plugins/hetero/src/properties.hpp @@ -13,5 +13,10 @@ namespace hetero { */ static constexpr Property caching_device_properties{"CACHING_DEVICE_PROPERTIES"}; +/** + * @brief Read-only property showing number of compiled submodels + */ +static constexpr Property number_of_submodels{"HETERO_NUMBER_OF_SUBMODELS"}; + } // namespace hetero } // namespace ov diff --git a/src/plugins/hetero/tests/functional/compile_model_tests.cpp b/src/plugins/hetero/tests/functional/compile_model_tests.cpp index 9fb2745f5944ff..bfcd0ca1c8bb90 100644 --- a/src/plugins/hetero/tests/functional/compile_model_tests.cpp +++ b/src/plugins/hetero/tests/functional/compile_model_tests.cpp @@ -42,6 +42,20 @@ TEST_F(HeteroTests, compile_without_device_priorities_throw) { EXPECT_THROW(core.compile_model(model, "HETERO"), ov::Exception); } +TEST_F(HeteroTests, compile_dynamic_model_fail) { + // Change device priority + core.set_property("HETERO", ov::device::priorities("MOCK0,MOCK1")); + auto model = create_model_with_subtract_reshape(true); + EXPECT_THROW(core.compile_model(model, "HETERO"), ov::Exception); +} + +TEST_F(HeteroTests, compile_model_shapeof) { + // Change device priority + core.set_property("HETERO", ov::device::priorities("MOCK0,MOCK1")); + auto model = create_model_with_subtract_shapeof_reshape(); + EXPECT_NO_THROW(core.compile_model(model, "HETERO")); +} + TEST_F(HeteroTests, compile_with_device_properties) { ov::AnyMap config = {ov::device::priorities("MOCK0,MOCK1"), ov::device::properties("MOCK0", ov::num_streams(4), ov::enable_profiling(false)), diff --git a/src/plugins/hetero/tests/functional/hetero_tests.cpp b/src/plugins/hetero/tests/functional/hetero_tests.cpp index f8d1f5ea91c814..4228a5c14ce8e6 100644 --- a/src/plugins/hetero/tests/functional/hetero_tests.cpp +++ b/src/plugins/hetero/tests/functional/hetero_tests.cpp @@ -12,6 +12,8 @@ #include "openvino/core/any.hpp" #include "openvino/core/except.hpp" #include "openvino/opsets/opset11.hpp" +#include "openvino/pass/constant_folding.hpp" +#include "openvino/pass/manager.hpp" #include "openvino/pass/serialize.hpp" #include "openvino/runtime/exec_model_info.hpp" #include "openvino/runtime/internal_properties.hpp" @@ -22,6 +24,7 @@ #include "openvino/runtime/properties.hpp" #include "openvino/util/file_util.hpp" #include "openvino/util/shared_object.hpp" +#include "transformations/init_node_info.hpp" #include "transformations/rt_info/fused_names_attribute.hpp" namespace { @@ -67,8 +70,9 @@ ov::Tensor ov::hetero::tests::HeteroTests::create_and_fill_tensor(const ov::elem OPENVINO_THROW("Cannot generate tensor. Unsupported element type."); } -std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract() { - auto param = std::make_shared(ov::element::i64, ov::Shape{1, 3, 2, 2}); +std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract(bool dynamic) { + int64_t bs = dynamic ? -1 : 1; + auto param = std::make_shared(ov::element::i64, ov::PartialShape{bs, 3, 2, 2}); param->set_friendly_name("input"); auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); const_value->set_friendly_name("const_val"); @@ -81,8 +85,9 @@ std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_sub return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); } -std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract_reshape() { - auto param = std::make_shared(ov::element::i64, ov::Shape{1, 3, 2, 2}); +std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract_reshape(bool dynamic) { + int64_t bs = dynamic ? -1 : 1; + auto param = std::make_shared(ov::element::i64, ov::PartialShape{bs, 3, 2, 2}); param->set_friendly_name("input"); auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); const_value->set_friendly_name("const_val"); @@ -99,8 +104,9 @@ std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_sub return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); } -std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract_reshape_relu() { - auto param = std::make_shared(ov::element::i64, ov::Shape{1, 3, 2, 2}); +std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract_reshape_relu(bool dynamic) { + int64_t bs = dynamic ? -1 : 1; + auto param = std::make_shared(ov::element::i64, ov::PartialShape{bs, 3, 2, 2}); param->set_friendly_name("input"); auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); const_value->set_friendly_name("const_val"); @@ -119,8 +125,9 @@ std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_sub return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); } -std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_reshape() { - auto param = std::make_shared(ov::element::i64, ov::Shape{1, 3, 2, 2}); +std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_reshape(bool dynamic) { + int64_t bs = dynamic ? -1 : 1; + auto param = std::make_shared(ov::element::i64, ov::PartialShape{bs, 3, 2, 2}); param->set_friendly_name("input"); auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); const_value->set_friendly_name("const_val"); @@ -135,6 +142,27 @@ std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_res return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); } +std::shared_ptr ov::hetero::tests::HeteroTests::create_model_with_subtract_shapeof_reshape(bool dynamic) { + int64_t bs = dynamic ? -1 : 1; + auto param = std::make_shared(ov::element::i64, ov::PartialShape{bs, 3, 2, 2}); + param->set_friendly_name("input"); + auto reshape_val0 = ov::opset11::Constant::create(ov::element::i64, ov::Shape{2}, {bs, 12}); + reshape_val0->set_friendly_name("reshape_val0"); + auto reshape0 = std::make_shared(param, reshape_val0, true); + reshape0->set_friendly_name("reshape0"); + auto const_value = ov::opset11::Constant::create(ov::element::i64, ov::Shape{1, 1}, {1}); + const_value->set_friendly_name("const_val"); + auto subtract = std::make_shared(reshape0, const_value); + subtract->set_friendly_name("sub"); + auto shape_of = std::make_shared(param); + shape_of->set_friendly_name("shape_of"); + auto reshape1 = std::make_shared(subtract, shape_of, true); + reshape1->set_friendly_name("reshape1"); + auto result = std::make_shared(reshape1); + result->set_friendly_name("res"); + return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); +} + // Mock plugins class MockCompiledModel : public ov::ICompiledModel { @@ -386,8 +414,11 @@ class MockCustomRemoteContext : public ov::IRemoteContext { class MockPluginBase : public ov::IPlugin { public: - MockPluginBase(const std::string& name, const std::unordered_set& supported_ops) - : m_supported_ops(supported_ops) { + MockPluginBase(const std::string& name, + const std::unordered_set& supported_ops, + bool dynamism_supported = false) + : m_supported_ops(supported_ops), + m_dynamism_supported(dynamism_supported) { set_device_name(name); } @@ -501,10 +532,24 @@ class MockPluginBase : public ov::IPlugin { auto device_id = properties.count(ov::device::id.name()) ? properties.at(ov::device::id.name()).as() : m_default_device_id; - for (const auto& op : model->get_ordered_ops()) { - if (m_supported_ops.find(op->get_type_info().name) == m_supported_ops.end()) - continue; - res[op->get_friendly_name()] = get_device_name() + "." + device_id; + + auto supported = ov::get_supported_nodes( + model, + [&](std::shared_ptr& model) { + ov::pass::Manager manager; + manager.register_pass(); + manager.register_pass(); + manager.run_passes(model); + }, + [&](const std::shared_ptr& op) { + if (op->is_dynamic() && !m_dynamism_supported) + return false; + if (m_supported_ops.find(op->get_type_info().name) == m_supported_ops.end()) + return false; + return true; + }); + for (auto&& op_name : supported) { + res.emplace(op_name, get_device_name() + "." + device_id); } return res; } @@ -512,6 +557,7 @@ class MockPluginBase : public ov::IPlugin { protected: std::string m_default_device_id = "0"; std::unordered_set m_supported_ops; + bool m_dynamism_supported = false; bool m_profiling = false; bool m_loaded_from_cache{false}; }; @@ -519,7 +565,7 @@ class MockPluginBase : public ov::IPlugin { class MockPluginReshape : public MockPluginBase { public: MockPluginReshape(const std::string& name) - : MockPluginBase(name, {"Parameter", "Result", "Add", "Constant", "Reshape"}) {} + : MockPluginBase(name, {"Parameter", "Result", "Add", "Constant", "Reshape"}, true) {} const ov::Version& get_const_version() override { static const ov::Version version = {CI_BUILD_NUMBER, "openvino_mock_reshape_plugin"}; diff --git a/src/plugins/hetero/tests/functional/hetero_tests.hpp b/src/plugins/hetero/tests/functional/hetero_tests.hpp index b2af29f19472a5..7b6e5f85fad0ee 100644 --- a/src/plugins/hetero/tests/functional/hetero_tests.hpp +++ b/src/plugins/hetero/tests/functional/hetero_tests.hpp @@ -20,10 +20,11 @@ class HeteroTests : public ::testing::Test { void SetUp() override; - std::shared_ptr create_model_with_subtract(); - std::shared_ptr create_model_with_subtract_reshape(); - std::shared_ptr create_model_with_subtract_reshape_relu(); - std::shared_ptr create_model_with_reshape(); + std::shared_ptr create_model_with_subtract(bool dynamic = false); + std::shared_ptr create_model_with_subtract_reshape(bool dynamic = false); + std::shared_ptr create_model_with_subtract_reshape_relu(bool dynamic = false); + std::shared_ptr create_model_with_reshape(bool dynamic = false); + std::shared_ptr create_model_with_subtract_shapeof_reshape(bool dynamic = false); ov::Tensor create_and_fill_tensor(const ov::element::Type& type, const ov::Shape& shape); private: diff --git a/src/plugins/hetero/tests/functional/query_model_tests.cpp b/src/plugins/hetero/tests/functional/query_model_tests.cpp index 9df8c2b110abcf..4563cdd726b7f0 100644 --- a/src/plugins/hetero/tests/functional/query_model_tests.cpp +++ b/src/plugins/hetero/tests/functional/query_model_tests.cpp @@ -37,8 +37,14 @@ TEST_F(HeteroTests, query_model_on_mock1) { EXPECT_EQ(op.second, dev_name); names.erase(op.first); } - EXPECT_EQ(1, names.size()); - EXPECT_EQ("reshape", *names.begin()); + const std::vector unmarked_names = {"reshape_val", "reshape", "res"}; + EXPECT_EQ(unmarked_names.size(), names.size()); + for (auto& name : unmarked_names) { + auto it = names.find(name); + if (it != names.end()) + names.erase(it); + } + EXPECT_EQ(0, names.size()); } TEST_F(HeteroTests, query_model_on_mixed) { @@ -65,3 +71,30 @@ TEST_F(HeteroTests, query_model_on_mixed) { } EXPECT_EQ(0, names.size()); } + +TEST_F(HeteroTests, query_dynamic_model_on_mixed) { + const std::string dev_name0 = "MOCK0.3"; + const std::string dev_name1 = "MOCK1.2"; + ov::AnyMap config = {ov::device::priorities(dev_name0 + "," + dev_name1)}; + const auto model = create_model_with_subtract_reshape(true); + std::set supported_ops_mock0; + for (auto& op : core.query_model(model, dev_name0)) { + if (op.second == dev_name0) + supported_ops_mock0.insert(op.first); + } + const auto supported_ops = core.query_model(model, "HETERO", config); + std::unordered_set names; + for (const auto& op : model->get_ops()) { + names.insert(op->get_friendly_name()); + } + for (const auto& op : supported_ops) { + if (supported_ops_mock0.count(op.first)) + EXPECT_EQ(op.second, dev_name0); + else + EXPECT_EQ(op.second, dev_name1); + names.erase(op.first); + } + EXPECT_EQ(1, names.size()); + // fallback plugin doesn't support dynamism + ASSERT_TRUE(names.count("sub")); +} 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 e321cec288acf2..b501519c15bbce 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 @@ -22,7 +22,7 @@ void RegisterTestCustomQueries(void) { std::map& extTestQueries = *::PostgreSQLLink::get_ext_test_queries(); std::map& extTestNames = *::PostgreSQLLink::get_ext_test_names(); - std::string testName("checkPluginImplementation"); + std::string testName("checkPluginImplementationCompileModel"); extTestQueries[testName + "_ON_START"] = "OpImplCheck_CheckPluginImpl($__test_id, '$opName', '$opSet', " "'$targetDevice', '$targetDeviceArch', '$targetDeviceName', '$config', $__is_temp)"; diff --git a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir_tests.cpp b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir_tests.cpp index 062861c9a35e74..8a0092bc0204e5 100644 --- a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir_tests.cpp +++ b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/read_ir/read_ir_tests.cpp @@ -17,15 +17,16 @@ using namespace ov::test::subgraph; namespace { -TEST_P(ReadIRTest, ReadIR) { +TEST_P(ReadIRTest, Inference) { run(); } -TEST_P(ReadIRTest, QueryModel) { +// temporarty disable to provide correct numbers for release +TEST_P(ReadIRTest, DISABLED_QueryModel) { query_model(); } -TEST_P(ReadIRTest, ImportExport) { +TEST_P(ReadIRTest, DISABLED_ImportExport) { import_export(); } diff --git a/src/tests/test_utils/functional_test_utils/layer_tests_summary/merge_xmls.py b/src/tests/test_utils/functional_test_utils/layer_tests_summary/merge_xmls.py index 1a7a32b114b28f..c75a1e5607dbe8 100644 --- a/src/tests/test_utils/functional_test_utils/layer_tests_summary/merge_xmls.py +++ b/src/tests/test_utils/functional_test_utils/layer_tests_summary/merge_xmls.py @@ -67,7 +67,7 @@ def aggregate_test_results(aggregated_results: SubElement, xml_reports: list, continue xml_results = xml_root.find("results") xml_timestamp = xml_root.get("timestamp") - if aggregated_timestamp is None or xml_timestamp < aggregated_timestamp: + if aggregated_timestamp is None or xml_timestamp > aggregated_timestamp: aggregated_timestamp = xml_timestamp for xml_device_entry in xml_results: if merge_device_suffix and "." in xml_device_entry.tag: diff --git a/src/tests/test_utils/functional_test_utils/layer_tests_summary/rename_conformance_ir.py b/src/tests/test_utils/functional_test_utils/layer_tests_summary/rename_conformance_ir.py index 9347617afee3ae..0cf63c5ce1e216 100644 --- a/src/tests/test_utils/functional_test_utils/layer_tests_summary/rename_conformance_ir.py +++ b/src/tests/test_utils/functional_test_utils/layer_tests_summary/rename_conformance_ir.py @@ -24,7 +24,6 @@ if PY_OPENVINO in os.listdir(ov_bin_path): env = os.environ py_ov = os.path.join(ov_bin_path, PY_OPENVINO) - py_ov = os.path.join(py_ov, find_latest_dir(py_ov)) env = set_env_variable(env, "PYTHONPATH", py_ov) env = set_env_variable(env, LD_LIB_PATH_NAME, ov_bin_path) diff --git a/src/tests/test_utils/functional_test_utils/layer_tests_summary/template/report_template.html b/src/tests/test_utils/functional_test_utils/layer_tests_summary/template/report_template.html index 80efaabbdb250f..e440458b2704ed 100644 --- a/src/tests/test_utils/functional_test_utils/layer_tests_summary/template/report_template.html +++ b/src/tests/test_utils/functional_test_utils/layer_tests_summary/template/report_template.html @@ -32,7 +32,7 @@

Operations coverage summary: Tag: {{report_tag}} | Version: {{report_version Passrates are based on relative weights each subgraphs! You can check absolute value in `General passrate` row!
- Relative Passrate could be from 0 to 200% now! Relative weight of operation is calculated once for current set of models, but there are more then one tests per model. + Relative Passrate could be from 0 to 100% (Inference only)! Relative weight of operation is calculated once for current set of models, but there are more then one tests per model.
Status: diff --git a/src/tests/test_utils/functional_test_utils/layer_tests_summary/utils/constants.py b/src/tests/test_utils/functional_test_utils/layer_tests_summary/utils/constants.py index a5cef0ce3ebf9f..825e599d52ea07 100644 --- a/src/tests/test_utils/functional_test_utils/layer_tests_summary/utils/constants.py +++ b/src/tests/test_utils/functional_test_utils/layer_tests_summary/utils/constants.py @@ -28,7 +28,7 @@ LD_LIB_PATH_NAME = "PATH" if IS_WIN else "LD_LIBRARY_PATH" OPENVINO_NAME = 'openvino' -PY_OPENVINO = "python_api" +PY_OPENVINO = "python" DEBUG_DIR = "Debug" RELEASE_DIR = "Release" diff --git a/tests/layer_tests/mo_python_api_tests/test_mo_convert_pytorch.py b/tests/layer_tests/mo_python_api_tests/test_mo_convert_pytorch.py index 5e6cdc765c9db0..ae48f1ce1ae7f2 100644 --- a/tests/layer_tests/mo_python_api_tests/test_mo_convert_pytorch.py +++ b/tests/layer_tests/mo_python_api_tests/test_mo_convert_pytorch.py @@ -74,6 +74,7 @@ def __init__(self): ) def forward(self, x, y=None, z=None): + logits = None if y is None: logits = self.linear_relu_stack(x + z) if z is None: @@ -87,7 +88,7 @@ def make_ref_pt_model_one_input(shape, dtype=np.float32): shape = PartialShape(shape) param1 = ov.opset8.parameter(shape, name="input_0", dtype=dtype) relu = ov.opset8.relu(param1) - if dtype != np.float32: + if dtype not in [np.float32, Type.dynamic]: relu = ov.opset8.convert(relu, np.float32) sigm = ov.opset8.sigmoid(relu) @@ -106,9 +107,13 @@ def make_ref_pt_model_two_inputs(shape, dtype=np.float32): shape = PartialShape(shape) param1 = ov.opset8.parameter(shape, name="input_0", dtype=dtype) param2 = ov.opset8.parameter(shape, name="input_1", dtype=dtype) - mul = ov.opset8.multiply(param1, param2) + if dtype == Type.dynamic: + cl = ov.opset8.convert_like(param2, param1) + mul = ov.opset8.multiply(param1, cl) + else: + mul = ov.opset8.multiply(param1, param2) relu = ov.opset8.relu(mul) - if dtype != np.float32: + if dtype not in [np.float32, Type.dynamic]: relu = ov.opset8.convert(relu, np.float32) sigm = ov.opset8.sigmoid(relu) @@ -277,7 +282,7 @@ def scripted_fn(x: torch.Tensor, y: torch.Tensor): return torch.sigmoid(torch.relu(x * y)) inp_shape = PartialShape([Dimension(1, -1), Dimension(-1, 5), 10]) - ref_model = make_ref_pt_model_two_inputs(inp_shape) + ref_model = make_ref_pt_model_two_inputs(inp_shape, dtype=Type.dynamic) return scripted_fn, ref_model, {'input': [(inp_shape), (inp_shape)]} @@ -292,7 +297,7 @@ def create_pytorch_nn_module_layout_list(tmp_dir): ref_model.inputs[1].node.layout = Layout('nhwc') return pt_model, ref_model, { - 'input_shape': [shape, shape], 'layout': ['nchw', Layout('nhwc')], 'use_convert_model_from_mo': True + 'input': [(shape, np.float32), (shape, np.float32)], 'layout': ['nchw', Layout('nhwc')], 'use_convert_model_from_mo': True } @@ -307,30 +312,7 @@ def create_pytorch_nn_module_layout_list_case2(tmp_dir): ref_model.inputs[1].node.layout = Layout('nhwc') return pt_model, ref_model, { - 'input_shape': [shape, shape], 'layout': ('nchw', Layout('nhwc')), 'use_convert_model_from_mo': True} - - -def create_pytorch_nn_module_mean_list(tmp_dir): - pt_model = make_pt_model_two_inputs() - shape = [1, 10, 10, 3] - - shape = PartialShape(shape) - param1 = ov.opset8.parameter(shape) - param2 = ov.opset8.parameter(shape) - const1 = ov.opset8.constant([[[[-0.0, -0.0, -0.0]]]], dtype=np.float32) - const2 = ov.opset8.constant([[[[-0.0, -0.0, -0.0]]]], dtype=np.float32) - add1 = ov.opset8.add(param1, const1) - add2 = ov.opset8.add(param2, const2) - mul = ov.opset8.multiply(add1, add2) - relu = ov.opset8.relu(mul) - sigm = ov.opset8.sigmoid(relu) - - parameter_list = [param1, param2] - ref_model = Model([sigm], parameter_list, "test") - - return pt_model, ref_model, { - 'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], 'compress_to_fp16': False, - 'use_convert_model_from_mo': True} + 'input': [(shape, np.float32), (shape, np.float32)], 'layout': ('nchw', Layout('nhwc')), 'use_convert_model_from_mo': True} def create_pytorch_nn_module_mean_list_compression_disabled(tmp_dir): @@ -351,7 +333,7 @@ def create_pytorch_nn_module_mean_list_compression_disabled(tmp_dir): parameter_list = [param1, param2] ref_model = Model([sigm], parameter_list, "test") - return pt_model, ref_model, {'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], + return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], 'mean_values': [[0, 0, 0], [0, 0, 0]], 'compress_to_fp16': False, 'use_convert_model_from_mo': True} @@ -375,7 +357,7 @@ def create_pytorch_nn_module_mean_list_compression_default(tmp_dir): parameter_list = [param1, param2] ref_model = Model([sigm], parameter_list, "test") - return pt_model, ref_model, {'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], + return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], 'mean_values': [[0, 0, 0], [0, 0, 0]], 'use_convert_model_from_mo': True} @@ -403,32 +385,10 @@ def create_pytorch_nn_module_mean_list_compression_enabled(tmp_dir): ref_model = Model([sigm], parameter_list, "test") return pt_model, ref_model, { - 'input_shape': [shape, shape], 'mean_values': [[0, 0, 0], [0, 0, 0]], + 'input': [(shape, np.float32), (shape, np.float32)], 'mean_values': [[0, 0, 0], [0, 0, 0]], 'compress_to_fp16': True, 'use_convert_model_from_mo': True} -def create_pytorch_nn_module_scale_list(tmp_dir): - pt_model = make_pt_model_two_inputs() - shape = [1, 10, 10, 3] - - shape = PartialShape(shape) - param1 = ov.opset8.parameter(shape) - param2 = ov.opset8.parameter(shape) - const1 = ov.opset8.constant([[[[1, 1, 1]]]], dtype=np.float32) - const2 = ov.opset8.constant([[[[1, 1, 1]]]], dtype=np.float32) - sub1 = ov.opset8.multiply(param1, const1) - sub2 = ov.opset8.multiply(param2, const2) - mul = ov.opset8.multiply(sub1, sub2) - relu = ov.opset8.relu(mul) - sigm = ov.opset8.sigmoid(relu) - - parameter_list = [param1, param2] - ref_model = Model([sigm], parameter_list, "test") - - return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], 'compress_to_fp16': False, - 'use_convert_model_from_mo': True} - - def create_pytorch_nn_module_scale_list_compression_disabled(tmp_dir): pt_model = make_pt_model_two_inputs() shape = [1, 10, 10, 3] @@ -447,7 +407,8 @@ def create_pytorch_nn_module_scale_list_compression_disabled(tmp_dir): parameter_list = [param1, param2] ref_model = Model([sigm], parameter_list, "test") - return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], + return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], + 'scale_values': [[1, 1, 1], [1, 1, 1]], 'compress_to_fp16': False, 'use_convert_model_from_mo': True} @@ -471,7 +432,8 @@ def create_pytorch_nn_module_scale_list_compression_default(tmp_dir): parameter_list = [param1, param2] ref_model = Model([sigm], parameter_list, "test") - return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], + return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], + 'scale_values': [[1, 1, 1], [1, 1, 1]], 'use_convert_model_from_mo': True} @@ -497,13 +459,14 @@ def create_pytorch_nn_module_scale_list_compression_enabled(tmp_dir): parameter_list = [param1, param2] ref_model = Model([sigm], parameter_list, "test") - return pt_model, ref_model, {'input_shape': [shape, shape], 'scale_values': [[1, 1, 1], [1, 1, 1]], + return pt_model, ref_model, {'input': [(shape, np.float32), (shape, np.float32)], + 'scale_values': [[1, 1, 1], [1, 1, 1]], 'compress_to_fp16': True, 'use_convert_model_from_mo': True} def create_pytorch_nn_module_shapes_list_static(tmp_dir): pt_model = make_pt_model_two_inputs() - ref_model = make_ref_pt_model_two_inputs([1, 3, 20, 20]) + ref_model = make_ref_pt_model_two_inputs([1, 3, 20, 20], dtype=Type.dynamic) return pt_model, ref_model, {'input': [[1, 3, 20, 20], [1, 3, 20, 20]]} @@ -521,10 +484,11 @@ def create_pytorch_nn_module_shapes_list_dynamic(tmp_dir): [-1, 3, 20, Dimension(-1, 20)]] param1 = ov.opset8.parameter(PartialShape( - inp_shapes[0]), name="x", dtype=np.float32) + inp_shapes[0]), name="x", dtype=Type.dynamic) param2 = ov.opset8.parameter(PartialShape( - inp_shapes[1]), name="y", dtype=np.float32) - mul = ov.opset8.multiply(param1, param2) + inp_shapes[1]), name="y", dtype=Type.dynamic) + cl = ov.opset8.convert_like(param2, param1) + mul = ov.opset8.multiply(param1, cl) relu = ov.opset8.relu(mul) sigm = ov.opset8.sigmoid(relu) @@ -548,13 +512,13 @@ def create_pytorch_nn_module_shapes_list_dynamic_via_input(tmp_dir): parameter_list = [param1, param2] ref_model = Model([sigm], parameter_list, "test") - return pt_model, ref_model, {'input': [(inp_shapes[0],), (inp_shapes[1],)]} + return pt_model, ref_model, {'input': [(inp_shapes[0], Type.f32), (inp_shapes[1], Type.f32)]} def create_pytorch_nn_module_shapes_list_dynamic_single_input(tmp_dir): pt_model = make_pt_model_one_input() inp_shapes = [[Dimension(-1), 3, 20, Dimension(20, -1)]] - ref_model = make_ref_pt_model_one_input(inp_shapes[0]) + ref_model = make_ref_pt_model_one_input(inp_shapes[0], dtype=Type.dynamic) return pt_model, ref_model, {'input': inp_shapes} @@ -568,7 +532,7 @@ def create_pytorch_nn_module_shapes_list_dynamic_single_input_via_input(tmp_dir) def create_pytorch_nn_module_shapes_list_static_single_input(tmp_dir): pt_model = make_pt_model_one_input() inp_shapes = [[1, 3, 20, 20]] - ref_model = make_ref_pt_model_one_input(inp_shapes[0]) + ref_model = make_ref_pt_model_one_input(inp_shapes[0], dtype=Type.dynamic) return pt_model, ref_model, {'input': inp_shapes} @@ -735,20 +699,6 @@ def create_pytorch_module_with_optional_inputs_case3(tmp_dir): return net, ref_model, {"example_input": example_input, "input": [[3, 3, 3, 3], [3, 3, 3, 3]]} -def create_pytorch_module_with_optional_inputs_case4(tmp_dir): - net = make_pt_model_with_optional_input() - ref_model = make_ref_pt_model_with_optional_inputs( - [3, 3, 3, 3], z_exist=True) - return net, ref_model, {"input": [("x", [3, 3, 3, 3]), ("z", [3, 3, 3, 3])]} - - -def create_pytorch_module_with_optional_inputs_case5(tmp_dir): - net = make_pt_model_with_optional_input() - ref_model = make_ref_pt_model_with_optional_inputs( - [1, 3, -1, -1], z_exist=True) - return net, ref_model, {"input": [("x",[1, 3, -1, -1]), ("z", [1, 3, -1, -1])]} - - def create_pytorch_module_with_compressed_int8_constant_compress_to_fp16_default(tmp_dir): import torch import torch.nn.functional as F @@ -1013,11 +963,9 @@ class TestMoConvertPyTorch(CommonMOConvertTest): create_pytorch_jit_script_function, create_pytorch_nn_module_layout_list, create_pytorch_nn_module_layout_list_case2, - create_pytorch_nn_module_mean_list, create_pytorch_nn_module_mean_list_compression_default, create_pytorch_nn_module_mean_list_compression_disabled, create_pytorch_nn_module_mean_list_compression_enabled, - create_pytorch_nn_module_scale_list, create_pytorch_nn_module_scale_list_compression_default, create_pytorch_nn_module_scale_list_compression_disabled, create_pytorch_nn_module_scale_list_compression_enabled, @@ -1039,8 +987,6 @@ class TestMoConvertPyTorch(CommonMOConvertTest): create_pytorch_module_with_optional_inputs_case1, create_pytorch_module_with_optional_inputs_case2, create_pytorch_module_with_optional_inputs_case3, - create_pytorch_module_with_optional_inputs_case4, - create_pytorch_module_with_optional_inputs_case5, create_pytorch_nn_module_with_scalar_input, create_pytorch_module_with_compressed_int8_constant, create_pytorch_module_with_compressed_int8_constant_compress_to_fp16_default, diff --git a/tests/layer_tests/tensorflow_tests/test_tf_MaxPoolWithArgmax.py b/tests/layer_tests/tensorflow_tests/test_tf_MaxPoolWithArgmax.py new file mode 100644 index 00000000000000..bb39a94594b91a --- /dev/null +++ b/tests/layer_tests/tensorflow_tests/test_tf_MaxPoolWithArgmax.py @@ -0,0 +1,75 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import numpy as np +import pytest +import tensorflow as tf +from common.tf_layer_test_class import CommonTFLayerTest + + +class TestMaxPoolWithArgmax(CommonTFLayerTest): + def _prepare_input(self, inputs_info): + assert 'input' in inputs_info + input_shape = inputs_info['input'] + inputs_data = {} + inputs_data['input'] = np.random.randint(-5, 5, input_shape).astype(self.input_type) + return inputs_data + + def create_max_pool_with_argmax_net(self, input_shape, ksize, strides, input_type, padding, targmax, + include_batch_in_index, with_second_output): + self.input_type = input_type + tf.compat.v1.reset_default_graph() + # Create the graph and model + with tf.compat.v1.Session() as sess: + input = tf.compat.v1.placeholder(input_type, input_shape, 'input') + max_pool_with_argmax = tf.raw_ops.MaxPoolWithArgmax(input=input, ksize=ksize, strides=strides, + padding=padding, Targmax=targmax, + include_batch_in_index=include_batch_in_index + ) + tf.identity(max_pool_with_argmax[0], name='max_pool') + if with_second_output: + tf.identity(max_pool_with_argmax[1], name='output_indices') + tf.compat.v1.global_variables_initializer() + tf_net = sess.graph_def + + return tf_net, None + + test_data_basic = [ + dict(input_shape=[1, 25, 24, 3], + ksize=[1, 1, 1, 1], strides=[1, 1, 1, 1]), + dict(input_shape=[1, 10, 20, 3], + ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1]), + ] + + @pytest.mark.parametrize("params", test_data_basic) + @pytest.mark.parametrize("input_type", [ + np.float32, np.int32 + ]) + @pytest.mark.parametrize("padding", [ + 'VALID', 'SAME' + ]) + @pytest.mark.parametrize("targmax", [ + tf.int32, tf.int64 + ]) + @pytest.mark.parametrize("include_batch_in_index", [ + True, False + ]) + @pytest.mark.parametrize("with_second_output", [ + pytest.param( + True, + marks=pytest.mark.skip(reason="117415: TransposeSinking crash") + ), + False + ]) + @pytest.mark.precommit_tf_fe + @pytest.mark.nightly + def test_max_pool_with_argmax_basic(self, params, input_type, padding, targmax, + include_batch_in_index, with_second_output, + ie_device, precision, ir_version, temp_dir, + use_new_frontend, use_old_api): + self._test( + *self.create_max_pool_with_argmax_net(**params, input_type=input_type, padding=padding, targmax=targmax, + include_batch_in_index=include_batch_in_index, + with_second_output=with_second_output), + ie_device, precision, ir_version, temp_dir=temp_dir, + use_new_frontend=use_new_frontend, use_old_api=use_old_api) diff --git a/thirdparty/open_model_zoo b/thirdparty/open_model_zoo index 4035972e8a3dbb..7353ea15fc0ba5 160000 --- a/thirdparty/open_model_zoo +++ b/thirdparty/open_model_zoo @@ -1 +1 @@ -Subproject commit 4035972e8a3dbbac90d22df5cf741f6cbbca1ea2 +Subproject commit 7353ea15fc0ba57d4bcdd7aaf9c4cde454ca447b diff --git a/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py b/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py index b42fa131225077..7cb46d92300640 100644 --- a/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py +++ b/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py @@ -30,7 +30,7 @@ def get_pytorch_decoder(model, input_shape, example_inputs, args): "NNCF models produced by nncf<2.6 are not supported directly. Please export to ONNX first.") except: pass - inputs = prepare_torch_inputs(example_inputs, input_shape, args.get("input"), allow_none=True) + inputs = prepare_torch_inputs(example_inputs) decoder = TorchScriptPythonDecoder(model, example_input=inputs) args['input_model'] = decoder args["framework"] = "pytorch" @@ -151,36 +151,7 @@ def to_torch_tensor(tensor): "Got {}".format(type(tensor))) -def get_torch_dtype(dtype): - import torch - ov_str_to_torch = { - "boolean": torch.bool, - "f16": torch.float16, - "f32": torch.float32, - "f64": torch.float64, - "i8": torch.int8, - "i16": torch.int16, - "i32": torch.int32, - "i64": torch.int64, - "u8": torch.uint8, - } - if dtype is None: - return torch.float - if isinstance(dtype, torch.dtype): - return dtype - if isinstance(dtype, (type, np.dtype)): - dtype = get_element_type_str(dtype) - if isinstance(dtype, Type): - dtype = dtype.get_type_name() - if isinstance(dtype, str): - str_dtype = ov_str_to_torch.get(dtype) - if str_dtype is None: - raise Error(f"Unexpected data type '{dtype}' for input") - return str_dtype - raise Error(f"Unexpected data type for input. Supported torch.dtype, numpy.dtype, ov.Type and str. Got {type(dtype)}") - - -def prepare_torch_inputs(example_inputs, input_shape, input_info=None, allow_none=False): +def prepare_torch_inputs(example_inputs): import torch inputs = None if example_inputs is not None: @@ -201,29 +172,7 @@ def prepare_torch_inputs(example_inputs, input_shape, input_info=None, allow_non inputs[name] = to_torch_tensor(tensor) else: inputs = to_torch_tensor(inputs) - elif input_info is not None or input_shape is not None: - input_info = input_to_input_cut_info(input_info) or [] - input_shape_to_input_cut_info(input_shape, input_info) - inputs = [] - inputs_with_names = {} - for inp in input_info: - shape = inp.shape - if shape is None: - if not allow_none: - raise Error("Please provide input_shape or example_input for all inputs converting PyTorch model.") - inputs = None - break - dtype = get_torch_dtype(inp.type) - static_shape = get_static_shape(shape, dynamic_value=1) - input_tensor = torch.zeros(static_shape, dtype=dtype) # pylint: disable=no-member - if inp.name is not None: - inputs_with_names[inp.name] = input_tensor - inputs.append(input_tensor) - if isinstance(inputs, list): - inputs = tuple(inputs) - if inputs is not None and len(inputs) == len(inputs_with_names): - inputs = inputs_with_names else: - if not allow_none: - raise Error("Please provide input_shape or example_input for converting PyTorch model.") + # No example_input were provided, decoder will use scripting + return None return inputs diff --git a/tools/ovc/openvino/tools/ovc/moc_frontend/pytorch_frontend_utils.py b/tools/ovc/openvino/tools/ovc/moc_frontend/pytorch_frontend_utils.py index 3bb6c928f3a10f..89c5ce11ae520b 100644 --- a/tools/ovc/openvino/tools/ovc/moc_frontend/pytorch_frontend_utils.py +++ b/tools/ovc/openvino/tools/ovc/moc_frontend/pytorch_frontend_utils.py @@ -30,7 +30,7 @@ def get_pytorch_decoder(model, example_inputs, args): "NNCF models produced by nncf<2.6 are not supported directly. Please export to ONNX first.") except: pass - inputs = prepare_torch_inputs(example_inputs, args.get("input"), allow_none=True) + inputs = prepare_torch_inputs(example_inputs) decoder = TorchScriptPythonDecoder(model, example_input=inputs) args['input_model'] = decoder args["example_input"] = inputs @@ -150,36 +150,7 @@ def to_torch_tensor(tensor): "Got {}".format(type(tensor))) -def get_torch_dtype(dtype): - import torch - ov_str_to_torch = { - "boolean": torch.bool, - "f16": torch.float16, - "f32": torch.float32, - "f64": torch.float64, - "i8": torch.int8, - "i16": torch.int16, - "i32": torch.int32, - "i64": torch.int64, - "u8": torch.uint8, - } - if dtype is None: - return torch.float - if isinstance(dtype, torch.dtype): - return dtype - if isinstance(dtype, (type, np.dtype)): - dtype = get_element_type_str(dtype) - if isinstance(dtype, Type): - dtype = dtype.get_type_name() - if isinstance(dtype, str): - str_dtype = ov_str_to_torch.get(dtype) - if str_dtype is None: - raise Error(f"Unexpected data type '{dtype}' for input") - return str_dtype - raise Error(f"Unexpected data type for input. Supported torch.dtype, numpy.dtype, ov.Type and str. Got {type(dtype)}") - - -def prepare_torch_inputs(example_inputs, input_info=None, allow_none=False): +def prepare_torch_inputs(example_inputs): import torch inputs = None if example_inputs is not None: @@ -200,28 +171,7 @@ def prepare_torch_inputs(example_inputs, input_info=None, allow_none=False): inputs[name] = to_torch_tensor(tensor) else: inputs = to_torch_tensor(inputs) - elif input_info is not None: - input_info = input_to_input_cut_info(input_info) or [] - inputs = [] - inputs_with_names = {} - for inp in input_info: - shape = inp.shape - if shape is None: - if not allow_none: - raise Error("Please provide shape in `input` or `example_input` for all inputs converting PyTorch model.") - inputs = None - break - dtype = get_torch_dtype(inp.type) - static_shape = get_static_shape(shape, dynamic_value=1) - input_tensor = torch.zeros(static_shape, dtype=dtype) # pylint: disable=no-member - if inp.name is not None: - inputs_with_names[inp.name] = input_tensor - inputs.append(input_tensor) - if isinstance(inputs, list): - inputs = tuple(inputs) - if inputs is not None and len(inputs) == len(inputs_with_names): - inputs = inputs_with_names else: - if not allow_none: - raise Error("Please provide shapes `input` or `example_input` for converting PyTorch model.") + # No example_input were provided, decoder will use scripting + return None return inputs