diff --git a/.ci/azure/linux_arm64.yml b/.ci/azure/linux_arm64.yml index 62840d46200de5..11f9e545f4bdd8 100644 --- a/.ci/azure/linux_arm64.yml +++ b/.ci/azure/linux_arm64.yml @@ -191,10 +191,10 @@ jobs: -DENABLE_INTEL_GPU=ON \ -DENABLE_PYTHON=ON \ -DENABLE_WHEEL=ON \ - -DPYBIND11_PYTHONLIBS_OVERWRITE=OFF \ -DPYTHON_MODULE_EXTENSION=$(aarch64-linux-gnu-python3-config --extension-suffix) \ - -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libc-2.31.so \ - -DPYTHON_INCLUDE_DIR=$(Agent.ToolsDirectory)/Python/$(OV_PYTHON_VERSION)/x64/include/python$(OV_PYTHON_VERSION_MAJOR_MINOR) \ + -DPYBIND11_PYTHON_EXECUTABLE_LAST=$(Agent.ToolsDirectory)/Python/$(OV_PYTHON_VERSION)/x64/bin/python$(OV_PYTHON_VERSION_MAJOR_MINOR) \ + -DPython3_EXECUTABLE=$(Agent.ToolsDirectory)/Python/$(OV_PYTHON_VERSION)/x64/bin/python$(OV_PYTHON_VERSION_MAJOR_MINOR) \ + -DPython3_INCLUDE_DIR=$(Agent.ToolsDirectory)/Python/$(OV_PYTHON_VERSION)/x64/include/python$(OV_PYTHON_VERSION_MAJOR_MINOR) \ -DENABLE_TESTS=ON \ -DENABLE_SYSTEM_TBB=ON \ -DENABLE_SYSTEM_PROTOBUF=ON \ diff --git a/.ci/azure/linux_debian.yml b/.ci/azure/linux_debian.yml index e94a0819705bd7..6fc7355b87d3de 100644 --- a/.ci/azure/linux_debian.yml +++ b/.ci/azure/linux_debian.yml @@ -150,7 +150,7 @@ jobs: -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DENABLE_PYTHON=ON -DENABLE_INTEL_GNA=OFF - -DPYTHON_EXECUTABLE=$(BUILD_VENV)/bin/python3 + -DPython3_EXECUTABLE=$(BUILD_VENV)/bin/python3 -DENABLE_TESTS=ON -DENABLE_FASTER_BUILD=ON -DENABLE_STRICT_DEPENDENCIES=OFF diff --git a/.ci/azure/linux_lohika.yml b/.ci/azure/linux_lohika.yml index 5fb3b59129efa3..08f3690c76c282 100644 --- a/.ci/azure/linux_lohika.yml +++ b/.ci/azure/linux_lohika.yml @@ -49,7 +49,7 @@ jobs: # -DCMAKE_VERBOSE_MAKEFILE=ON # -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) # -DENABLE_PYTHON=ON -# -DPYTHON_EXECUTABLE=/usr/bin/python3.8 +# -DPython3_EXECUTABLE=/usr/bin/python3.8 # -DENABLE_TESTS=ON # -DENABLE_OV_ONNX_FRONTEND=ON # -DENABLE_FASTER_BUILD=ON diff --git a/.ci/azure/windows.yml b/.ci/azure/windows.yml index f0217b36c10df9..8379825bd23f55 100644 --- a/.ci/azure/windows.yml +++ b/.ci/azure/windows.yml @@ -166,9 +166,7 @@ jobs: -DENABLE_PYTHON=ON ^ -DBUILD_nvidia_plugin=OFF ^ -DCUSTOM_OPERATIONS="calculate_grid;complex_mul;fft;grid_sample;sparse_conv;sparse_conv_transpose" ^ - -DPYTHON_EXECUTABLE="C:\hostedtoolcache\windows\Python\3.11.2\x64\python.exe" ^ - -DPYTHON_INCLUDE_DIR="C:\hostedtoolcache\windows\Python\3.11.2\x64\include" ^ - -DPYTHON_LIBRARY="C:\hostedtoolcache\windows\Python\3.11.2\x64\libs\python311.lib" ^ + -DPython3_EXECUTABLE="C:\hostedtoolcache\windows\Python\3.11.2\x64\python.exe" ^ -DOPENVINO_EXTRA_MODULES=$(OPENVINO_CONTRIB_REPO_DIR)\modules ^ -DCMAKE_C_COMPILER:PATH="$(MSVC_COMPILER_PATH)" ^ -DCMAKE_CXX_COMPILER:PATH="$(MSVC_COMPILER_PATH)" ^ diff --git a/.ci/azure/windows_conditional_compilation.yml b/.ci/azure/windows_conditional_compilation.yml index daf75364d29e1c..70c7ebfff239e6 100644 --- a/.ci/azure/windows_conditional_compilation.yml +++ b/.ci/azure/windows_conditional_compilation.yml @@ -151,7 +151,7 @@ jobs: - script: | call "$(MSVS_VARS_PATH)" && cmake ^ -G "Visual Studio 16 2019" ^ - -DVERBOSE_BUILD=ON ^ + -DCMAKE_VERBOSE_MAKEFILE=ON ^ -DENABLE_CPPLINT=OFF ^ -DENABLE_GAPI_PREPROCESSING=OFF ^ -DENABLE_PROFILING_ITT=OFF ^ diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0b0a46c71e8080..a00a5b9d0241eb 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -22,9 +22,11 @@ on: - '**/conformance/**' branches: - master + - 'releases/**' concurrency: - group: ${{ github.head_ref || github.run_id }}-linux + # github.ref is not unique in post-commit + group: ${{ github.event_name == 'push' && github.run_id || github.ref }}-linux cancel-in-progress: true jobs: @@ -171,7 +173,7 @@ jobs: cmake -UPYTHON* \ -DCPACK_GENERATOR=DEB \ -DENABLE_PYTHON_PACKAGING=ON \ - -DPYTHON_EXECUTABLE=/usr/bin/python3.8 \ + -DPython3_EXECUTABLE=/usr/bin/python3.8 \ -DENABLE_TESTS=OFF \ -S ${OPENVINO_REPO} \ -B ${BUILD_DIR} diff --git a/.github/workflows/linux_arm64.yml b/.github/workflows/linux_arm64.yml index 3ed58d0ec02de9..117f4eee1594f2 100644 --- a/.github/workflows/linux_arm64.yml +++ b/.github/workflows/linux_arm64.yml @@ -161,8 +161,7 @@ jobs: -DENABLE_WHEEL=ON \ -DPYBIND11_PYTHONLIBS_OVERWRITE=OFF \ -DPYTHON_MODULE_EXTENSION=$(aarch64-linux-gnu-python3-config --extension-suffix) \ - -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libc-2.31.so \ - -DPYTHON_INCLUDE_DIR=$(python3 -c "import sysconfig; print(sysconfig.get_path('include'))") \ + -DPython3_INCLUDE_DIR=$(python3 -c "import sysconfig; print(sysconfig.get_path('include'))") \ -DENABLE_TESTS=ON \ -DENABLE_SYSTEM_TBB=ON \ -DENABLE_SYSTEM_PROTOBUF=ON \ diff --git a/.github/workflows/windows_conditional_compilation.yml b/.github/workflows/windows_conditional_compilation.yml index 5418afff20f54a..fabd763e1a3f2d 100644 --- a/.github/workflows/windows_conditional_compilation.yml +++ b/.github/workflows/windows_conditional_compilation.yml @@ -138,7 +138,7 @@ jobs: - name: CMake CC ON run: | & "${{ env.VCVARSPATH }}" x64 && cmake -G "Visual Studio 17 2022" ` - -DVERBOSE_BUILD=ON ` + -DCMAKE_VERBOSE_MAKEFILE=ON ` -DENABLE_CPPLINT=OFF ` -DENABLE_GAPI_PREPROCESSING=OFF ` -DENABLE_PROFILING_ITT=OFF ` diff --git a/CMakeLists.txt b/CMakeLists.txt index 51df130603a65e..e4d31492a43f4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,14 @@ if(NOT DEFINED CMAKE_MINIMUM_REQUIRED_VERSION) # we have to use CPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS variable set(CMAKE_MINIMUM_REQUIRED_VERSION 3.20) else() - # default choice - set(CMAKE_MINIMUM_REQUIRED_VERSION 3.13) + if(WIN32) + # 3.16: FindPython3.cmake can find Python via -DPython3_EXECUTABLE + # 3.18: FindPython3.cmake can find Python automatically from virtualenv + set(CMAKE_MINIMUM_REQUIRED_VERSION 3.16) + else() + # 3.13: default choice + set(CMAKE_MINIMUM_REQUIRED_VERSION 3.13) + endif() endif() endif() endif() diff --git a/cmake/developer_package/IEDevScriptsConfig.cmake b/cmake/developer_package/IEDevScriptsConfig.cmake index 4f6a195b293bc9..e1ccba489fcacf 100644 --- a/cmake/developer_package/IEDevScriptsConfig.cmake +++ b/cmake/developer_package/IEDevScriptsConfig.cmake @@ -200,6 +200,8 @@ set(CMAKE_POLICY_DEFAULT_CMP0068 NEW) set(CMAKE_POLICY_DEFAULT_CMP0074 NEW) # CMake 3.13+: option() honors normal variables. set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) +# CMake 3.15: Modules FindPython3, FindPython2 and FindPython use LOCATION for lookup strategy +set(CMAKE_POLICY_DEFAULT_CMP0094 NEW) # CMake 3.19+: An imported target missing its location property fails during generation. set(CMAKE_POLICY_DEFAULT_CMP0111 NEW) # CMake 3.22+ :cmake_dependent_option() supports full Condition Syntax diff --git a/cmake/developer_package/cpplint/cpplint.cmake b/cmake/developer_package/cpplint/cpplint.cmake index a4f03940567fd0..d4da25ea31952f 100644 --- a/cmake/developer_package/cpplint/cpplint.cmake +++ b/cmake/developer_package/cpplint/cpplint.cmake @@ -3,9 +3,9 @@ # if(ENABLE_CPPLINT) - find_host_package(PythonInterp 3 QUIET) + find_host_package(Python3 QUIET COMPONENTS Interpreter) - if(NOT PYTHONINTERP_FOUND) + if(NOT Python3_Interpreter_FOUND) message(WARNING "Python3 interpreter was not found (required for cpplint check)") set(ENABLE_CPPLINT OFF) endif() @@ -68,7 +68,7 @@ function(add_cpplint_target TARGET_NAME) "${output_file}" COMMAND "${CMAKE_COMMAND}" - -D "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" + -D "Python3_EXECUTABLE=${Python3_EXECUTABLE}" -D "CPPLINT_SCRIPT=${IEDevScripts_DIR}/cpplint/cpplint.py" -D "INPUT_FILE=${source_file}" -D "OUTPUT_FILE=${output_file}" diff --git a/cmake/developer_package/cpplint/cpplint_html.cmake b/cmake/developer_package/cpplint/cpplint_html.cmake index 28ebad97d31731..23268099eee70c 100644 --- a/cmake/developer_package/cpplint/cpplint_html.cmake +++ b/cmake/developer_package/cpplint/cpplint_html.cmake @@ -10,7 +10,7 @@ file(MAKE_DIRECTORY "${REPORT_DIR}") execute_process( COMMAND - "${PYTHON_EXECUTABLE}" + "${Python3_EXECUTABLE}" "${CONVERT_SCRIPT}" "--file=${INPUT_FILE}" "--report-dir=${REPORT_DIR}" diff --git a/cmake/developer_package/cpplint/cpplint_run.cmake b/cmake/developer_package/cpplint/cpplint_run.cmake index b10580655bf47b..e477c9b0b70ba6 100644 --- a/cmake/developer_package/cpplint/cpplint_run.cmake +++ b/cmake/developer_package/cpplint/cpplint_run.cmake @@ -25,7 +25,7 @@ set(FILTER "${DEFAULT_FILTER}${CUSTOM_FILTER}") execute_process( COMMAND - "${PYTHON_EXECUTABLE}" + "${Python3_EXECUTABLE}" "${CPPLINT_SCRIPT}" "--linelength=160" "--counting=detailed" diff --git a/cmake/developer_package/cpplint/cpplint_to_cppcheck_xml.cmake b/cmake/developer_package/cpplint/cpplint_to_cppcheck_xml.cmake index db3aa1417a6b65..6853f544c20393 100644 --- a/cmake/developer_package/cpplint/cpplint_to_cppcheck_xml.cmake +++ b/cmake/developer_package/cpplint/cpplint_to_cppcheck_xml.cmake @@ -4,7 +4,7 @@ execute_process( COMMAND - "${PYTHON_EXECUTABLE}" + "${Python3_EXECUTABLE}" "${CONVERT_SCRIPT}" INPUT_FILE "${INPUT_FILE}" OUTPUT_FILE "${OUTPUT_FILE}" diff --git a/cmake/developer_package/features.cmake b/cmake/developer_package/features.cmake index 466a6041dfb179..bda6eb353bb022 100644 --- a/cmake/developer_package/features.cmake +++ b/cmake/developer_package/features.cmake @@ -73,8 +73,6 @@ ie_option (ENABLE_CLANG_FORMAT "Enable clang-format checks during the build" ${S ie_option (ENABLE_NCC_STYLE "Enable ncc style check" ${STYLE_CHECKS_DEFAULT}) -ie_option (VERBOSE_BUILD "shows extra information about build" OFF) - ie_option (ENABLE_UNSAFE_LOCATIONS "skip check for MD5 for dependency" OFF) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER_EQUAL 1930) @@ -104,5 +102,3 @@ if(ENABLE_AVX512F) set(ENABLE_AVX512F OFF CACHE BOOL "" FORCE) endif() endif() - -set(CMAKE_VERBOSE_MAKEFILE ${VERBOSE_BUILD} CACHE BOOL "" FORCE) diff --git a/cmake/developer_package/ncc_naming_style/ncc_naming_style.cmake b/cmake/developer_package/ncc_naming_style/ncc_naming_style.cmake index b22930fb2047ec..cf2f447565ae43 100644 --- a/cmake/developer_package/ncc_naming_style/ncc_naming_style.cmake +++ b/cmake/developer_package/ncc_naming_style/ncc_naming_style.cmake @@ -12,28 +12,28 @@ set(ncc_style_bin_dir "${CMAKE_CURRENT_BINARY_DIR}/ncc_naming_style") # find python3 if(ENABLE_NCC_STYLE) - find_host_package(PythonInterp 3 QUIET) - if(NOT PYTHONINTERP_FOUND) + find_host_package(Python3 QUIET COMPONENTS Interpreter) + if(NOT Python3_Interpreter_FOUND) message(WARNING "Python3 interpreter was not found (required for ncc naming style check)") set(ENABLE_NCC_STYLE OFF) endif() endif() if(ENABLE_NCC_STYLE) - if(PYTHON_VERSION_MINOR EQUAL 6) + if(Python3_VERSION_MINOR EQUAL 6) set(clang_version 10) - elseif(PYTHON_VERSION_MINOR EQUAL 7) + elseif(Python3_VERSION_MINOR EQUAL 7) set(clang_version 11) - elseif(PYTHON_VERSION_MINOR EQUAL 8) + elseif(Python3_VERSION_MINOR EQUAL 8) set(clang_version 12) - elseif(PYTHON_VERSION_MINOR EQUAL 9) + elseif(Python3_VERSION_MINOR EQUAL 9) set(clang_version 12) - elseif(PYTHON_VERSION_MINOR EQUAL 10) + elseif(Python3_VERSION_MINOR EQUAL 10) set(clang_version 14) - elseif(PYTHON_VERSION_MINOR EQUAL 11) + elseif(Python3_VERSION_MINOR EQUAL 11) set(clang_version 14) else() - message(WARNING "Cannot suggest clang package for python ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") + message(WARNING "Cannot suggest clang package for python ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") endif() endif() @@ -170,7 +170,7 @@ function(ov_ncc_naming_style) ${output_file} COMMAND "${CMAKE_COMMAND}" - -D "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" + -D "Python3_EXECUTABLE=${Python3_EXECUTABLE}" -D "NCC_PY_SCRIPT=${ncc_script_py}" -D "INPUT_FILE=${source_file}" -D "OUTPUT_FILE=${output_file}" diff --git a/cmake/developer_package/ncc_naming_style/ncc_run.cmake b/cmake/developer_package/ncc_naming_style/ncc_run.cmake index f37124df9b7c34..6f87be15c1b2ce 100644 --- a/cmake/developer_package/ncc_naming_style/ncc_run.cmake +++ b/cmake/developer_package/ncc_naming_style/ncc_run.cmake @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # -foreach(var NCC_PY_SCRIPT PYTHON_EXECUTABLE OUTPUT_FILE DEFINITIONS EXPECTED_FAIL +foreach(var NCC_PY_SCRIPT Python3_EXECUTABLE OUTPUT_FILE DEFINITIONS EXPECTED_FAIL INPUT_FILE ADDITIONAL_INCLUDE_DIRECTORIES STYLE_FILE CLANG_LIB_PATH) if(NOT DEFINED ${var}) message(FATAL_ERROR "${var} is not defined for ncc_run.cmake") @@ -17,7 +17,7 @@ endif() execute_process( COMMAND - "${PYTHON_EXECUTABLE}" + "${Python3_EXECUTABLE}" "${NCC_PY_SCRIPT}" --path ${INPUT_FILE} --style ${STYLE_FILE} diff --git a/cmake/developer_package/packaging/packaging.cmake b/cmake/developer_package/packaging/packaging.cmake index 7bb33d49490aef..ae2d4d643211d6 100644 --- a/cmake/developer_package/packaging/packaging.cmake +++ b/cmake/developer_package/packaging/packaging.cmake @@ -35,9 +35,9 @@ endmacro() # ov_get_pyversion() # function(ov_get_pyversion pyversion) - find_package(PythonInterp 3 QUIET) - if(PYTHONINTERP_FOUND) - set(${pyversion} "python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" PARENT_SCOPE) + find_package(Python3 QUIET COMPONENTS Interpreter Develoment.Module) + if(Python3_Interpreter_FOUND) + set(${pyversion} "python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}" PARENT_SCOPE) else() set(${pyversion} "NOT-FOUND" PARENT_SCOPE) endif() diff --git a/cmake/developer_package/python_requirements.cmake b/cmake/developer_package/python_requirements.cmake index 3f5dcd6bd0d5dd..4d031f22c8a4a6 100644 --- a/cmake/developer_package/python_requirements.cmake +++ b/cmake/developer_package/python_requirements.cmake @@ -9,7 +9,7 @@ # [MESSAGE_MODE ]) # function(ov_check_pip_package) - find_host_package(PythonInterp 3 QUIET) + find_host_package(Python3 QUIET COMPONENTS Interpreter) set(oneValueOptionalArgs MESSAGE_MODE # Set the type of message: { FATAL_ERROR | WARNING | ... } @@ -42,19 +42,21 @@ function(ov_check_pip_package) # quote '3.x' with \'3.x\' string(REPLACE "'" "\\'" REQ "${ARG_REQUIREMENT}") - if(PYTHONINTERP_FOUND) + if(Python3_Interpreter_FOUND) execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "import pkg_resources ; pkg_resources.require('${REQ}')" + COMMAND ${Python3_EXECUTABLE} -c "import pkg_resources ; pkg_resources.require('${REQ}')" RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE OUTPUT_TEXT ERROR_VARIABLE ERROR_TEXT) + else() + set(EXIT_CODE 1) endif() - if(NOT EXIT_CODE EQUAL 0) + if(EXIT_CODE EQUAL 0) + set(${ARG_RESULT_VAR} ON PARENT_SCOPE) + else() set(${ARG_RESULT_VAR} OFF PARENT_SCOPE) message(${ARG_MESSAGE_MODE} "Python module '${REQ}' is missed, ${ARG_WARNING_MESSAGE}") - else() - set(${ARG_RESULT_VAR} ON PARENT_SCOPE) endif() endfunction() @@ -65,7 +67,7 @@ endfunction() # [MESSAGE_MODE ]) # function(ov_check_pip_packages) - find_host_package(PythonInterp 3 QUIET) + find_host_package(Python3 QUIET COMPONENTS Interpreter) set(oneValueOptionalArgs MESSAGE_MODE # Set the type of message: { FATAL_ERROR | WARNING | ... } @@ -95,9 +97,9 @@ function(ov_check_pip_packages) message(SEND_ERROR "Unexpected parameters have passed to the function: ${ARG_UNPARSED_ARGUMENTS}") endif() - if(PYTHONINTERP_FOUND) + if(Python3_Interpreter_FOUND) execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c " + COMMAND ${Python3_EXECUTABLE} -c " from check_python_requirements import check_python_requirements ; check_python_requirements('${ARG_REQUIREMENTS_FILE}') ; " @@ -105,12 +107,14 @@ check_python_requirements('${ARG_REQUIREMENTS_FILE}') ; RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE OUTPUT_TEXT ERROR_VARIABLE ERROR_TEXT) + else() + set(EXIT_CODE 1) endif() - if(NOT EXIT_CODE EQUAL 0) + if(EXIT_CODE EQUAL 0) + set(${ARG_RESULT_VAR} ON PARENT_SCOPE) + else() set(${ARG_RESULT_VAR} OFF PARENT_SCOPE) message(${ARG_MESSAGE_MODE} "Python requirement file ${ARG_REQUIREMENTS_FILE} is not installed, ${ARG_WARNING_MESSAGE}") - else() - set(${ARG_RESULT_VAR} ON PARENT_SCOPE) endif() endfunction() diff --git a/cmake/features.cmake b/cmake/features.cmake index 2ba1567b7762c5..455ff21388989a 100644 --- a/cmake/features.cmake +++ b/cmake/features.cmake @@ -14,8 +14,6 @@ ie_dependent_option (ENABLE_ARM_COMPUTE_CMAKE "Enable ARM Compute build via cmak ie_option (ENABLE_TESTS "unit, behavior and functional tests" OFF) -ie_option (ENABLE_STRICT_DEPENDENCIES "Skip configuring \"convinient\" dependencies for efficient parallel builds" ON) - if(X86_64) set(ENABLE_INTEL_GPU_DEFAULT ON) else() @@ -112,8 +110,12 @@ ie_option (ENABLE_SAMPLES "console samples are part of OpenVINO Runtime package" set(OPENVINO_EXTRA_MODULES "" CACHE STRING "Extra paths for extra modules to include into OpenVINO build") -find_host_package(PythonInterp 3 QUIET) -ie_option(ENABLE_OV_ONNX_FRONTEND "Enable ONNX FrontEnd" ${PYTHONINTERP_FOUND}) +find_host_package(Python3 QUIET COMPONENTS Interpreter) +if(Python3_Interpreter_FOUND) + ie_option(ENABLE_OV_ONNX_FRONTEND "Enable ONNX FrontEnd" ON) +else() + ie_option(ENABLE_OV_ONNX_FRONTEND "Enable ONNX FrontEnd" OFF) +endif() ie_option(ENABLE_OV_PADDLE_FRONTEND "Enable PaddlePaddle FrontEnd" ON) ie_option(ENABLE_OV_IR_FRONTEND "Enable IR FrontEnd" ON) ie_option(ENABLE_OV_PYTORCH_FRONTEND "Enable PyTorch FrontEnd" ON) @@ -123,6 +125,8 @@ ie_option(ENABLE_OV_TF_LITE_FRONTEND "Enable TensorFlow Lite FrontEnd" ON) ie_dependent_option(ENABLE_SNAPPY_COMPRESSION "Enables compression support for TF FE" ON "ENABLE_OV_TF_FRONTEND" OFF) +ie_dependent_option (ENABLE_STRICT_DEPENDENCIES "Skip configuring \"convinient\" dependencies for efficient parallel builds" ON "ENABLE_TESTS;ENABLE_OV_ONNX_FRONTEND" OFF) + if(CMAKE_HOST_LINUX AND LINUX) # Debian packages are enabled on Ubuntu systems # so, system TBB / pugixml / OpenCL can be tried for usage diff --git a/cmake/packaging/debian.cmake b/cmake/packaging/debian.cmake index d359a40aa6df51..fda353d6ab512e 100644 --- a/cmake/packaging/debian.cmake +++ b/cmake/packaging/debian.cmake @@ -47,9 +47,9 @@ 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 "pyopenvino_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") + # skip OpenVINO Python API (pattern in form of "pyopenvino_python${Python3_VERSION_MAJOR}${Python3_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 + # because in case of .deb package, pyopenvino_package_python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR} is installed (NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_python.*" OR ENABLE_PYTHON_PACKAGING) AND # see ticket # 82605 NOT item STREQUAL "gna" AND diff --git a/cmake/packaging/rpm.cmake b/cmake/packaging/rpm.cmake index 077e970d138bc4..9c8103e12bd8ad 100644 --- a/cmake/packaging/rpm.cmake +++ b/cmake/packaging/rpm.cmake @@ -33,9 +33,9 @@ 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 "pyopenvino_python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") + # skip OpenVINO Python API (pattern in form of "pyopenvino_python${Python3_VERSION_MAJOR}${Python3_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 + # because in case of .rpm package, pyopenvino_package_python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR} is installed (NOT item MATCHES "^${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_python.*" OR ENABLE_PYTHON_PACKAGING) AND # see ticket # 82605 NOT item STREQUAL "gna" AND diff --git a/cmake/test_model_zoo.cmake b/cmake/test_model_zoo.cmake index ee6cd463fd764a..9af452c8a4d2cb 100644 --- a/cmake/test_model_zoo.cmake +++ b/cmake/test_model_zoo.cmake @@ -22,6 +22,7 @@ function(ov_model_convert SRC DST OUT) if(onnx_FOUND) file(GLOB_RECURSE prototxt_models RELATIVE "${SRC}" "${SRC}/*.prototxt") + find_host_package(Python3 REQUIRED COMPONENTS Interpreter) endif() foreach(in_file IN LISTS prototxt_models xml_models bin_models onnx_models data_models) @@ -48,7 +49,7 @@ function(ov_model_convert SRC DST OUT) add_custom_command(OUTPUT ${full_out_name} COMMAND ${CMAKE_COMMAND} -E make_directory "${DST}/${rel_dir}" - COMMAND ${PYTHON_EXECUTABLE} ${onnx_gen_script} + COMMAND ${Python3_EXECUTABLE} ${onnx_gen_script} "${SRC}/${in_file}" ${full_out_name} DEPENDS ${onnx_gen_script} "${SRC}/${in_file}" COMMENT "Generate ${rel_out_name}" diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 1f7d3a5357f690..debd39fc5d208b 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -66,7 +66,7 @@ function(build_docs) set(DOXYFILE_BUILD "${DOCS_BUILD_DIR}/Doxyfile.config") configure_file(${DOXYFILE_SOURCE} ${DOXYFILE_BUILD} @ONLY) - list(APPEND commands COMMAND ${PYTHON_EXECUTABLE} ${DOXY_MD_FILTER} + list(APPEND commands COMMAND ${Python3_EXECUTABLE} ${DOXY_MD_FILTER} --input_dir=${OpenVINO_SOURCE_DIR} --output_dir=${DOCS_BUILD_DIR}/openvino --exclude_dir=${DOCS_BUILD_DIR}) @@ -77,7 +77,7 @@ function(build_docs) if(ENABLE_OPENVINO_NOTEBOOKS) set(NBDOC_SCRIPT "${DOCS_SOURCE_DIR}/nbdoc/nbdoc.py") list(PREPEND commands - COMMAND ${PYTHON_EXECUTABLE} "${NBDOC_SCRIPT}" "${DOCS_SOURCE_DIR}/notebooks" "${RST_OUTPUT}/notebooks" + COMMAND ${Python3_EXECUTABLE} "${NBDOC_SCRIPT}" "${DOCS_SOURCE_DIR}/notebooks" "${RST_OUTPUT}/notebooks" ) endif() @@ -97,8 +97,8 @@ function(build_docs) if(EXISTS "${OMZ_DOCS_DIR}") get_filename_component(OMZ_DOCS_DIR "${OMZ_DOCS_DIR}" ABSOLUTE) list(APPEND commands - COMMAND ${PYTHON_EXECUTABLE} ${OMZ_DOCS_DIR}/ci/prepare-documentation.py ${CMAKE_BINARY_DIR}/open_model_zoo) - list(APPEND commands COMMAND ${PYTHON_EXECUTABLE} ${DOXY_MD_FILTER} + COMMAND ${Python3_EXECUTABLE} ${OMZ_DOCS_DIR}/ci/prepare-documentation.py ${CMAKE_BINARY_DIR}/open_model_zoo) + list(APPEND commands COMMAND ${Python3_EXECUTABLE} ${DOXY_MD_FILTER} --input_dir=${CMAKE_BINARY_DIR}/open_model_zoo --output_dir=${DOCS_BUILD_DIR}/open_model_zoo) endif() @@ -107,7 +107,7 @@ function(build_docs) if(EXISTS "${WORKBENCH_DOCS_DIR}") get_filename_component(WORKBENCH_DOCS_DIR "${WORKBENCH_DOCS_DIR}" ABSOLUTE) - list(APPEND commands COMMAND ${PYTHON_EXECUTABLE} ${DOXY_MD_FILTER} + list(APPEND commands COMMAND ${Python3_EXECUTABLE} ${DOXY_MD_FILTER} --input_dir=${WORKBENCH_DOCS_DIR} --output_dir=${DOCS_BUILD_DIR}/workbench) endif() @@ -116,7 +116,7 @@ function(build_docs) if(EXISTS "${OTE_DOCS_DIR}") get_filename_component(WORKBENCH_DOCS_DIR "${OTE_DOCS_DIR}" ABSOLUTE) - list(APPEND commands COMMAND ${PYTHON_EXECUTABLE} ${DOXY_MD_FILTER} + list(APPEND commands COMMAND ${Python3_EXECUTABLE} ${DOXY_MD_FILTER} --input_dir=${OTE_DOCS_DIR} --output_dir=${DOCS_BUILD_DIR}/ote) endif() @@ -125,7 +125,7 @@ function(build_docs) if(EXISTS "${OVMS_DOCS_DIR}") get_filename_component(OVMS_DOCS_DIR "${OVMS_DOCS_DIR}" ABSOLUTE) - list(APPEND commands COMMAND ${PYTHON_EXECUTABLE} ${DOXY_MD_FILTER} + list(APPEND commands COMMAND ${Python3_EXECUTABLE} ${DOXY_MD_FILTER} --input_dir=${OVMS_DOCS_DIR} --output_dir=${DOCS_BUILD_DIR}/ovms) endif() @@ -144,7 +144,7 @@ function(build_docs) add_custom_target(doxygen_xml DEPENDS preprocess_docs - COMMAND ${PYTHON_EXECUTABLE} ${REMOVE_XML_SCRIPT} ${XML_OUTPUT} + COMMAND ${Python3_EXECUTABLE} ${REMOVE_XML_SCRIPT} ${XML_OUTPUT} COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_BUILD} WORKING_DIRECTORY ${DOCS_BUILD_DIR} COMMENT "Generate doxygen XML output" @@ -153,11 +153,11 @@ function(build_docs) # Post-process docs add_custom_command(TARGET doxygen_xml POST_BUILD - COMMAND ${PYTHON_EXECUTABLE} ${PREPARE_XML_SCRIPT} ${XML_OUTPUT} + COMMAND ${Python3_EXECUTABLE} ${PREPARE_XML_SCRIPT} ${XML_OUTPUT} COMMAND ${CMAKE_COMMAND} -E copy_directory ${DOXYREST_IN} ${DOXYREST_OUT} COMMAND ${DOXYREST_EXECUTABLE} -c ${DOXYREST_CONFIG_OUT} - COMMAND ${PYTHON_EXECUTABLE} ${COPY_IMAGES_SCRIPT} ${XML_OUTPUT} ${RST_OUTPUT} - COMMAND ${PYTHON_EXECUTABLE} ${DOXYGEN_MAPPING_SCRIPT} ${XML_OUTPUT} ${DOCS_BUILD_DIR} ${OpenVINO_SOURCE_DIR}/../ + COMMAND ${Python3_EXECUTABLE} ${COPY_IMAGES_SCRIPT} ${XML_OUTPUT} ${RST_OUTPUT} + COMMAND ${Python3_EXECUTABLE} ${DOXYGEN_MAPPING_SCRIPT} ${XML_OUTPUT} ${DOCS_BUILD_DIR} ${OpenVINO_SOURCE_DIR}/../ COMMAND ${CMAKE_COMMAND} -E copy ${SPHINX_INDEX_IN} ${SPHINX_INDEX_OUT} COMMAND ${CMAKE_COMMAND} -E copy_directory ${SPHINX_TEMPLATES_IN} ${SPHINX_TEMPLATES_OUT} COMMAND ${CMAKE_COMMAND} -E copy_directory ${DOXYREST_IN} ${DOXYREST_OUT} diff --git a/docs/_static/js/custom.js b/docs/_static/js/custom.js index a208c2c7362a8a..3b9af96ec7314f 100644 --- a/docs/_static/js/custom.js +++ b/docs/_static/js/custom.js @@ -317,7 +317,7 @@ document.addEventListener('DOMContentLoaded', function () { if (searchInterfaceSa) { let ver = getCurrentVersion(); if (ver) { - searchInterfaceSa.innerHTML = searchInterfaceSa.innerHTML.replace('search.html', 'search.html#f-ovversion=' + ver); + searchInterfaceSa.innerHTML = searchInterfaceSa.innerHTML.replace('search.html', '/' + ver +'/search.html#f-ovversion=' + ver); } await searchInterfaceSa.initialize({ accessToken: "xx1f2aebd3-4307-4632-aeea-17c13378b237", diff --git a/docs/dev/build_linux.md b/docs/dev/build_linux.md index 35fee45de09e94..e2794bcdfda4cf 100644 --- a/docs/dev/build_linux.md +++ b/docs/dev/build_linux.md @@ -72,11 +72,9 @@ You can use the following additional build options: ```sh pip install -r requirements-dev.txt ``` - 2. Enable the `-DENABLE_PYTHON=ON` option in the CMake step above (Step 4). To specify an exact Python version, use the following options: + 2. Enable the `-DENABLE_PYTHON=ON` option in the CMake step above (Step 4). To specify an exact Python version, use the following options (requires cmake 3.16 and higher): ``` - -DPYTHON_EXECUTABLE=`which python3.8` \ - -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.8.so \ - -DPYTHON_INCLUDE_DIR=/usr/include/python3.8 + -DPython3_EXECUTABLE=/usr/bin/python3.8 ``` 3. To build a wheel package (.whl), enable the `-DENABLE_WHEEL=ON` option in the CMake step above (Step 4), and install requirements: ```sh diff --git a/docs/dev/build_raspbian.md b/docs/dev/build_raspbian.md index 9665c1ddb4954f..6b81e9d3c446fb 100644 --- a/docs/dev/build_raspbian.md +++ b/docs/dev/build_raspbian.md @@ -43,9 +43,7 @@ git clone --recurse-submodules --single-branch --branch=master https://github.co via `pip3`, adding the following options: ```sh -DENABLE_PYTHON=ON \ - -DPYTHON_EXECUTABLE=/usr/bin/python3.8 \ - -DPYTHON_LIBRARY=/usr/lib/arm-linux-gnueabihf/libpython3.8.so \ - -DPYTHON_INCLUDE_DIR=/usr/include/python3.8 + -DPython3_EXECUTABLE=/usr/bin/python3.8 ``` ## See also diff --git a/docs/dev/build_windows.md b/docs/dev/build_windows.md index 57b38d9deeb93c..86785e8bdc494f 100644 --- a/docs/dev/build_windows.md +++ b/docs/dev/build_windows.md @@ -55,11 +55,9 @@ Supported configurations: ```sh pip install -r \src\bindings\python\src\compatibility\openvino\requirements-dev.txt ``` - 2. Second, enable the `-DENABLE_PYTHON=ON` in the CMake (Step #4) option above. To specify an exact Python version, use the following options: + 2. Second, enable the `-DENABLE_PYTHON=ON` in the CMake (Step #4) option above. To specify an exact Python version, use the following options (requires cmake 3.16 and higher): ```sh - -DPYTHON_EXECUTABLE="C:\Program Files\Python11\python.exe" ^ - -DPYTHON_LIBRARY="C:\Program Files\Python11\libs\python11.lib" ^ - -DPYTHON_INCLUDE_DIR="C:\Program Files\Python11\include" + -DPython3_EXECUTABLE="C:\Program Files\Python11\python.exe" ``` 3. To build a wheel package (.whl), enable the `-DENABLE_WHEEL=ON` option in the CMake step above (Step 4), and install requirements: ```sh diff --git a/src/bindings/c/include/openvino/c/openvino.h b/src/bindings/c/include/openvino/c/openvino.h index f49a5049f7ed91..c534fc688d1a9e 100644 --- a/src/bindings/c/include/openvino/c/openvino.h +++ b/src/bindings/c/include/openvino/c/openvino.h @@ -15,6 +15,12 @@ **/ #pragma once +#ifdef _WINDOWS_ +# pragma message( \ + "The BOOLEAN define in ov_element_type_e conflict with Windows.h BOOLEAN define. The BOOLEAN of ov_element_type_e redefine to OV_BOOLEAN here. If you want to use BOOLEAN of Windows.h, pls redefine befor include openvino/c/openvino.h, such as typedef BOOLEAN WIN_BOOLEAN") +#endif +#define BOOLEAN OV_BOOLEAN + #include "openvino/c/auto/properties.h" #include "openvino/c/ov_common.h" #include "openvino/c/ov_compiled_model.h" diff --git a/src/bindings/c/tests/ov_windows_conflict_test.cpp b/src/bindings/c/tests/ov_windows_conflict_test.cpp new file mode 100644 index 00000000000000..07262bddeebe7f --- /dev/null +++ b/src/bindings/c/tests/ov_windows_conflict_test.cpp @@ -0,0 +1,26 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +/* + * This test only for Windows, which caused by the BOOLEAN define conflict between Windows.h and openvino.h + * (ov_element_type_e). Sollution: 1) check Windows.h was used or not in openvino.h for windows OS 2) if YES, will + * redefine the "BOOLEAN" from Windows.h to "WIN_BOOLEAN" and also redefine the "BOOLEAN" from openvino.h to + * "OV_BOOLEAN" + */ + +#if defined(_WIN32) +# include +# include + +# include "openvino/c/openvino.h" + +# ifndef UNUSED +# define UNUSED(x) ((void)(x)) +# endif + +TEST(ov_windows_conflict_test, ov_windows_boolean_conflict) { + ov_element_type_e element_type = OV_BOOLEAN; // The BOOLEAN from ov_element_type_e will be replaced by OV_BOOLEAN + UNUSED(element_type); +} +#endif diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index b46eaaf9883e16..c8b55e3b280e01 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -2,7 +2,14 @@ # SPDX-License-Identifier: Apache-2.0 # -cmake_minimum_required (VERSION 3.13) +if(WIN32) + # 3.16: FindPython3.cmake can find Python via -DPython3_EXECUTABLE + # 3.18: FindPython3.cmake can find Python automatically from virtualenv + cmake_minimum_required(VERSION 3.16) +else() + # 3.13: default choice + cmake_minimum_required(VERSION 3.13) +endif() project(OpenVINOPython DESCRIPTION "OpenVINO Runtime Python bindings") @@ -16,6 +23,28 @@ if(NOT DEFINED OpenVINO_SOURCE_DIR) set(OpenVINO_BINARY_DIR "${OpenVINODeveloperPackage_DIR}") endif() +# +# Settings for FindPython3.cmake +# + +if(NOT DEFINED Python3_USE_STATIC_LIBS) + set(Python3_USE_STATIC_LIBS OFF) +endif() + +if(NOT DEFINED Python3_FIND_VIRTUALENV) + set(Python3_FIND_VIRTUALENV FIRST) +endif() + +if(NOT DEFINED Python3_FIND_IMPLEMENTATIONS) + set(Python3_FIND_IMPLEMENTATIONS CPython PyPy) +endif() + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) + set(python3_development_component Development.Module) +else() + set(python3_development_component Development) +endif() + # # Check python requirements # @@ -32,52 +61,24 @@ function(ov_check_python_build_conditions) set(message_mode WARNING) endif() - # Try to find python3 and its libs - find_package(PythonInterp 3 ${find_package_mode}) - if(PYTHONINTERP_FOUND) - if(PYTHON_VERSION_MINOR GREATER_EQUAL 11) - set(pybind11_min_version 2.9.2) - else() - set(pybind11_min_version 2.8.0) + find_package(Python3 ${find_package_mode} COMPONENTS Interpreter ${python3_development_component}) + if(Python3_Development.Module_FOUND OR Python3_Development_FOUND) + message(STATUS "Python3 executable: ${Python3_EXECUTABLE}") + message(STATUS "Python3 version: ${Python3_VERSION}") + if(Python3_PyPy_VERSION) + message(STATUS "Python3 PyPy version: ${Python3_PyPy_VERSION}") endif() - if(CMAKE_CROSSCOMPILING) - # since this version pybind11 has PYBIND11_PYTHONLIBS_OVERWRITE option - # to properly cross-compile, users need to set: - # -DPYTHON_EXECUTABLE= - # -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libc-2.31.so - # -DPYTHON_INCLUDE_DIR= - # -DPYBIND11_PYTHONLIBS_OVERWRITE=OFF - # -DPYTHON_MODULE_EXTENSION=$(aarch64-linux-gnu-python3-config --extension-suffix) - set(pybind11_min_version 2.10.1) + message(STATUS "Python3 interpreter ID: ${Python3_INTERPRETER_ID}") + if(Python3_SOABI) + message(STATUS "Python3 SOABI: ${Python3_SOABI}") endif() - - function(_ov_find_python_libs_new) - set(pybind11_tools_dir "${OpenVINOPython_SOURCE_DIR}/thirdparty/pybind11/tools") - if(EXISTS ${pybind11_tools_dir}) - list(APPEND CMAKE_MODULE_PATH ${pybind11_tools_dir}) - else() - find_package(pybind11 ${pybind11_min_version} QUIET) - if(pybind11_FOUND) - list(APPEND CMAKE_MODULE_PATH "${pybind11_DIR}") - endif() - endif() - # use libraries with the same version as python itself - set(PYBIND11_PYTHON_VERSION ${PYTHON_VERSION_STRING}) - find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} EXACT ${find_package_mode}) - set(PYTHONLIBSNEW_FOUND ${PYTHONLIBS_FOUND} PARENT_SCOPE) - endfunction() - # try to find python libraries - _ov_find_python_libs_new() - if(PYTHONLIBSNEW_FOUND) - # clear Python_ADDITIONAL_VERSIONS to find only python library matching PYTHON_EXECUTABLE - unset(Python_ADDITIONAL_VERSIONS CACHE) - find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT ${find_package_mode}) - endif() - if(NOT PYTHONLIBS_FOUND) - message(${message_mode} "Python development libraries are not found. OpenVINO Python API will be turned off (ENABLE_PYTHON is OFF)") + if(PYTHON_MODULE_EXTENSION) + message(STATUS "PYTHON_MODULE_EXTENSION: ${PYTHON_MODULE_EXTENSION}") endif() + message(STATUS "Python3 include dirs: ${Python3_INCLUDE_DIRS}") + message(STATUS "Python3 libraries: ${Python3_LIBRARIES}") else() - message(${message_mode} "Python 3.x interpreter is not found. OpenVINO Python API will be turned off (ENABLE_PYTHON is OFF)") + message(${message_mode} "Python 3.x Interpreter and Development.Module components are not found. OpenVINO Python API will be turned off (ENABLE_PYTHON is OFF)") endif() # check for Cython requirement for build IE API 1.0 @@ -107,7 +108,8 @@ function(ov_check_python_build_conditions) set(python_debug OFF) endif() - if(PYTHONLIBS_FOUND AND ie_build_python_req_FOUND AND NOT python_debug) + if((Python3_Development.Module_FOUND OR Python3_Development_FOUND) AND + ie_build_python_req_FOUND AND NOT python_debug) set(ENABLE_PYTHON_DEFAULT ON PARENT_SCOPE) else() set(ENABLE_PYTHON_DEFAULT OFF PARENT_SCOPE) @@ -115,8 +117,6 @@ function(ov_check_python_build_conditions) # to disable API 1.0 set(ie_build_python_req_FOUND ${ie_build_python_req_FOUND} PARENT_SCOPE) - # set pybind11 minimal version - set(pybind11_min_version ${pybind11_min_version} PARENT_SCOPE) endfunction() ov_check_python_build_conditions() @@ -200,7 +200,7 @@ ie_dependent_option(ENABLE_WHEEL "Build wheel packages for PyPI" ${ENABLE_WHEEL_ if(NOT ENABLE_PYTHON) if(CMAKE_SOURCE_DIR STREQUAL OpenVINOPython_SOURCE_DIR) - message(FATAL_ERROR "Python OpenVINO API requirements are not satisfied. Please, install ${ie_build_python_req}") + message(FATAL_ERROR "Python OpenVINO API build requirements are not satisfied. Please, install ${ie_build_python_req}") else() return() endif() @@ -214,6 +214,13 @@ endif() # Build the code # +if(Python3_VERSION_MINOR GREATER_EQUAL 11) + set(pybind11_min_version 2.9.2) +else() + set(pybind11_min_version 2.8.0) +endif() + +find_package(Python3 REQUIRED COMPONENTS Interpreter ${python3_development_component}) find_package(pybind11 ${pybind11_min_version} QUIET) if(NOT pybind11_FOUND) @@ -234,8 +241,8 @@ endif() # macro(ov_define_setup_py_packaging_vars) - # PYTHON_VERSION_MAJOR and PYTHON_VERSION_MINOR are defined inside pybind11 - set(pyversion python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) + # Python3_VERSION_MAJOR and Python3_VERSION_MINOR are defined inside pybind11 + set(pyversion python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) # define version (syncronize with tools/openvino_dev/CMakeLists.txt) if(DEFINED ENV{CI_BUILD_DEV_TAG} AND NOT "$ENV{CI_BUILD_DEV_TAG}" STREQUAL "") @@ -330,9 +337,9 @@ endif() if(ENABLE_PYTHON_PACKAGING) # site-packages depending on package type - set(python_xy "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") + set(python_xy "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") if(CPACK_GENERATOR STREQUAL "DEB") - set(python_versioned_folder "python${PYTHON_VERSION_MAJOR}") + set(python_versioned_folder "python${Python3_VERSION_MAJOR}") set(ov_site_packages "dist-packages") elseif(CPACK_GENERATOR STREQUAL "RPM") set(python_versioned_folder "python${python_xy}") @@ -351,7 +358,7 @@ if(ENABLE_PYTHON_PACKAGING) # variables to reflect options (extensions only or full wheel package) PYTHON_EXTENSIONS_ONLY=ON SKIP_RPATH=ON - "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/wheel/setup.py" + "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/wheel/setup.py" --no-user-cfg --quiet build diff --git a/src/bindings/python/docs/build.md b/src/bindings/python/docs/build.md index 8aa8bcf3be460b..4786332647bd6b 100644 --- a/src/bindings/python/docs/build.md +++ b/src/bindings/python/docs/build.md @@ -48,15 +48,10 @@ OpenVINO can be built based on specific virtual environments such as [venv](http pip install -r src/bindings/python/wheel/requirements-dev.txt ``` -6. Add following flags to the main `cmake` command to use specific virtual environment: +6. Add following flags to the main `cmake` command to use specific virtual environment (requires cmake 3.16 and higher): ```shell - -DPYTHON_EXECUTABLE=`which python` \ - -DPYTHON_LIBRARY=/home/user/.pyenv/versions/3.10.7/lib/libpython3.10.so \ - -DPYTHON_INCLUDE_DIR=/home/user/.pyenv/versions/3.10.7/include/python3.10 + -DPython3_EXECUTABLE=/home/user/.pyenv/versions/3.10.7/bin/python ``` - *Note: In order to use `which python`, specific virtual environment has to be activated in a current shell.* - - *Note: `libpython3.10.so` is created with `--enable-shared` flag while installing specific Python version. For static build name of library may differ.* 7. Follow the rest of building and installation steps from ["How to build OpenVINO" developer documentation](../../../../docs/dev/build.md). diff --git a/src/bindings/python/src/compatibility/openvino/CMakeLists.txt b/src/bindings/python/src/compatibility/openvino/CMakeLists.txt index 6a1c48777cfa70..e6f7f2aec3b347 100644 --- a/src/bindings/python/src/compatibility/openvino/CMakeLists.txt +++ b/src/bindings/python/src/compatibility/openvino/CMakeLists.txt @@ -27,7 +27,8 @@ else() message(STATUS "Found Cython version ${CYTHON_VERSION}") endif() -set(pyversion python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) +# Python3_VERSION_MAJOR and Python3_VERSION_MINOR are defined in FindPython3 +set(pyversion python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) set(PYTHON_COMPONENT ${OV_CPACK_COMP_PYTHON_OPENVINO}_${pyversion}) if(OV_GENERATOR_MULTI_CONFIG) diff --git a/src/bindings/python/src/compatibility/openvino/cmake/CythonConfig.cmake b/src/bindings/python/src/compatibility/openvino/cmake/CythonConfig.cmake index 4cc32dacec1375..b27dcbc7e84f2f 100644 --- a/src/bindings/python/src/compatibility/openvino/cmake/CythonConfig.cmake +++ b/src/bindings/python/src/compatibility/openvino/cmake/CythonConfig.cmake @@ -30,21 +30,26 @@ # Use the Cython executable that lives next to the Python executable # if it is a local installation. -find_package(PythonInterp 3 QUIET) -if( PYTHONINTERP_FOUND ) - get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH ) - file(TO_CMAKE_PATH "$ENV{HOME}" ENV_HOME) - find_host_program( CYTHON_EXECUTABLE - NAMES cython cython.bat cython3 - HINTS ${_python_path} ${ENV_HOME}/.local/bin $ENV{HOMEBREW_OPT}/cython/bin - ${ENV_HOME}/Library/Python/${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/bin - ) -else() - find_host_program( CYTHON_EXECUTABLE - NAMES cython cython.bat cython3 - ) -endif() +function( _find_cython_executable ) + find_host_package(Python3 QUIET COMPONENTS Interpreter) + if( Python3_Interpreter_FOUND ) + get_filename_component( _python_path ${Python3_EXECUTABLE} PATH ) + file(TO_CMAKE_PATH "$ENV{HOME}" ENV_HOME) + find_host_program( CYTHON_EXECUTABLE + NAMES cython cython.bat cython3 + HINTS ${_python_path} ${ENV_HOME}/.local/bin $ENV{HOMEBREW_OPT}/cython/bin + ${ENV_HOME}/Library/Python/${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/bin + ) + else() + find_host_program( CYTHON_EXECUTABLE + NAMES cython cython.bat cython3 + ) + endif() + + set(CYTHON_EXECUTABLE "${CYTHON_EXECUTABLE}" PARENT_SCOPE) +endfunction() +_find_cython_executable() include( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE ) diff --git a/src/bindings/python/src/compatibility/openvino/cmake/UseCython.cmake b/src/bindings/python/src/compatibility/openvino/cmake/UseCython.cmake index 6b30c0c96ff688..03a208f03c233f 100644 --- a/src/bindings/python/src/compatibility/openvino/cmake/UseCython.cmake +++ b/src/bindings/python/src/compatibility/openvino/cmake/UseCython.cmake @@ -13,7 +13,7 @@ # # cython_add_module( ... ) # -# To avoid dependence on Python, set the PYTHON_LIBRARY cache variable to point +# To avoid dependence on Python, set the Python3_LIBRARY cache variable to point # to a static library. If a MAIN_MODULE source is specified, # the "if __name__ == '__main__':" from that module is used as the C main() method # for the executable. If MAIN_MODULE, the source with the same basename as @@ -89,7 +89,7 @@ find_package( Cython REQUIRED NO_CMAKE_FIND_ROOT_PATH NO_DEFAULT_PATH ) -find_package(PythonInterp 3 REQUIRED) +find_package(Python3 REQUIRED COMPONENTS Interpreter ${python3_development_component}) set( CYTHON_CXX_EXTENSION "cxx" ) set( CYTHON_C_EXTENSION "c" ) @@ -233,7 +233,7 @@ function( compile_pyx _name generated_file ) set( cython_debug_arg "$<$,$>:--gdb>" ) - if( "${PYTHONLIBS_VERSION_STRING}" MATCHES "^3." ) + if( Python3_VERSION_MAJOR EQUAL 3 ) set( version_arg "-3" ) else() set( version_arg ) @@ -284,16 +284,15 @@ function( cython_add_module _name ) endif() endforeach() compile_pyx( ${_name} generated_file ${pyx_module_sources} ) - python_add_module ( ${_name} ${generated_file} ${other_module_sources} ) - target_include_directories( ${_name} PRIVATE ${PYTHON_INCLUDE_DIRS} ) - if(PYTHON_MODULE_EXTENSION) - set_target_properties(${_name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}") - else() - message(FATAL_ERROR "Internal error: PYTHON_MODULE_EXTENSION is not defined") + python3_add_library ( ${_name} MODULE ${generated_file} ${other_module_sources} ) + # Python3_SOABI is not defined during cross-compilation + if (Python3_SOABI AND NOT PYTHON_MODULE_EXTENSION MATCHES "^\.${Python3_SOABI}.+$") + message(FATAL_ERROR "Python3_SOABI (${Python3_SOABI}) and PYTHON_MODULE_EXTENSION (${PYTHON_MODULE_EXTENSION}) are not matching") endif() + pybind11_extension( ${_name} ) if( APPLE ) set_target_properties( ${_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" ) else() - target_link_libraries( ${_name} PRIVATE ${PYTHON_LIBRARIES} ) + target_link_libraries( ${_name} PRIVATE ${Python3_LIBRARIES} ) endif() endfunction() diff --git a/src/bindings/python/src/compatibility/pyngraph/CMakeLists.txt b/src/bindings/python/src/compatibility/pyngraph/CMakeLists.txt index 0ca34d0230f8af..998c950ff4cc97 100644 --- a/src/bindings/python/src/compatibility/pyngraph/CMakeLists.txt +++ b/src/bindings/python/src/compatibility/pyngraph/CMakeLists.txt @@ -12,8 +12,8 @@ if(NOT DEFINED OpenVINO_SOURCE_DIR) find_package(OpenVINO REQUIRED) endif() -# PYTHON_VERSION_MAJOR and PYTHON_VERSION_MINOR are defined inside pybind11 -set(pyversion python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) +# Python3_VERSION_MAJOR and Python3_VERSION_MINOR are defined in FindPython3 +set(pyversion python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) if(OpenVINO_SOURCE_DIR) if(OV_GENERATOR_MULTI_CONFIG) diff --git a/src/bindings/python/src/openvino/properties/__init__.py b/src/bindings/python/src/openvino/properties/__init__.py index a9fa5a0dac4e93..b611cf3a085b0d 100644 --- a/src/bindings/python/src/openvino/properties/__init__.py +++ b/src/bindings/python/src/openvino/properties/__init__.py @@ -6,25 +6,9 @@ from openvino._pyopenvino.properties import Affinity # Properties -from openvino._pyopenvino.properties import enable_profiling -from openvino._pyopenvino.properties import cache_dir -from openvino._pyopenvino.properties import auto_batch_timeout -from openvino._pyopenvino.properties import num_streams -from openvino._pyopenvino.properties import inference_num_threads -from openvino._pyopenvino.properties import compilation_num_threads -from openvino._pyopenvino.properties import affinity -from openvino._pyopenvino.properties import force_tbb_terminate -from openvino._pyopenvino.properties import enable_mmap -from openvino._pyopenvino.properties import supported_properties -from openvino._pyopenvino.properties import available_devices -from openvino._pyopenvino.properties import model_name -from openvino._pyopenvino.properties import optimal_number_of_infer_requests -from openvino._pyopenvino.properties import range_for_streams -from openvino._pyopenvino.properties import optimal_batch_size -from openvino._pyopenvino.properties import max_batch_size -from openvino._pyopenvino.properties import range_for_async_infer_requests -from openvino._pyopenvino.properties import execution_devices -from openvino._pyopenvino.properties import loaded_from_cache +import openvino._pyopenvino.properties as __properties +from openvino.properties._properties import __make_properties +__make_properties(__properties, __name__) # Submodules from openvino.runtime.properties import hint diff --git a/src/bindings/python/src/openvino/properties/_properties.py b/src/bindings/python/src/openvino/properties/_properties.py new file mode 100644 index 00000000000000..dfabe6a7b4178e --- /dev/null +++ b/src/bindings/python/src/openvino/properties/_properties.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import sys +from types import BuiltinFunctionType, ModuleType +from typing import Callable, Any, Union + + +class Property(str): + """This class allows to make a string object callable. Call returns underlying string's data.""" + def __new__(cls, prop: Callable[..., Any]): # type: ignore + instance = super().__new__(cls, prop()) + instance.prop = prop + return instance + + def __call__(self, *args: Any) -> Callable[..., Any]: + if args is not None: + return self.prop(*args) + return self.prop() + + +def __append_property_to_module(func: Callable[..., Any], target_module_name: str) -> None: + """Modifies the target module's __getattr__ method to expose a python property wrapper by the function's name. + + :param func: the function which will be transformed to behave as python property. + :param target_module_name: the name of the module to which properties are added. + """ + module = sys.modules[target_module_name] + + def base_getattr(name: str) -> None: + raise AttributeError( + f"Module '{module.__name__}' doesn't have the attribute with name '{name}'.") + + getattr_old = getattr(module, "__getattr__", base_getattr) + + def getattr_new(name: str) -> Union[Callable[..., Any], Any]: + if func.__name__ == name: + return Property(func) + else: + return getattr_old(name) + + module.__getattr__ = getattr_new # type: ignore + + +def __make_properties(source_module_of_properties: ModuleType, target_module_name: str) -> None: + """Makes python properties in target module from functions found in the source module. + + :param source_module_of_properties: the source module from which functions should be taken. + :param target_module_name: the name of the module to which properties are added. + """ + for attr in dir(source_module_of_properties): + func = getattr(source_module_of_properties, attr) + if isinstance(func, BuiltinFunctionType): + __append_property_to_module(func, target_module_name) diff --git a/src/bindings/python/src/openvino/properties/device/__init__.py b/src/bindings/python/src/openvino/properties/device/__init__.py index 5729dd101234f3..3fd42834197b24 100644 --- a/src/bindings/python/src/openvino/properties/device/__init__.py +++ b/src/bindings/python/src/openvino/properties/device/__init__.py @@ -6,17 +6,9 @@ from openvino._pyopenvino.properties.device import Type # Properties -from openvino._pyopenvino.properties.device import priorities -from openvino._pyopenvino.properties.device import id -from openvino._pyopenvino.properties.device import full_name -from openvino._pyopenvino.properties.device import architecture -from openvino._pyopenvino.properties.device import type -from openvino._pyopenvino.properties.device import gops -from openvino._pyopenvino.properties.device import thermal -from openvino._pyopenvino.properties.device import capabilities -from openvino._pyopenvino.properties.device import uuid -from openvino._pyopenvino.properties.device import luid -from openvino._pyopenvino.properties.device import properties +import openvino._pyopenvino.properties.device as __device +from openvino.properties._properties import __make_properties +__make_properties(__device, __name__) # Classes from openvino._pyopenvino.properties.device import Capability diff --git a/src/bindings/python/src/openvino/properties/hint/__init__.py b/src/bindings/python/src/openvino/properties/hint/__init__.py index 9b4fdd0d752f8a..b218ee7b2a3e26 100644 --- a/src/bindings/python/src/openvino/properties/hint/__init__.py +++ b/src/bindings/python/src/openvino/properties/hint/__init__.py @@ -9,13 +9,6 @@ from openvino.runtime.properties.hint.overloads import PerformanceMode # Properties -from openvino._pyopenvino.properties.hint import inference_precision -from openvino._pyopenvino.properties.hint import model_priority -from openvino._pyopenvino.properties.hint import performance_mode -from openvino._pyopenvino.properties.hint import enable_cpu_pinning -from openvino._pyopenvino.properties.hint import scheduling_core_type -from openvino._pyopenvino.properties.hint import enable_hyper_threading -from openvino._pyopenvino.properties.hint import execution_mode -from openvino._pyopenvino.properties.hint import num_requests -from openvino._pyopenvino.properties.hint import model -from openvino._pyopenvino.properties.hint import allow_auto_batching +import openvino._pyopenvino.properties.hint as __hint +from openvino.properties._properties import __make_properties +__make_properties(__hint, __name__) diff --git a/src/bindings/python/src/openvino/properties/intel_auto/__init__.py b/src/bindings/python/src/openvino/properties/intel_auto/__init__.py index a9a7e450794638..2d8a52ac10920f 100644 --- a/src/bindings/python/src/openvino/properties/intel_auto/__init__.py +++ b/src/bindings/python/src/openvino/properties/intel_auto/__init__.py @@ -2,6 +2,7 @@ # Copyright (C) 2018-2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -from openvino._pyopenvino.properties.intel_auto import device_bind_buffer -from openvino._pyopenvino.properties.intel_auto import enable_startup_fallback -from openvino._pyopenvino.properties.intel_auto import enable_runtime_fallback +# Properties +import openvino._pyopenvino.properties.intel_auto as __intel_auto +from openvino.properties._properties import __make_properties +__make_properties(__intel_auto, __name__) diff --git a/src/bindings/python/src/openvino/properties/intel_cpu/__init__.py b/src/bindings/python/src/openvino/properties/intel_cpu/__init__.py index 2b947dc960e809..7b13195261ed65 100644 --- a/src/bindings/python/src/openvino/properties/intel_cpu/__init__.py +++ b/src/bindings/python/src/openvino/properties/intel_cpu/__init__.py @@ -2,5 +2,7 @@ # Copyright (C) 2018-2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -from openvino._pyopenvino.properties.intel_cpu import denormals_optimization -from openvino._pyopenvino.properties.intel_cpu import sparse_weights_decompression_rate +# Properties +import openvino._pyopenvino.properties.intel_cpu as __intel_cpu +from openvino.properties._properties import __make_properties +__make_properties(__intel_cpu, __name__) diff --git a/src/bindings/python/src/openvino/properties/intel_gpu/__init__.py b/src/bindings/python/src/openvino/properties/intel_gpu/__init__.py index 0cfa6dde23d7e3..6cb43927241a40 100644 --- a/src/bindings/python/src/openvino/properties/intel_gpu/__init__.py +++ b/src/bindings/python/src/openvino/properties/intel_gpu/__init__.py @@ -3,12 +3,9 @@ # SPDX-License-Identifier: Apache-2.0 # Properties -from openvino._pyopenvino.properties.intel_gpu import device_total_mem_size -from openvino._pyopenvino.properties.intel_gpu import uarch_version -from openvino._pyopenvino.properties.intel_gpu import execution_units_count -from openvino._pyopenvino.properties.intel_gpu import memory_statistics -from openvino._pyopenvino.properties.intel_gpu import enable_loop_unrolling -from openvino._pyopenvino.properties.intel_gpu import disable_winograd_convolution +import openvino._pyopenvino.properties.intel_gpu as __intel_gpu +from openvino.properties._properties import __make_properties +__make_properties(__intel_gpu, __name__) # Classes from openvino._pyopenvino.properties.intel_gpu import MemoryType diff --git a/src/bindings/python/src/openvino/properties/intel_gpu/hint/__init__.py b/src/bindings/python/src/openvino/properties/intel_gpu/hint/__init__.py index 78b18bdf477be5..af54a90c6e69f9 100644 --- a/src/bindings/python/src/openvino/properties/intel_gpu/hint/__init__.py +++ b/src/bindings/python/src/openvino/properties/intel_gpu/hint/__init__.py @@ -3,10 +3,9 @@ # SPDX-License-Identifier: Apache-2.0 # Properties -from openvino._pyopenvino.properties.intel_gpu.hint import queue_throttle -from openvino._pyopenvino.properties.intel_gpu.hint import queue_priority -from openvino._pyopenvino.properties.intel_gpu.hint import host_task_priority -from openvino._pyopenvino.properties.intel_gpu.hint import available_device_mem +import openvino._pyopenvino.properties.intel_gpu.hint as __hint +from openvino.properties._properties import __make_properties +__make_properties(__hint, __name__) # Classes from openvino._pyopenvino.properties.intel_gpu.hint import ThrottleLevel diff --git a/src/bindings/python/src/openvino/properties/log/__init__.py b/src/bindings/python/src/openvino/properties/log/__init__.py index bf29a7a70e71ac..9295f5b11fa5f3 100644 --- a/src/bindings/python/src/openvino/properties/log/__init__.py +++ b/src/bindings/python/src/openvino/properties/log/__init__.py @@ -6,4 +6,6 @@ from openvino._pyopenvino.properties.log import Level # Properties -from openvino._pyopenvino.properties.log import level +import openvino._pyopenvino.properties.log as __log +from openvino.properties._properties import __make_properties +__make_properties(__log, __name__) diff --git a/src/bindings/python/src/openvino/properties/streams/__init__.py b/src/bindings/python/src/openvino/properties/streams/__init__.py index e1ce0b19044f57..457d6c88f706be 100644 --- a/src/bindings/python/src/openvino/properties/streams/__init__.py +++ b/src/bindings/python/src/openvino/properties/streams/__init__.py @@ -2,8 +2,10 @@ # Copyright (C) 2018-2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -# Properties -from openvino._pyopenvino.properties.streams import num - # Classes from openvino._pyopenvino.properties.streams import Num + +# Properties +import openvino._pyopenvino.properties.streams as __streams +from openvino.properties._properties import __make_properties +__make_properties(__streams, __name__) diff --git a/src/bindings/python/src/pyopenvino/CMakeLists.txt b/src/bindings/python/src/pyopenvino/CMakeLists.txt index c3b5ddad46544b..977a970e8095f2 100644 --- a/src/bindings/python/src/pyopenvino/CMakeLists.txt +++ b/src/bindings/python/src/pyopenvino/CMakeLists.txt @@ -7,8 +7,8 @@ if(NOT DEFINED OpenVINO_SOURCE_DIR) find_package(OpenVINODeveloperPackage REQUIRED) endif() -# PYTHON_VERSION_MAJOR and PYTHON_VERSION_MINOR are defined inside pybind11 -set(pyversion python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) +# Python3_VERSION_MAJOR and Python3_VERSION_MINOR are defined by FindPython3 +set(pyversion python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) if(OpenVINO_SOURCE_DIR) if(OV_GENERATOR_MULTI_CONFIG) diff --git a/src/bindings/python/tests/test_runtime/test_properties.py b/src/bindings/python/tests/test_runtime/test_properties.py index e11afaf5a844c7..cb70887fb19055 100644 --- a/src/bindings/python/tests/test_runtime/test_properties.py +++ b/src/bindings/python/tests/test_runtime/test_properties.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- -# Copyright (C) 2022 Intel Corporation +# Copyright (C) 2018-2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 import pytest import numpy as np import os +import openvino as ov import openvino.properties as props import openvino.properties.hint as hints import openvino.properties.intel_cpu as intel_cpu @@ -28,7 +29,7 @@ def test_properties_ro_base(): def test_properties_rw_base(): - assert props.cache_dir() == "CACHE_DIR" + assert ov.properties.cache_dir == "CACHE_DIR" assert props.cache_dir("./test_dir") == ("CACHE_DIR", OVAny("./test_dir")) with pytest.raises(TypeError) as e: @@ -181,6 +182,7 @@ def test_conflicting_enum(proxy_enums, expected_values): def test_properties_ro(ov_property_ro, expected_value): # Test if property is correctly registered assert ov_property_ro() == expected_value + assert ov_property_ro == expected_value ### @@ -369,6 +371,7 @@ def test_properties_ro(ov_property_ro, expected_value): def test_properties_rw(ov_property_rw, expected_value, test_values): # Test if property is correctly registered assert ov_property_rw() == expected_value + assert ov_property_rw == expected_value # Test if property process values correctly for values in test_values: @@ -381,7 +384,7 @@ def test_properties_rw(ov_property_rw, expected_value, test_values): # Special cases ### def test_properties_device_priorities(): - assert device.priorities() == "MULTI_DEVICE_PRIORITIES" + assert device.priorities == "MULTI_DEVICE_PRIORITIES" assert device.priorities("CPU,GPU") == ("MULTI_DEVICE_PRIORITIES", OVAny("CPU,GPU,")) assert device.priorities("CPU", "GPU") == ("MULTI_DEVICE_PRIORITIES", OVAny("CPU,GPU,")) @@ -401,7 +404,7 @@ def make_dict(*arg): def check(value1, value2): assert device.properties(value1) == ("DEVICE_PROPERTIES", OVAny(value2)) - check({"CPU": {streams.num(): 2}}, + check({"CPU": {streams.num: 2}}, {"CPU": {"NUM_STREAMS": 2}}) check({"CPU": make_dict(streams.num(2))}, {"CPU": {"NUM_STREAMS": streams.Num(2)}}) @@ -457,7 +460,7 @@ def test_properties_hint_model(): model = generate_add_model() - assert hints.model() == "MODEL_PTR" + assert hints.model == "MODEL_PTR" property_tuple = hints.model(model) assert property_tuple[0] == "MODEL_PTR" @@ -468,7 +471,7 @@ def test_single_property_setting(device): core.set_property(device, streams.num(streams.Num.AUTO)) - assert streams.Num.AUTO.to_integer() == -1 + assert props.streams.Num.AUTO.to_integer() == -1 assert type(core.get_property(device, streams.num())) == int @@ -494,28 +497,28 @@ def test_single_property_setting(device): ), # Pure dict { - props.enable_profiling(): True, - props.cache_dir(): "./", - props.inference_num_threads(): 9, - props.affinity(): props.Affinity.NONE, - hints.inference_precision(): Type.f32, - hints.performance_mode(): hints.PerformanceMode.LATENCY, - hints.enable_cpu_pinning(): True, - hints.scheduling_core_type(): hints.SchedulingCoreType.PCORE_ONLY, - hints.enable_hyper_threading(): True, - hints.num_requests(): 12, - streams.num(): 5, + props.enable_profiling: True, + props.cache_dir: "./", + props.inference_num_threads: 9, + props.affinity: props.Affinity.NONE, + hints.inference_precision: Type.f32, + hints.performance_mode: hints.PerformanceMode.LATENCY, + hints.enable_cpu_pinning: True, + hints.scheduling_core_type: hints.SchedulingCoreType.PCORE_ONLY, + hints.enable_hyper_threading: True, + hints.num_requests: 12, + streams.num: 5, }, # Mixed dict { - props.enable_profiling(): True, + props.enable_profiling: True, "CACHE_DIR": "./", - props.inference_num_threads(): 9, - props.affinity(): "NONE", + props.inference_num_threads: 9, + props.affinity: "NONE", "INFERENCE_PRECISION_HINT": Type.f32, - hints.performance_mode(): hints.PerformanceMode.LATENCY, - hints.scheduling_core_type(): hints.SchedulingCoreType.PCORE_ONLY, - hints.num_requests(): 12, + hints.performance_mode: hints.PerformanceMode.LATENCY, + hints.scheduling_core_type: hints.SchedulingCoreType.PCORE_ONLY, + hints.num_requests: 12, "NUM_STREAMS": streams.Num(5), "ENABLE_MMAP": "NO", }, @@ -526,21 +529,20 @@ def test_core_cpu_properties(properties_to_set): if "Intel" not in core.get_property("CPU", "FULL_DEVICE_NAME"): pytest.skip("This test runs only on openvino intel cpu plugin") - core.set_property(properties_to_set) # RW properties - assert core.get_property("CPU", props.enable_profiling()) is True - assert core.get_property("CPU", props.cache_dir()) == "./" - assert core.get_property("CPU", props.inference_num_threads()) == 9 - assert core.get_property("CPU", props.affinity()) == props.Affinity.NONE - assert core.get_property("CPU", streams.num()) == 5 + assert core.get_property("CPU", props.enable_profiling) is True + assert core.get_property("CPU", props.cache_dir) == "./" + assert core.get_property("CPU", props.inference_num_threads) == 9 + assert core.get_property("CPU", props.affinity) == props.Affinity.NONE + assert core.get_property("CPU", streams.num) == 5 # RO properties - assert type(core.get_property("CPU", props.supported_properties())) == dict - assert type(core.get_property("CPU", props.available_devices())) == list - assert type(core.get_property("CPU", props.optimal_number_of_infer_requests())) == int - assert type(core.get_property("CPU", props.range_for_streams())) == tuple - assert type(core.get_property("CPU", props.range_for_async_infer_requests())) == tuple - assert type(core.get_property("CPU", device.full_name())) == str - assert type(core.get_property("CPU", device.capabilities())) == list + assert type(core.get_property("CPU", props.supported_properties)) == dict + assert type(core.get_property("CPU", props.available_devices)) == list + assert type(core.get_property("CPU", props.optimal_number_of_infer_requests)) == int + assert type(core.get_property("CPU", props.range_for_streams)) == tuple + assert type(core.get_property("CPU", props.range_for_async_infer_requests)) == tuple + assert type(core.get_property("CPU", device.full_name)) == str + assert type(core.get_property("CPU", device.capabilities)) == list diff --git a/src/bindings/python/wheel/CMakeLists.txt b/src/bindings/python/wheel/CMakeLists.txt index 0641f6f788ddee..d2cc6f348ab679 100644 --- a/src/bindings/python/wheel/CMakeLists.txt +++ b/src/bindings/python/wheel/CMakeLists.txt @@ -6,11 +6,11 @@ # Define proper package name # -execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import wheel.vendored.packaging.tags as tags ; print(f'{tags.interpreter_name()}{tags.interpreter_version()}')" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import wheel.vendored.packaging.tags as tags ; print(f'{tags.interpreter_name()}{tags.interpreter_version()}')" OUTPUT_VARIABLE PYTHON_TAG OUTPUT_STRIP_TRAILING_WHITESPACE) -execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import wheel.bdist_wheel ; print(f'{wheel.bdist_wheel.get_abi_tag()}')" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import wheel.bdist_wheel ; print(f'{wheel.bdist_wheel.get_abi_tag()}')" OUTPUT_VARIABLE ABI_TAG OUTPUT_STRIP_TRAILING_WHITESPACE) -execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import wheel.vendored.packaging.tags as tags ; print(f'{next(tags.platform_tags())}')" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import wheel.vendored.packaging.tags as tags ; print(f'{next(tags.platform_tags())}')" OUTPUT_VARIABLE PLATFORM_TAG OUTPUT_STRIP_TRAILING_WHITESPACE) # defines wheel architecture part of `PLATFORM_TAG` @@ -81,7 +81,7 @@ set(openvino_wheel_path "${openvino_wheels_output_dir}/${openvino_wheel_name}") # create target for openvino.wheel # -execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip --version +execute_process(COMMAND ${Python3_EXECUTABLE} -m pip --version OUTPUT_VARIABLE pip_version OUTPUT_STRIP_TRAILING_WHITESPACE) string(REGEX MATCH "pip[ ]+([\\.0-9]*)" pip_version "${pip_version}") @@ -89,7 +89,7 @@ set(pip_version ${CMAKE_MATCH_1}) if(pip_version VERSION_GREATER_EQUAL 22.0) set(wheel_build_command - ${PYTHON_EXECUTABLE} -m pip wheel + ${Python3_EXECUTABLE} -m pip wheel --no-deps --wheel-dir ${openvino_wheels_output_dir} # --verbose @@ -98,7 +98,7 @@ if(pip_version VERSION_GREATER_EQUAL 22.0) "${CMAKE_CURRENT_SOURCE_DIR}") else() set(wheel_build_command - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/setup.py" + ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/setup.py" --quiet --no-user-cfg bdist_wheel @@ -119,7 +119,7 @@ add_custom_command(OUTPUT ${openvino_wheel_path} set(fdupes_report ${CMAKE_CURRENT_BINARY_DIR}/fdupes_report.txt) add_custom_command(OUTPUT "${fdupes_report}" COMMAND ${CMAKE_COMMAND} - -D PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} + -D Python3_EXECUTABLE=${Python3_EXECUTABLE} -D WORKING_DIRECTORY=${CMAKE_CURRENT_BINARY_DIR} -D WHEEL_VERSION=${WHEEL_VERSION} -D PACKAGE_FILE=${openvino_wheel_path} diff --git a/src/bindings/python/wheel/fdupes_check.cmake b/src/bindings/python/wheel/fdupes_check.cmake index 2709b1fdfbf35e..da9e1711dc5d05 100644 --- a/src/bindings/python/wheel/fdupes_check.cmake +++ b/src/bindings/python/wheel/fdupes_check.cmake @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # -foreach(var PYTHON_EXECUTABLE WORKING_DIRECTORY REPORT_FILE WHEEL_VERSION PACKAGE_FILE CMAKE_SHARED_LIBRARY_SUFFIX) +foreach(var Python3_EXECUTABLE WORKING_DIRECTORY REPORT_FILE WHEEL_VERSION PACKAGE_FILE CMAKE_SHARED_LIBRARY_SUFFIX) if(NOT DEFINED ${var}) message(FATAL_ERROR "Variable ${var} is not defined") endif() @@ -20,7 +20,7 @@ endif() get_filename_component(wheel_name "${PACKAGE_FILE}" NAME) -execute_process(COMMAND ${PYTHON_EXECUTABLE} -m wheel unpack ${PACKAGE_FILE} +execute_process(COMMAND ${Python3_EXECUTABLE} -m wheel unpack ${PACKAGE_FILE} WORKING_DIRECTORY ${WORKING_DIRECTORY} OUTPUT_VARIABLE output_message ERROR_VARIABLE error_message diff --git a/src/bindings/python/wheel/setup.py b/src/bindings/python/wheel/setup.py index a6440f3de93a2a..94de22103d3b70 100644 --- a/src/bindings/python/wheel/setup.py +++ b/src/bindings/python/wheel/setup.py @@ -253,7 +253,7 @@ def cmake_build_and_install(self, install_cfg): binary_dir = os.path.join(self.build_temp, binary_dir) self.announce(f"Configuring {comp} cmake project", level=3) self.spawn(["cmake", f"-DOpenVINODeveloperPackage_DIR={OPENVINO_BINARY_DIR}", - f"-DPYTHON_EXECUTABLE={sys.executable}", + f"-DPython3_EXECUTABLE={sys.executable}", f"-DCPACK_GENERATOR={CPACK_GENERATOR}", f"-DCMAKE_BUILD_TYPE={CONFIG}", "-DENABLE_WHEEL=OFF", diff --git a/src/common/conditional_compilation/CMakeLists.txt b/src/common/conditional_compilation/CMakeLists.txt index af732f35fe6181..b0a0f2835fbabc 100644 --- a/src/common/conditional_compilation/CMakeLists.txt +++ b/src/common/conditional_compilation/CMakeLists.txt @@ -20,7 +20,7 @@ elseif(SELECTIVE_BUILD STREQUAL "ON") message(FATAL_ERROR "In case SELECTIVE_BUILD is enabled, the SELECTIVE_BUILD_STAT variable should contain the path to the collected IntelSEAPI statistics.\ Usage: -DSELECTIVE_BUILD=ON -DSELECTIVE_BUILD_STAT=/path/*.csv") endif() - find_package (PythonInterp 3 REQUIRED) + find_host_package (Python3 REQUIRED COMPONENTS Interpreter) file(GLOB STAT_FILES ${SELECTIVE_BUILD_STAT}) @@ -42,7 +42,7 @@ elseif(SELECTIVE_BUILD STREQUAL "ON") set(GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/scripts/ccheader.py) add_custom_command(OUTPUT ${GENERATED_HEADER} - COMMAND ${PYTHON_EXECUTABLE} ${GENERATOR} --stat ${SELECTIVE_BUILD_STAT} --out ${GENERATED_HEADER} + COMMAND ${Python3_EXECUTABLE} ${GENERATOR} --stat ${SELECTIVE_BUILD_STAT} --out ${GENERATED_HEADER} DEPENDS ${STAT_FILES}) add_custom_target(conditional_compilation_gen DEPENDS ${GENERATED_HEADER}) add_dependencies(${TARGET_NAME} conditional_compilation_gen) diff --git a/src/common/transformations/include/transformations/common_optimizations/enable_shapeof_constant_folding.hpp b/src/common/transformations/include/transformations/common_optimizations/enable_shapeof_constant_folding.hpp new file mode 100644 index 00000000000000..1cfb90a77bd48d --- /dev/null +++ b/src/common/transformations/include/transformations/common_optimizations/enable_shapeof_constant_folding.hpp @@ -0,0 +1,25 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/pass/graph_rewrite.hpp" +#include "transformations_visibility.hpp" + +namespace ov { +namespace pass { + +/** + * @ingroup ie_transformation_common_api + * @brief This transformation enables constfoldability for ShapeOf nodes that was + * disabled by DisableShapeOfConstantFolding. + */ +class TRANSFORMATIONS_API EnableShapeOfConstantFolding : public MatcherPass { +public: + OPENVINO_RTTI("EnableShapeOfConstantFolding", "0"); + EnableShapeOfConstantFolding(); +}; + +} // namespace pass +} // namespace ov diff --git a/src/common/transformations/include/transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp b/src/common/transformations/include/transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp index 29d335b0db1c06..7576abfac15e9e 100644 --- a/src/common/transformations/include/transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp +++ b/src/common/transformations/include/transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp @@ -14,6 +14,7 @@ namespace pass { class TRANSFORMATIONS_API EnableDecompressionConvertConstantFolding; class TRANSFORMATIONS_API DisableDecompressionConvertConstantFolding; class TRANSFORMATIONS_API KeepConstAndDecompression; +class TRANSFORMATIONS_API KeepConstantsPrecisionAndAddConverts; } // namespace pass } // namespace ov @@ -47,3 +48,13 @@ class ov::pass::KeepConstAndDecompression : public MatcherPass { OPENVINO_RTTI("KeepConstAndDecompression", "0"); KeepConstAndDecompression(); }; + +/** + * @ingroup ie_transformation_common_api + * @brief Prevents Consts precision conversion and adds Convert with disabled ConstantFolding + */ +class ov::pass::KeepConstantsPrecisionAndAddConverts : public MatcherPass { +public: + OPENVINO_RTTI("KeepConstantsPrecisionAndAddConverts", "0"); + KeepConstantsPrecisionAndAddConverts(); +}; diff --git a/src/common/transformations/include/transformations/rt_info/keep_const_precision.hpp b/src/common/transformations/include/transformations/rt_info/keep_const_precision.hpp new file mode 100644 index 00000000000000..af9d7002387410 --- /dev/null +++ b/src/common/transformations/include/transformations/rt_info/keep_const_precision.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/node.hpp" +#include "openvino/core/runtime_attribute.hpp" +#include "transformations_visibility.hpp" + +namespace ov { + +TRANSFORMATIONS_API void enable_keep_const_precision(const std::shared_ptr& node); + +TRANSFORMATIONS_API void disable_keep_const_precision(const std::shared_ptr& node); + +TRANSFORMATIONS_API bool is_keep_const_precision(const std::shared_ptr& node); + +/** + * @ingroup ie_runtime_attr_api + * @brief KeepConstPrecision class represents runtime info attribute that marks a Constant + * as prohibitted to fuse precision in ConvertPrecision + */ +class TRANSFORMATIONS_API KeepConstPrecision : public RuntimeAttribute { +public: + OPENVINO_RTTI("keep_const_precision", "0"); + + KeepConstPrecision() = default; + + bool is_copyable() const override { + return false; + } +}; + +} // namespace ov diff --git a/src/common/transformations/include/transformations/rt_info/keep_fp16_const.hpp b/src/common/transformations/include/transformations/rt_info/keep_fp16_const.hpp deleted file mode 100644 index f38ca72f9a03a6..00000000000000 --- a/src/common/transformations/include/transformations/rt_info/keep_fp16_const.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include "openvino/core/node.hpp" -#include "openvino/core/runtime_attribute.hpp" -#include "transformations_visibility.hpp" - -namespace ov { - -TRANSFORMATIONS_API void enable_keep_fp16_const(const std::shared_ptr& node); - -TRANSFORMATIONS_API void disable_keep_fp16_const(const std::shared_ptr& node); - -TRANSFORMATIONS_API bool is_keep_fp16_const(const std::shared_ptr& node); - -/** - * @ingroup ie_runtime_attr_api - * @brief DisableFP16Compression class represents runtime info attribute that marks operation - * as prohibitted to convert to FP16 as part of Compressed Only format. - */ -class TRANSFORMATIONS_API KeepFP16Const : public RuntimeAttribute { -public: - OPENVINO_RTTI("keep_fp16_const", "0"); - - KeepFP16Const() = default; - - bool is_copyable() const override { - return false; - } -}; - -} // namespace ov diff --git a/src/common/transformations/src/transformations/common_optimizations/enable_shapeof_constant_folding.cpp b/src/common/transformations/src/transformations/common_optimizations/enable_shapeof_constant_folding.cpp new file mode 100644 index 00000000000000..3db1d28f7fcf2a --- /dev/null +++ b/src/common/transformations/src/transformations/common_optimizations/enable_shapeof_constant_folding.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/common_optimizations/enable_shapeof_constant_folding.hpp" + +#include "openvino/op/util/shape_of_base.hpp" +#include "openvino/pass/pattern/op/wrap_type.hpp" +#include "transformations/rt_info/disable_constant_folding.hpp" + +ov::pass::EnableShapeOfConstantFolding::EnableShapeOfConstantFolding() { + auto shape_of = pattern::wrap_type([=](const Output& output) { + const auto& shape = output.get_partial_shape(); + return shape.is_dynamic() || shape_size(shape.get_shape()) != 1; + }); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + enable_constant_folding(m.get_match_root()); + return true; + }; + + auto m = std::make_shared(shape_of, "EnableShapeOfConstantFolding"); + this->register_matcher(m, callback); +} diff --git a/src/common/transformations/src/transformations/control_flow/unroll_if.cpp b/src/common/transformations/src/transformations/control_flow/unroll_if.cpp index 25a35e8c3d1333..d70656b55c6941 100644 --- a/src/common/transformations/src/transformations/control_flow/unroll_if.cpp +++ b/src/common/transformations/src/transformations/control_flow/unroll_if.cpp @@ -42,6 +42,9 @@ bool ov::pass::UnrollIf::run_on_model(const std::shared_ptr& f) { auto body = (cond_value[0]) ? if_node->get_then_body() : if_node->get_else_body(); auto input_descriptions = if_node->get_input_descriptions(static_cast(!cond_value[0])); auto output_descriptions = if_node->get_output_descriptions(static_cast(!cond_value[0])); + // copy rt info before reconnection + for (auto& op : body->get_ops()) + copy_runtime_info({op, if_node}, op); // connect inputs instead of body parameters for (const auto& input_descr : input_descriptions) { @@ -67,7 +70,6 @@ bool ov::pass::UnrollIf::run_on_model(const std::shared_ptr& f) { } is_applicable = true; f->add_sinks(body->get_sinks()); - copy_runtime_info(if_node, body->get_ops()); } return is_applicable; } diff --git a/src/common/transformations/src/transformations/convert_precision.cpp b/src/common/transformations/src/transformations/convert_precision.cpp index 65387086310830..c5e2b13381c9f6 100644 --- a/src/common/transformations/src/transformations/convert_precision.cpp +++ b/src/common/transformations/src/transformations/convert_precision.cpp @@ -26,7 +26,7 @@ #include "transformations/fp16_compression/mark_subgraphs_to_keep_in_mixed_precision.hpp" #include "transformations/rt_info/decompression.hpp" #include "transformations/rt_info/disable_fp16_compression.hpp" -#include "transformations/rt_info/keep_fp16_const.hpp" +#include "transformations/rt_info/keep_const_precision.hpp" #include "transformations/utils/utils.hpp" using namespace ov; @@ -1125,8 +1125,8 @@ std::shared_ptr convert_low_precisions_int(std::shared_ptr& node, const precisions_map& precisions, const std::vector>& consumers) { - // Consts marked with disable_constant_folding should be kept in f16 until they reach the plugin - if (is_keep_fp16_const(node)) + // Consts marked with is_keep_const_precision should be kept in their own precision until they reach the plugin + if (is_keep_const_precision(node)) return false; auto from = node->get_element_type(); diff --git a/src/common/transformations/src/transformations/fp16_compression/mark_decompression_convert_constant_folding.cpp b/src/common/transformations/src/transformations/fp16_compression/mark_decompression_convert_constant_folding.cpp index de03d931ac47cc..26505dee5278b8 100644 --- a/src/common/transformations/src/transformations/fp16_compression/mark_decompression_convert_constant_folding.cpp +++ b/src/common/transformations/src/transformations/fp16_compression/mark_decompression_convert_constant_folding.cpp @@ -5,14 +5,16 @@ #include "transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp" #include "itt.hpp" +#include "openvino/core/rt_info.hpp" #include "openvino/op/constant.hpp" #include "openvino/op/convert.hpp" #include "openvino/op/matmul.hpp" #include "openvino/pass/pattern/op/wrap_type.hpp" #include "transformations/rt_info/decompression.hpp" #include "transformations/rt_info/disable_constant_folding.hpp" +#include "transformations/rt_info/disable_fp16_compression.hpp" #include "transformations/rt_info/is_shape_subgraph.hpp" -#include "transformations/rt_info/keep_fp16_const.hpp" +#include "transformations/rt_info/keep_const_precision.hpp" using namespace ov; @@ -67,10 +69,53 @@ pass::KeepConstAndDecompression::KeepConstAndDecompression() { if (!is_type(node->input_value(0).get_node_shared_ptr())) return false; - enable_keep_fp16_const(node->input_value(0).get_node_shared_ptr()); + enable_keep_const_precision(node->input_value(0).get_node_shared_ptr()); return false; }; auto m = std::make_shared(node_pattern, matcher_name); register_matcher(m, callback); } + +pass::KeepConstantsPrecisionAndAddConverts::KeepConstantsPrecisionAndAddConverts() { + MATCHER_SCOPE(KeepConstantsPrecisionAndAddConverts); + auto const_pattern = pattern::wrap_type(); + + matcher_pass_callback callback = [=](pattern::Matcher& m) { + auto const_node = m.get_match_root(); + + if (transformation_callback(const_node)) { + return false; + } + + enable_keep_const_precision(const_node); + + const auto& constant_target_inputs = const_node->get_output_target_inputs(0); + const auto& next_node = constant_target_inputs.begin()->get_node()->shared_from_this(); + if (is_type(next_node)) { + disable_constant_folding(next_node); + if (is_decompression(next_node)) { + unmark_as_decompression(next_node); + } + return true; + } + + auto convert = std::make_shared(const_node, const_node->get_element_type()); + convert->set_friendly_name(const_node->get_friendly_name()); + + std::string postfix = const_node->get_element_type() == ov::element::f32 ? "compression" : "decompression"; + const_node->set_friendly_name(const_node->get_friendly_name() + "_postponed_" + postfix); + + ov::copy_runtime_info(const_node, convert); + disable_constant_folding(convert); + + for (const auto& target_input : constant_target_inputs) { + target_input.replace_source_output(convert); + } + + return true; + }; + + auto m = std::make_shared(const_pattern, matcher_name); + this->register_matcher(m, callback); +} diff --git a/src/common/transformations/src/transformations/rt_info/keep_const_precision.cpp b/src/common/transformations/src/transformations/rt_info/keep_const_precision.cpp new file mode 100644 index 00000000000000..8752631e74b9c2 --- /dev/null +++ b/src/common/transformations/src/transformations/rt_info/keep_const_precision.cpp @@ -0,0 +1,20 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/rt_info/keep_const_precision.hpp" + +void ov::enable_keep_const_precision(const std::shared_ptr& node) { + auto& rt_info = node->get_rt_info(); + rt_info[KeepConstPrecision::get_type_info_static()] = KeepConstPrecision{}; +} + +void ov::disable_keep_const_precision(const std::shared_ptr& node) { + auto& rt_info = node->get_rt_info(); + rt_info.erase(KeepConstPrecision::get_type_info_static()); +} + +bool ov::is_keep_const_precision(const std::shared_ptr& node) { + const auto& rt_info = node->get_rt_info(); + return rt_info.count(KeepConstPrecision::get_type_info_static()); +} diff --git a/src/common/transformations/src/transformations/rt_info/keep_fp16_const.cpp b/src/common/transformations/src/transformations/rt_info/keep_fp16_const.cpp deleted file mode 100644 index 41fce20bd7ed95..00000000000000 --- a/src/common/transformations/src/transformations/rt_info/keep_fp16_const.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "transformations/rt_info/keep_fp16_const.hpp" - -void ov::enable_keep_fp16_const(const std::shared_ptr& node) { - auto& rt_info = node->get_rt_info(); - rt_info[KeepFP16Const::get_type_info_static()] = KeepFP16Const{}; -} - -void ov::disable_keep_fp16_const(const std::shared_ptr& node) { - auto& rt_info = node->get_rt_info(); - rt_info.erase(KeepFP16Const::get_type_info_static()); -} - -bool ov::is_keep_fp16_const(const std::shared_ptr& node) { - const auto& rt_info = node->get_rt_info(); - return rt_info.count(KeepFP16Const::get_type_info_static()); -} diff --git a/src/common/transformations/src/transformations/transpose_sinking/ts_general.cpp b/src/common/transformations/src/transformations/transpose_sinking/ts_general.cpp index ccbef0501f0cf7..4b4a0835a9da70 100644 --- a/src/common/transformations/src/transformations/transpose_sinking/ts_general.cpp +++ b/src/common/transformations/src/transformations/transpose_sinking/ts_general.cpp @@ -10,6 +10,7 @@ #include "openvino/pass/manager.hpp" #include "openvino/pass/pattern/op/wrap_type.hpp" #include "transformations/common_optimizations/disable_shapeof_constant_folding.hpp" +#include "transformations/common_optimizations/enable_shapeof_constant_folding.hpp" #include "transformations/transpose_sinking/ts_binary.hpp" #include "transformations/transpose_sinking/ts_concat.hpp" #include "transformations/transpose_sinking/ts_data_movement.hpp" @@ -77,6 +78,7 @@ bool TSGeneral::run_on_model(const std::shared_ptr& f) { manager.register_pass(); manager.register_pass(); manager.register_pass(); + manager.register_pass(); manager.run_passes(f); } diff --git a/src/common/transformations/tests/common_optimizations/enable_shapeof_constant_folding.cpp b/src/common/transformations/tests/common_optimizations/enable_shapeof_constant_folding.cpp new file mode 100644 index 00000000000000..a771ca7332cf1b --- /dev/null +++ b/src/common/transformations/tests/common_optimizations/enable_shapeof_constant_folding.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "transformations/common_optimizations/enable_shapeof_constant_folding.hpp" + +#include + +#include "common_test_utils/ov_test_utils.hpp" +#include "openvino/core/model.hpp" +#include "openvino/op/abs.hpp" +#include "openvino/op/reshape.hpp" +#include "openvino/op/shape_of.hpp" +#include "openvino/pass/constant_folding.hpp" +#include "openvino/pass/manager.hpp" + +using namespace testing; +using namespace ov; + +TEST_F(TransformationTestsF, EnableShapeOfV0ConstantFolding) { + { + auto data = std::make_shared(element::f32, Shape{1, 4, 10, 10}); + auto shape_of = std::make_shared(data); + pass::disable_constant_folding(shape_of); + auto abs = std::make_shared(shape_of); + auto reshape = std::make_shared(data, abs, false); + model = std::make_shared(reshape, ParameterVector{data}); + + manager.register_pass(); + manager.register_pass(); + } + + { + auto data = std::make_shared(element::f32, Shape{1, 4, 10, 10}); + auto shape = op::v0::Constant::create(element::i64, Shape{4}, {1, 4, 10, 10}); + auto reshape = std::make_shared(data, shape, false); + model_ref = std::make_shared(reshape, ParameterVector{data}); + } +} + +TEST_F(TransformationTestsF, EnableShapeOfV3ConstantFolding) { + { + auto data = std::make_shared(element::f32, Shape{1, 4, 10, 10}); + auto shape_of = std::make_shared(data); + pass::disable_constant_folding(shape_of); + auto abs = std::make_shared(shape_of); + auto reshape = std::make_shared(data, abs, false); + model = std::make_shared(reshape, ParameterVector{data}); + + manager.register_pass(); + manager.register_pass(); + } + + { + auto data = std::make_shared(element::f32, Shape{1, 4, 10, 10}); + auto shape = op::v0::Constant::create(element::i64, Shape{4}, {1, 4, 10, 10}); + auto reshape = std::make_shared(data, shape, false); + model_ref = std::make_shared(reshape, ParameterVector{data}); + } +} diff --git a/src/common/transformations/tests/common_optimizations/keep_constants_precision_and_add_converts_test.cpp b/src/common/transformations/tests/common_optimizations/keep_constants_precision_and_add_converts_test.cpp new file mode 100644 index 00000000000000..ae6076e81c8a4a --- /dev/null +++ b/src/common/transformations/tests/common_optimizations/keep_constants_precision_and_add_converts_test.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "common_test_utils/ov_test_utils.hpp" +#include "openvino/opsets/opset1.hpp" +#include "transformations/convert_precision.hpp" +#include "transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp" +#include "transformations/utils/utils.hpp" + +using namespace testing; +using namespace ov; +using namespace ov::opset1; +using const_node_ptr = const std::shared_ptr; + +TEST_F(TransformationTestsF, KeepConstantsPrecisionAndAddConvertsTestBase) { + { + auto input = std::make_shared(element::f32, Shape{3, 2, 2}); + auto weights = Constant::create(element::f32, Shape{1, 2, 2}, {1}); + auto matmul = std::make_shared(input, weights); + + model = std::make_shared(NodeVector{matmul}, ParameterVector{input}); + + manager.register_pass(); + manager.get_pass_config()->set_callback( + [](const_node_ptr& node) -> bool { + auto next_node = node->get_output_target_inputs(0).begin()->get_node(); + if (is_type(next_node)) { + next_node = next_node->get_output_target_inputs(0).begin()->get_node(); + } + return !is_type(next_node); + }); + + const precisions_map precisions = {{element::f32, element::f16}}; + const type_to_fuse_map empty_fuse_map = {}; + const bool keep_precision_sensitive_in_fp32_1 = true; + manager.register_pass(precisions, empty_fuse_map, keep_precision_sensitive_in_fp32_1); + } + { + auto input = std::make_shared(element::f16, Shape{3, 2, 2}); + auto weights = Constant::create(element::f32, Shape{1, 2, 2}, {1}); + auto convert_weights = std::make_shared(weights, element::f16); + auto matmul = std::make_shared(input, convert_weights); + + model_ref = std::make_shared(NodeVector{matmul}, ParameterVector{input}); + } +} + +TEST_F(TransformationTestsF, KeepConstantsPrecisionAndAddConvertsTestWithCompressedConvert) { + { + auto input = std::make_shared(element::f16, Shape{3, 2, 2}); + auto weights = Constant::create(element::f32, Shape{1, 2, 2}, {1}); + auto convert_weights = std::make_shared(weights, element::f16); + mark_as_decompression(convert_weights); + auto matmul = std::make_shared(input, convert_weights); + + model = std::make_shared(NodeVector{matmul}, ParameterVector{input}); + + manager.register_pass(); + manager.get_pass_config()->set_callback( + [](const_node_ptr& node) -> bool { + auto next_node = node->get_output_target_inputs(0).begin()->get_node(); + if (is_type(next_node)) { + next_node = next_node->get_output_target_inputs(0).begin()->get_node(); + } + return !is_type(next_node); + }); + + const precisions_map precisions = {{element::f32, element::f16}}; + const type_to_fuse_map empty_fuse_map = {}; + const bool keep_precision_sensitive_in_fp32_1 = true; + manager.register_pass(precisions, empty_fuse_map, keep_precision_sensitive_in_fp32_1); + } + { + auto input = std::make_shared(element::f16, Shape{3, 2, 2}); + auto weights = Constant::create(element::f32, Shape{1, 2, 2}, {1}); + auto convert_weights = std::make_shared(weights, element::f16); + auto matmul = std::make_shared(input, convert_weights); + + model_ref = std::make_shared(NodeVector{matmul}, ParameterVector{input}); + } +} diff --git a/src/common/transformations/tests/control_flow/unroll_if_test.cpp b/src/common/transformations/tests/control_flow/unroll_if_test.cpp index 1ffff85410b652..b9e21feb2ee75e 100644 --- a/src/common/transformations/tests/control_flow/unroll_if_test.cpp +++ b/src/common/transformations/tests/control_flow/unroll_if_test.cpp @@ -18,34 +18,51 @@ #include "openvino/op/variadic_split.hpp" #include "openvino/pass/constant_folding.hpp" #include "openvino/pass/manager.hpp" +#include "openvino/util/common_util.hpp" #include "transformations/common_optimizations/push_constant_to_subgraph.hpp" #include "transformations/init_node_info.hpp" +#include "transformations/rt_info/fused_names_attribute.hpp" + using namespace ov; using namespace testing; std::shared_ptr get_then_body() { auto Xt = std::make_shared(ov::element::f32, ov::Shape{3}); + Xt->set_friendly_name("Xt"); auto Yt = std::make_shared(ov::element::f32, ov::Shape{3}); + Yt->set_friendly_name("Yt"); auto add_op = std::make_shared(Xt, Yt); + add_op->set_friendly_name("add_op"); auto then_op_result = std::make_shared(add_op); + then_op_result->set_friendly_name("then_op_result"); auto then_body = std::make_shared(ov::OutputVector{then_op_result}, ov::ParameterVector{Xt, Yt}); + ov::pass::InitNodeInfo().run_on_model(then_body); return then_body; } std::shared_ptr get_else_body() { auto Xe = std::make_shared(ov::element::f32, ov::Shape{3}); + Xe->set_friendly_name("Xe"); auto Ye = std::make_shared(ov::element::f32, ov::Shape{3}); + Ye->set_friendly_name("Ye"); auto mul_op = std::make_shared(Xe, Ye); + mul_op->set_friendly_name("mul_op"); auto else_op_result = std::make_shared(mul_op); + else_op_result->set_friendly_name("else_op_result"); auto else_body = std::make_shared(ov::OutputVector{else_op_result}, ov::ParameterVector{Xe, Ye}); + ov::pass::InitNodeInfo().run_on_model(else_body); return else_body; } std::shared_ptr create_if_model(bool condition) { auto X = std::make_shared(ov::element::f32, ov::Shape{3}); + X->set_friendly_name("X"); auto Y = std::make_shared(ov::element::f32, ov::Shape{3}); + Y->set_friendly_name("y"); auto cond = std::make_shared(ov::element::boolean, ov::Shape{1}, condition); + cond->set_friendly_name("cond"); auto if_op = std::make_shared(cond); + if_op->set_friendly_name("if_op"); const auto& then_body = get_then_body(); const auto& else_body = get_else_body(); @@ -57,6 +74,7 @@ std::shared_ptr create_if_model(bool condition) { if_op->set_input(Y, then_p[1], else_p[1]); if_op->set_output(then_body->get_results()[0], else_body->get_results()[0]); auto if_result = std::make_shared(if_op); + if_result->set_friendly_name("if_result"); return std::make_shared(ov::NodeVector{if_result}, ov::ParameterVector{X, Y}); } @@ -78,6 +96,18 @@ TEST(TransformationTests, UnrollIfCondIsTrue) { auto res = compare_functions(f, f_ref); ASSERT_TRUE(res.first) << res.second; + + for (auto& op : f->get_ops()) { + std::vector fused_names = ov::getFusedNamesVector(op); + if (ov::is_type(op)) { + ASSERT_EQ(2, fused_names.size()); + ASSERT_TRUE(ov::util::contains(fused_names, "add_op")); + ASSERT_TRUE(ov::util::contains(fused_names, "if_op")); + } else { + ASSERT_EQ(1, fused_names.size()); + ASSERT_TRUE(!ov::util::contains(fused_names, "if_op")); + } + } } TEST(TransformationTests, UnrollIfCondIsFalse) { @@ -97,6 +127,18 @@ TEST(TransformationTests, UnrollIfCondIsFalse) { auto res = compare_functions(f, f_ref); ASSERT_TRUE(res.first) << res.second; + + for (auto& op : f->get_ops()) { + std::vector fused_names = ov::getFusedNamesVector(op); + if (ov::is_type(op)) { + ASSERT_EQ(2, fused_names.size()); + ASSERT_TRUE(ov::util::contains(fused_names, "mul_op")); + ASSERT_TRUE(ov::util::contains(fused_names, "if_op")); + } else { + ASSERT_EQ(1, fused_names.size()); + ASSERT_TRUE(!ov::util::contains(fused_names, "if_op")); + } + } } TEST(TransformationTests, UnrollIfWithSplitInput) { diff --git a/src/core/docs/tests.md b/src/core/docs/tests.md index 34e487ad8e37de..5442193563c893 100644 --- a/src/core/docs/tests.md +++ b/src/core/docs/tests.md @@ -11,8 +11,6 @@ OpenVINO Core [tests](../tests/) have next structure: * `type_prop` - type and shape propagation tests * `visitors` - tests covers visitor API for all supported operations -These tests can be disabled by CMake option `ENABLE_OV_CORE_UNIT_TESTS`, this option by default has the same value as `ENABLE_TESTS` option. - ## See also * [OpenVINOâ„¢ Core README](../README.md) * [OpenVINOâ„¢ README](../../../README.md) diff --git a/src/core/include/openvino/op/reduce_logical_and.hpp b/src/core/include/openvino/op/reduce_logical_and.hpp index 1358702a1fd39a..2fb2341a8c3d22 100644 --- a/src/core/include/openvino/op/reduce_logical_and.hpp +++ b/src/core/include/openvino/op/reduce_logical_and.hpp @@ -28,9 +28,7 @@ class OPENVINO_API ReduceLogicalAnd : public util::LogicalReductionKeepDims { std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; - OPENVINO_SUPPRESS_DEPRECATED_START - bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; - OPENVINO_SUPPRESS_DEPRECATED_END + bool evaluate(TensorVector& outputs, const TensorVector& inputs) const override; bool has_evaluate() const override; }; } // namespace v1 diff --git a/src/core/include/openvino/op/reduce_logical_or.hpp b/src/core/include/openvino/op/reduce_logical_or.hpp index 36a3fd34759b24..6d61e2f0a8ae07 100644 --- a/src/core/include/openvino/op/reduce_logical_or.hpp +++ b/src/core/include/openvino/op/reduce_logical_or.hpp @@ -28,9 +28,7 @@ class OPENVINO_API ReduceLogicalOr : public util::LogicalReductionKeepDims { std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; - OPENVINO_SUPPRESS_DEPRECATED_START - bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; - OPENVINO_SUPPRESS_DEPRECATED_END + bool evaluate(TensorVector& outputs, const TensorVector& inputs) const override; bool has_evaluate() const override; }; } // namespace v1 diff --git a/src/core/reference/include/openvino/reference/logical_reduction.hpp b/src/core/reference/include/openvino/reference/logical_reduction.hpp index 7fd88db5eaa8cb..97be74d112285a 100644 --- a/src/core/reference/include/openvino/reference/logical_reduction.hpp +++ b/src/core/reference/include/openvino/reference/logical_reduction.hpp @@ -8,54 +8,66 @@ #include #include "ngraph/shape_util.hpp" +#include "openvino/core/shape_util.hpp" +#include "openvino/reference/utils/coordinate_index.hpp" #include "openvino/reference/utils/coordinate_transform.hpp" namespace ov { namespace reference { -OPENVINO_SUPPRESS_DEPRECATED_START + +/** + * @brief Reference implementation of ReduceLogicalAnd operator. + * + * @param in Input pointer to data. + * @param out Output pointer to results. + * @param in_shape Input shape. + * @param reduction_axes Axes on which reduction is applied. + */ static inline void reduce_logical_and(const char* arg, char* out, const Shape& in_shape, const AxisSet& reduction_axes) { - constexpr bool dont_keep_dims_in_output = false; - const auto out_shape = ngraph::reduce(in_shape, reduction_axes, dont_keep_dims_in_output); + const auto out_shape = ov::util::reduce(in_shape, reduction_axes); std::fill(out, out + shape_size(out_shape), 1); const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); CoordinateTransformBasic input_transform(in_shape); - for (const Coordinate& input_coord : input_transform) { - const Coordinate output_coord = ngraph::reduce(input_coord, reduction_axes, dont_keep_dims_in_output); + for (const auto& in_coord : input_transform) { + const auto out_coord = ov::util::reduce(in_coord, reduction_axes); - const size_t in_idx = - std::inner_product(input_coord.begin(), input_coord.end(), in_strides.begin(), uint64_t(0)); - const size_t out_idx = - std::inner_product(output_coord.begin(), output_coord.end(), out_strides.begin(), uint64_t(0)); + const auto in_idx = ov::coordinate_offset(in_coord, in_strides); + const auto out_idx = ov::coordinate_offset(out_coord, out_strides); out[out_idx] = out[out_idx] && arg[in_idx]; } } +/** + * @brief Reference implementation of ReduceLogicalOr operator. + * + * @param in Input pointer to data. + * @param out Output pointer to results. + * @param in_shape Input shape. + * @param reduction_axes Axes on which reduction is applied. + */ static inline void reduce_logical_or(const char* arg, char* out, const Shape& in_shape, const AxisSet& reduction_axes) { - const auto out_shape = ngraph::reduce(in_shape, reduction_axes, false); + const auto out_shape = ov::util::reduce(in_shape, reduction_axes); std::fill(out, out + shape_size(out_shape), 0); const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); CoordinateTransformBasic input_transform(in_shape); - for (const Coordinate& input_coord : input_transform) { - const Coordinate output_coord = ngraph::reduce(input_coord, reduction_axes, false); + for (const auto& in_coord : input_transform) { + const auto out_coord = ov::util::reduce(in_coord, reduction_axes); - const size_t in_idx = - std::inner_product(input_coord.begin(), input_coord.end(), in_strides.begin(), uint64_t(0)); - const size_t out_idx = - std::inner_product(output_coord.begin(), output_coord.end(), out_strides.begin(), uint64_t(0)); + const auto in_idx = ov::coordinate_offset(in_coord, in_strides); + const auto out_idx = ov::coordinate_offset(out_coord, out_strides); out[out_idx] = out[out_idx] || arg[in_idx]; } } -OPENVINO_SUPPRESS_DEPRECATED_END } // namespace reference } // namespace ov diff --git a/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp b/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp index 7408e548cdb716..573fa708728074 100644 --- a/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp +++ b/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp @@ -11,4 +11,15 @@ namespace ov { std::size_t coordinate_index(const Coordinate& c, const Shape& s); +/** + * @brief Calculate offset from begin of buffer based on coordinate and strides. + * + * If coordinates and strides have different sizes then result is undefined behaviour. + * + * @param coordinate Vector with multi-dimension coordinates. + * @param strides Vector with multi-dimension strides + * @return Offset of element from start of buffer. + */ +size_t coordinate_offset(const std::vector& coordinate, const std::vector& strides); + } // namespace ov diff --git a/src/core/reference/src/utils/coordinate_index.cpp b/src/core/reference/src/utils/coordinate_index.cpp index a8654d4916918e..72232d62e35425 100644 --- a/src/core/reference/src/utils/coordinate_index.cpp +++ b/src/core/reference/src/utils/coordinate_index.cpp @@ -25,4 +25,8 @@ std::size_t coordinate_index(const Coordinate& c, const Shape& s) { return index; } + +size_t coordinate_offset(const std::vector& coordinate, const std::vector& strides) { + return std::inner_product(coordinate.cbegin(), coordinate.cend(), strides.cbegin(), static_cast(0)); +} } // namespace ov diff --git a/src/core/src/op/reduce_logical_and.cpp b/src/core/src/op/reduce_logical_and.cpp index 6ca1444fd90c08..adcfed43626306 100644 --- a/src/core/src/op/reduce_logical_and.cpp +++ b/src/core/src/op/reduce_logical_and.cpp @@ -2,76 +2,61 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "ngraph/op/reduce_logical_and.hpp" - -#include +#include "openvino/op/reduce_logical_and.hpp" +#include "element_visitor.hpp" #include "itt.hpp" -#include "ngraph/log.hpp" -#include "ngraph/op/util/evaluate_helpers.hpp" -#include "ngraph/runtime/host_tensor.hpp" +#include "openvino/core/shape_util.hpp" +#include "openvino/op/util/axes_util.hpp" #include "openvino/reference/logical_reduction.hpp" -#include "openvino/util/log.hpp" -using namespace ngraph; -using namespace std; +namespace ov { +namespace op { +namespace reduce_and { +struct Evaluate : element::NoAction { + using element::NoAction::visit; + + template + static result_type visit(const Tensor& in, Tensor& out, const AxisSet& reduction_axes) { + using T = fundamental_type_for; + reference::reduce_logical_and(in.data(), out.data(), in.get_shape(), reduction_axes); + return true; + } +}; +} // namespace reduce_and -op::v1::ReduceLogicalAnd::ReduceLogicalAnd(const Output& data, - const Output& reduction_axes, - const bool keep_dims) +namespace v1 { +ReduceLogicalAnd::ReduceLogicalAnd(const Output& data, const Output& reduction_axes, const bool keep_dims) : LogicalReductionKeepDims(data, reduction_axes, keep_dims) { constructor_validate_and_infer_types(); } -shared_ptr op::v1::ReduceLogicalAnd::clone_with_new_inputs(const OutputVector& new_args) const { +std::shared_ptr ReduceLogicalAnd::clone_with_new_inputs(const OutputVector& new_args) const { OV_OP_SCOPE(v1_ReduceLogicalAnd_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); + return std::make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); } -OPENVINO_SUPPRESS_DEPRECATED_START -namespace reduce_and { -namespace { -bool evaluate_reduce_logical_and(const HostTensorPtr& data, - const HostTensorPtr& out, - const AxisSet& reduction_axes, - bool keep_dims) { - OPENVINO_SUPPRESS_DEPRECATED_START - out->set_shape(reduce(data->get_shape(), reduction_axes, keep_dims)); - try { - ov::reference::reduce_logical_and(data->get_data_ptr(), - out->get_data_ptr(), - data->get_shape(), - reduction_axes); - return true; - } catch (const ngraph_error& e) { - OPENVINO_WARN << e.what(); - return false; - } - OPENVINO_SUPPRESS_DEPRECATED_END -} -} // namespace -} // namespace reduce_and - -bool op::v1::ReduceLogicalAnd::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { +bool ReduceLogicalAnd::evaluate(TensorVector& outputs, const TensorVector& inputs) const { OV_OP_SCOPE(v1_ReduceLogicalAnd_evaluate); OPENVINO_SUPPRESS_DEPRECATED_START - OPENVINO_ASSERT(validate_host_tensor_vector(inputs, 2)); - OPENVINO_ASSERT(validate_host_tensor_vector(outputs, 1)); + OPENVINO_ASSERT(inputs.size() == 2); + OPENVINO_ASSERT(outputs.size() == 1); - const auto& data = inputs[0]; - const auto& axes = inputs[1]; - const auto& out = outputs[0]; - if (data->get_element_type() != element::boolean || !axes->get_element_type().is_integral_number()) { - return false; - } - const auto reduction_axes = - get_normalized_axes_from_tensor(axes, data->get_partial_shape().rank(), get_friendly_name()); - OPENVINO_SUPPRESS_DEPRECATED_END - return reduce_and::evaluate_reduce_logical_and(data, out, reduction_axes, get_keep_dims()); + const auto reduction_axes = get_normalized_axes_from_tensor(this, inputs[1], inputs[0].get_shape().size()); + outputs[0].set_shape(ov::util::reduce(inputs[0].get_shape(), reduction_axes, get_keep_dims())); + + using namespace ov::element; + return IfTypeOf::apply(inputs[0].get_element_type(), + inputs[0], + outputs[0], + reduction_axes); } -bool op::v1::ReduceLogicalAnd::has_evaluate() const { +bool ReduceLogicalAnd::has_evaluate() const { OV_OP_SCOPE(v1_ReduceLogicalAnd_has_evaluate); return get_input_element_type(0) == element::boolean && get_input_element_type(1).is_integral_number(); } +} // namespace v1 +} // namespace op +} // namespace ov diff --git a/src/core/src/op/reduce_logical_or.cpp b/src/core/src/op/reduce_logical_or.cpp index dce03e81e40ce0..a2e84d420e606d 100644 --- a/src/core/src/op/reduce_logical_or.cpp +++ b/src/core/src/op/reduce_logical_or.cpp @@ -2,76 +2,63 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "ngraph/op/reduce_logical_or.hpp" - -#include +#include "openvino/op/reduce_logical_or.hpp" +#include "element_visitor.hpp" #include "itt.hpp" -#include "ngraph/log.hpp" -#include "ngraph/op/util/evaluate_helpers.hpp" -#include "ngraph/runtime/host_tensor.hpp" +#include "openvino/core/shape_util.hpp" +#include "openvino/op/util/axes_util.hpp" #include "openvino/reference/logical_reduction.hpp" #include "openvino/util/log.hpp" -using namespace ngraph; -using namespace std; +namespace ov { +namespace op { +namespace reduce_or { +struct Evaluate : element::NoAction { + using element::NoAction::visit; + + template + static result_type visit(const Tensor& in, Tensor& out, const AxisSet& reduction_axes) { + using T = fundamental_type_for; + reference::reduce_logical_or(in.data(), out.data(), in.get_shape(), reduction_axes); + return true; + } +}; +} // namespace reduce_or -op::v1::ReduceLogicalOr::ReduceLogicalOr(const Output& data, - const Output& reduction_axes, - const bool keep_dims) +namespace v1 { +ReduceLogicalOr::ReduceLogicalOr(const Output& data, const Output& reduction_axes, const bool keep_dims) : LogicalReductionKeepDims(data, reduction_axes, keep_dims) { constructor_validate_and_infer_types(); } -shared_ptr op::v1::ReduceLogicalOr::clone_with_new_inputs(const OutputVector& new_args) const { +std::shared_ptr ReduceLogicalOr::clone_with_new_inputs(const OutputVector& new_args) const { OV_OP_SCOPE(v1_ReduceLogicalOr_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); -} - -OPENVINO_SUPPRESS_DEPRECATED_START -namespace reduce_or { -namespace { -bool evaluate_reduce_logical_or(const HostTensorPtr& data, - const HostTensorPtr& out, - const AxisSet& reduction_axes, - bool keep_dims) { - OPENVINO_SUPPRESS_DEPRECATED_START - out->set_shape(reduce(data->get_shape(), reduction_axes, keep_dims)); - try { - ov::reference::reduce_logical_or(data->get_data_ptr(), - out->get_data_ptr(), - data->get_shape(), - reduction_axes); - return true; - } catch (const ngraph_error& e) { - OPENVINO_WARN << e.what(); - return false; - } - OPENVINO_SUPPRESS_DEPRECATED_END + return std::make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); } -} // namespace -} // namespace reduce_or -bool op::v1::ReduceLogicalOr::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { +bool ReduceLogicalOr::evaluate(TensorVector& outputs, const TensorVector& inputs) const { OV_OP_SCOPE(v1_ReduceLogicalOr_evaluate); - OPENVINO_SUPPRESS_DEPRECATED_START - OPENVINO_ASSERT(validate_host_tensor_vector(inputs, 2)); - OPENVINO_ASSERT(validate_host_tensor_vector(outputs, 1)); - const auto& data = inputs[0]; - const auto& axes = inputs[1]; - const auto& out = outputs[0]; - if (data->get_element_type() != element::boolean || !axes->get_element_type().is_integral_number()) { - return false; - } - const auto reduction_axes = - get_normalized_axes_from_tensor(axes, data->get_partial_shape().rank(), get_friendly_name()); - OPENVINO_SUPPRESS_DEPRECATED_END - return reduce_or::evaluate_reduce_logical_or(data, out, reduction_axes, get_keep_dims()); + OPENVINO_ASSERT(inputs.size() == 2); + OPENVINO_ASSERT(outputs.size() == 1); + + const auto reduction_axes = get_normalized_axes_from_tensor(this, inputs[1], inputs[0].get_shape().size()); + outputs[0].set_shape(ov::util::reduce(inputs[0].get_shape(), reduction_axes, get_keep_dims())); + + using namespace ov::element; + return IfTypeOf::apply(inputs[0].get_element_type(), + inputs[0], + outputs[0], + reduction_axes); } -bool op::v1::ReduceLogicalOr::has_evaluate() const { +bool ReduceLogicalOr::has_evaluate() const { OV_OP_SCOPE(v1_ReduceLogicalOr_has_evaluate); return get_input_element_type(0) == element::boolean && get_input_element_type(1).is_integral_number(); } + +} // namespace v1 +} // namespace op +} // namespace ov diff --git a/src/core/src/op/tensor_iterator.cpp b/src/core/src/op/tensor_iterator.cpp index dbee0d02f976e7..03eaf0e837f18e 100644 --- a/src/core/src/op/tensor_iterator.cpp +++ b/src/core/src/op/tensor_iterator.cpp @@ -95,7 +95,7 @@ void op::v0::TensorIterator::validate_and_infer_types() { auto end = make_positive(slice_input_description->m_end, dim_size); // +1 because the left and right borders are included [start, end] - m_num_iterations = (abs(end - start) + 1) / part_size; + m_num_iterations = (std::abs(end - start) + 1) / part_size; } } else { body_parameter->set_partial_shape(ov::PartialShape::dynamic(input_partial_shape.rank())); diff --git a/src/frontends/onnx/docs/tests.md b/src/frontends/onnx/docs/tests.md index 1b75aae45e9f59..6dc6068b2fc2b2 100644 --- a/src/frontends/onnx/docs/tests.md +++ b/src/frontends/onnx/docs/tests.md @@ -23,7 +23,7 @@ For example: ## Pre-steps for all Python tests -1. Build OpenVINO with `-DENABLE_PYTHON=ON`, preferably in a `Python` virtual environment. To avoid problems with too many Python interpreters installed on the host, you can also set the `-DPYTHON_EXECUTABLE=PYTHON_INTERPRETER_PATH` build option. +1. Build OpenVINO with `-DENABLE_PYTHON=ON`, preferably in a `Python` virtual environment. To avoid problems with too many Python interpreters installed on the host, you can also set the `-DPython3_EXECUTABLE=` build option (requires cmake 3.16 and higher). > **NOTE**: If you want to run the tests from the installation directory (like in the CI), add the `-P cmake_install.cmake` and `-DCOMPONENT=tests` CMake build options, and install OpenVINO via `cmake --build . --target install` as additional steps. 2. Set up Python paths via `source /setupvars.sh` for Linux, or `sh \setupvars.bat` for Windows. 3. Install Python dependencies: diff --git a/src/frontends/onnx/tests/CMakeLists.txt b/src/frontends/onnx/tests/CMakeLists.txt index 3a971373d612e1..67462466b9131c 100644 --- a/src/frontends/onnx/tests/CMakeLists.txt +++ b/src/frontends/onnx/tests/CMakeLists.txt @@ -21,7 +21,6 @@ add_compile_definitions( list(APPEND ONNX_TESTS_DEPENDENCIES openvino_template_extension) if (ENABLE_INTEL_CPU) - message(STATUS "ONNX frontend test: IE:CPU enabled") set(ACTIVE_BACKEND_LIST ${ACTIVE_BACKEND_LIST} "IE:CPU") if (ENABLE_STRICT_DEPENDENCIES) # For convinience add a runtime dependency to build along with this target. @@ -31,7 +30,6 @@ if (ENABLE_INTEL_CPU) endif() if (ENABLE_INTEL_GPU) - message(STATUS "ONNX frontend test: IE:GPU enabled") set(ACTIVE_BACKEND_LIST ${ACTIVE_BACKEND_LIST} "IE:GPU") if (ENABLE_STRICT_DEPENDENCIES) # For convinience add a runtime dependency to build along with this target. @@ -41,7 +39,6 @@ if (ENABLE_INTEL_GPU) endif() if (ENABLE_TEMPLATE) - message(STATUS "ONNX frontend test: INTERPRETER enabled") set(ACTIVE_BACKEND_LIST ${ACTIVE_BACKEND_LIST} INTERPRETER) if (ENABLE_STRICT_DEPENDENCIES) list(APPEND ONNX_TESTS_DEPENDENCIES openvino_template_plugin) diff --git a/src/frontends/paddle/tests/CMakeLists.txt b/src/frontends/paddle/tests/CMakeLists.txt index 58b12313d424cf..15f83ba43f9692 100644 --- a/src/frontends/paddle/tests/CMakeLists.txt +++ b/src/frontends/paddle/tests/CMakeLists.txt @@ -26,9 +26,9 @@ ov_add_test_target( # Test model generating set(PADDLE_REQ "${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt") -if(PYTHONINTERP_FOUND) +if(Python3_Interpreter_FOUND) execute_process( - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/paddle_pip_check.py" ${PADDLE_REQ} + COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/paddle_pip_check.py" ${PADDLE_REQ} RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE OUTPUT_TEXT ERROR_VARIABLE ERROR_TEXT) @@ -58,23 +58,15 @@ DownloadAndCheck(${PADDLEDET_OPS_URL} ${PADDLEDET_DIRNAME}/ops.py PADDLEDET_FATA if(paddlepaddle_FOUND AND PADDLEDET_RESULT) set(TEST_PADDLE_MODELS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_PADDLE_MODELS_DIRNAME}/) - if(WIN32) - set(SETENV "set") - set(PATHSEP ";") - else() - set(SETENV "export") - set(PATHSEP ":") - endif() - file(GLOB_RECURSE PADDLE_ALL_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/*.py) set(OUT_FILE ${TEST_PADDLE_MODELS}/generate_done.txt) add_custom_command(OUTPUT ${OUT_FILE} - COMMAND ${SETENV} PYTHONPATH=${PADDLEDET_DIRNAME}${PATHSEP}$ENV{PYTHONPATH} && ${PYTHON_EXECUTABLE} - ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py - ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_scripts - ${TEST_PADDLE_MODELS} - DEPENDS ${PADDLE_ALL_SCRIPTS} - ) + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PADDLEDET_DIRNAME} + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py + ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_scripts + ${TEST_PADDLE_MODELS} + DEPENDS ${PADDLE_ALL_SCRIPTS}) add_custom_target(paddle_test_models DEPENDS ${OUT_FILE}) install(DIRECTORY ${TEST_PADDLE_MODELS} diff --git a/src/frontends/tensorflow/tests/CMakeLists.txt b/src/frontends/tensorflow/tests/CMakeLists.txt index f5f7e5a6817b29..4adb81882c2a42 100644 --- a/src/frontends/tensorflow/tests/CMakeLists.txt +++ b/src/frontends/tensorflow/tests/CMakeLists.txt @@ -53,14 +53,13 @@ if (tensorflow_FOUND) set(OUT_DONE_FILE ${TEST_TENSORFLOW_MODELS}/${FILE_WE}_done.txt) set(OUT_FILES ${OUT_DONE_FILE} ${OUT_FILES}) add_custom_command(OUTPUT ${OUT_DONE_FILE} - COMMAND ${PYTHON_EXECUTABLE} - ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py - ${GEN_SCRIPT} - ${TEST_TENSORFLOW_MODELS} - ${OUT_DONE_FILE} + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py + ${GEN_SCRIPT} + ${TEST_TENSORFLOW_MODELS} + ${OUT_DONE_FILE} JOB_POOL four_jobs - DEPENDS ${TENSORFLOW_ALL_SCRIPTS} - ) + DEPENDS ${TENSORFLOW_ALL_SCRIPTS}) endforeach() add_custom_target(tensorflow_test_models DEPENDS ${OUT_FILES}) diff --git a/src/frontends/tensorflow/tests/compilation.cpp b/src/frontends/tensorflow/tests/compilation.cpp index 29bb77c7805959..fbb6ad94430c55 100644 --- a/src/frontends/tensorflow/tests/compilation.cpp +++ b/src/frontends/tensorflow/tests/compilation.cpp @@ -46,3 +46,24 @@ TEST_F(CompileModelsTests, ModelWithSplitConvConcat) { })); } } + +TEST_F(CompileModelsTests, ModelWithShapeOf) { + auto model = convert_model("shapeof_slice_abs/shapeof_slice_abs.pbtxt"); + ov::Core core; + ov::CompiledModel compiled_model = core.compile_model(model, "CPU"); + const auto runtime_model = compiled_model.get_runtime_model(); + auto get_layer_type = [](const std::shared_ptr& node) { + return node->get_rt_info().at(ExecGraphInfoSerialization::LAYER_TYPE).as(); + }; + const auto ops = runtime_model->get_ops(); + // one Input, one Eltwise and one Output + EXPECT_EQ(3, ops.size()); + // ShapeOf is folded + EXPECT_EQ(0, std::count_if(ops.begin(), ops.end(), [&](const std::shared_ptr& node) { + return get_layer_type(node) == "ShapeOf"; + })); + // Slice is eliminated + EXPECT_EQ(0, std::count_if(ops.begin(), ops.end(), [&](const std::shared_ptr& node) { + return get_layer_type(node) == "StridedSlice"; + })); +} diff --git a/src/frontends/tensorflow/tests/test_models/models_pbtxt/shapeof_slice_abs.pbtxt b/src/frontends/tensorflow/tests/test_models/models_pbtxt/shapeof_slice_abs.pbtxt new file mode 100644 index 00000000000000..0811447825e2fa --- /dev/null +++ b/src/frontends/tensorflow/tests/test_models/models_pbtxt/shapeof_slice_abs.pbtxt @@ -0,0 +1,149 @@ +node { + name: "input" + op: "Placeholder" + attr { + key: "_output_shapes" + value { + list { + shape { + dim { + size: 10 + } + dim { + size: 4 + } + } + } + } + } + attr { + key: "dtype" + value { + type: DT_FLOAT + } + } + attr { + key: "shape" + value { + shape { + dim { + size: 10 + } + dim { + size: 4 + } + } + } + } +} +node { + name: "start" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "stop" + input: "input" + op: "Shape" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } +} +node { + name: "stride" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "axes" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "slice" + op: "Slice" + input: "input" + input: "start" + input: "stop" + input: "stride" + input: "axes" + attr { + key: "T" + value { + type: DT_FLOAT + } + } +} +node { + name: "abs" + op: "Abs" + input: "slice" + attr { + key: "T" + value { + type: DT_FLOAT + } + } +} +library { +} diff --git a/src/frontends/tensorflow_lite/tests/CMakeLists.txt b/src/frontends/tensorflow_lite/tests/CMakeLists.txt index 278f7d313f0847..8869e5b4907ec5 100644 --- a/src/frontends/tensorflow_lite/tests/CMakeLists.txt +++ b/src/frontends/tensorflow_lite/tests/CMakeLists.txt @@ -45,14 +45,13 @@ if (tensorflow_FOUND) set(OUT_DONE_FILE ${TEST_TENSORFLOW_LITE_MODELS}/${FILE_WE}_done.txt) set(OUT_FILES ${OUT_DONE_FILE} ${OUT_FILES}) add_custom_command(OUTPUT ${OUT_DONE_FILE} - COMMAND ${PYTHON_EXECUTABLE} - ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py - ${GEN_SCRIPT} - ${TEST_TENSORFLOW_LITE_MODELS} - ${OUT_DONE_FILE} + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py + ${GEN_SCRIPT} + ${TEST_TENSORFLOW_LITE_MODELS} + ${OUT_DONE_FILE} JOB_POOL four_jobs - DEPENDS ${TENSORFLOW_ALL_SCRIPTS} - ) + DEPENDS ${TENSORFLOW_ALL_SCRIPTS}) endforeach() add_custom_target(tensorflow_lite_test_models DEPENDS ${OUT_FILES}) diff --git a/src/plugins/auto_batch/tests/functional/behavior/ov_executable_network/exec_net_base.cpp b/src/plugins/auto_batch/tests/functional/behavior/ov_executable_network/exec_net_base.cpp index b54c368600f738..9ff14d6083faff 100644 --- a/src/plugins/auto_batch/tests/functional/behavior/ov_executable_network/exec_net_base.cpp +++ b/src/plugins/auto_batch/tests/functional/behavior/ov_executable_network/exec_net_base.cpp @@ -14,7 +14,7 @@ auto autoBatchConfigs = []() { {ov::auto_batch_timeout.name(), "0"}}}; }; -INSTANTIATE_TEST_SUITE_P(smoke_AutoBatchBehaviorTests, OVExecutableNetworkBaseTest, +INSTANTIATE_TEST_SUITE_P(smoke_AutoBatch_BehaviorTests, OVExecutableNetworkBaseTest, ::testing::Combine( ::testing::Values(ov::test::utils::DEVICE_BATCH), ::testing::ValuesIn(autoBatchConfigs())), diff --git a/src/plugins/auto_batch/tests/functional/behavior/ov_infer_request/cancellation.cpp b/src/plugins/auto_batch/tests/functional/behavior/ov_infer_request/cancellation.cpp index 62518559dc88e3..0d5ab04ca35ec3 100644 --- a/src/plugins/auto_batch/tests/functional/behavior/ov_infer_request/cancellation.cpp +++ b/src/plugins/auto_batch/tests/functional/behavior/ov_infer_request/cancellation.cpp @@ -15,7 +15,7 @@ auto autoBatchConfigs = []() { {ov::auto_batch_timeout(0)}}}; }; -INSTANTIATE_TEST_SUITE_P(smoke_AutoBatchBehaviorTests, +INSTANTIATE_TEST_SUITE_P(smoke_AutoBatch_BehaviorTests, OVInferRequestCancellationTests, ::testing::Combine(::testing::Values(ov::test::utils::DEVICE_BATCH), ::testing::ValuesIn(autoBatchConfigs())), diff --git a/src/plugins/hetero/CMakeLists.txt b/src/plugins/hetero/CMakeLists.txt index 69b56cb79b36c3..fdb972a7b427b4 100644 --- a/src/plugins/hetero/CMakeLists.txt +++ b/src/plugins/hetero/CMakeLists.txt @@ -8,8 +8,8 @@ endif() set(TARGET_NAME openvino_hetero_plugin) -file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) -file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp) +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp) ov_add_plugin(NAME ${TARGET_NAME} DEVICE_NAME "HETERO" diff --git a/src/plugins/hetero/src/compiled_model.cpp b/src/plugins/hetero/src/compiled_model.cpp index 73824c88189ba8..9f5ee7c634aeb8 100644 --- a/src/plugins/hetero/src/compiled_model.cpp +++ b/src/plugins/hetero/src/compiled_model.cpp @@ -10,6 +10,7 @@ #include "graph_debug_dump.hpp" #include "ie_plugin_config.hpp" #include "itt.hpp" +#include "op/device_subgraph.hpp" #include "openvino/op/util/op_types.hpp" #include "openvino/pass/constant_folding.hpp" #include "openvino/pass/manager.hpp" @@ -18,7 +19,6 @@ #include "openvino/util/common_util.hpp" #include "plugin.hpp" #include "properties.hpp" -#include "subgraph_collector.hpp" #include "xml_parse_utils.h" ov::hetero::CompiledModel::CompiledModel(const std::shared_ptr& model, @@ -38,10 +38,6 @@ ov::hetero::CompiledModel::CompiledModel(const std::shared_ptr& model } void ov::hetero::CompiledModel::compile_model(const std::shared_ptr& model) { - bool dump_dot_file = m_cfg.dump_graph; - if (std::getenv("OPENVINO_HETERO_VISUALIZE")) - dump_dot_file = 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 @@ -51,149 +47,28 @@ void ov::hetero::CompiledModel::compile_model(const std::shared_ptr& manager.run_passes(model); ov::SupportedOpsMap query_model_result; - auto ordered_ops = model->get_ordered_ops(); - - bool all_empty = true; + bool user_set_affinities = false; // Get user defined affinity - for (const auto& node : ordered_ops) { + for (const auto& node : model->get_ordered_ops()) { auto& node_info = node->get_rt_info(); auto it_info = node_info.find("affinity"); if (it_info != node_info.end()) { OPENVINO_ASSERT(it_info->second.is(), "Unexpected type of \"affinity\" attribute"); query_model_result.emplace(node->get_friendly_name(), it_info->second.as()); - all_empty = false; - } - } - - if (query_model_result.empty()) { - // Restore properties in order to pass "device priorities" together - // with devices properties - auto full_properties = m_cfg.get_hetero_properties(); - for (const auto& property : m_cfg.get_device_properties()) - full_properties[property.first] = property.second; - query_model_result = get_hetero_plugin()->query_model(model, full_properties); - } - - std::unordered_set devices; - SubgraphCollector::AffinitiesMap affinities; - // Check that all nodes has user or plugin defined affinities - for (const auto& node : ordered_ops) { - auto it_affinity = query_model_result.find(node->get_friendly_name()); - if (it_affinity != query_model_result.end()) { - affinities[node] = it_affinity->second; - devices.emplace(it_affinity->second); - } else if (all_empty) { - OPENVINO_THROW("Hetero device used default fallback policy, but some layers eg: \n(Name:", - node->get_friendly_name(), - ", Type: ", - node->get_type_name(), - ") were not able to be assigned on any pointed device.\n", - "It happened because these layers are not supported in plugins by default.\n", - "You need to implement custom layers to support them."); - } else { - OPENVINO_THROW("Model passed to CompiledModel has affinity assigned, but some layers eg: \n(Name:", - node->get_friendly_name(), - ", Type: ", - node->get_type_name(), - ") were not assigned to any device.\n", - "It might happen if you assigned layers manually and missed some layers or\n", - "if you used some automatic assigning mode which decided that these layers are not\n", - "supported by any plugin"); - } - } - - if (dump_dot_file) { - ov::hetero::debug::dump_affinities(model, query_model_result, devices); - } - - // Init subgraph collector - SubgraphCollector subgraph_collector(model, affinities); - - if (dump_dot_file) { - auto subgraph_ids = subgraph_collector.get_subgraph_ids(); - std::map map_id; - for (const auto& v : subgraph_ids) { - map_id.emplace(v.first->get_friendly_name(), v.second); - } - ov::hetero::debug::dump_subgraphs(model, query_model_result, map_id); - } - - // Get subgraphs sorted topologically - auto ordered_subgraphs = subgraph_collector.get_ordered_subgraphs(); - - // Prepare mapping between original inputs/outputs and compiled - // submodels inputs/outputs. Example: - // original input 0 -> submodel 0 input 0, - // original input 1 -> submodel 1 input 0, - // original output 0 -> submodel 1 output 0. - // - // Mapping is required only because before compilation - // submodel may be preprocessed (if legacy API used), - // so original inputs/outputs != submodels inputs/outputs - const auto& orig_parameters = model->get_parameters(); - const auto& orig_results = model->get_results(); - m_inputs_to_submodels_inputs.resize(orig_parameters.size()); - m_outputs_to_submodels_outputs.resize(orig_results.size()); - for (size_t id = 0; id < ordered_subgraphs.size(); id++) { - for (size_t i = 0; i < ordered_subgraphs[id]._parameters.size(); i++) { - for (size_t j = 0; j < orig_parameters.size(); j++) - if (ordered_subgraphs[id]._parameters[i] == orig_parameters[j]) - m_inputs_to_submodels_inputs[j] = {id, i}; - } - for (size_t i = 0; i < ordered_subgraphs[id]._results.size(); i++) { - for (size_t j = 0; j < orig_results.size(); j++) - if (ordered_subgraphs[id]._results[i] == orig_results[j]) - m_outputs_to_submodels_outputs[j] = {id, i}; + user_set_affinities = true; } } - // Prepare mapping between manually splitted inputs/outputs - // to connect tensors between compiled submodels - for (const auto& kvp : subgraph_collector.get_subgraph_parameter_to_prev_result()) { - const auto& intermed_output = kvp.second; - const auto& intermed_input = kvp.first; - for (size_t id = 0; id < ordered_subgraphs.size(); id++) { - const auto& out_it = std::find(ordered_subgraphs[id]._results.begin(), - ordered_subgraphs[id]._results.end(), - intermed_output); - if (out_it != ordered_subgraphs[id]._results.end()) { - for (size_t id2 = 0; id2 < ordered_subgraphs.size(); id2++) { - if (id2 == id) - continue; - const auto& in_it = std::find(ordered_subgraphs[id2]._parameters.begin(), - ordered_subgraphs[id2]._parameters.end(), - intermed_input); - if (in_it != ordered_subgraphs[id2]._parameters.end()) { - auto out_idx = std::distance(ordered_subgraphs[id]._results.begin(), out_it); - auto in_idx = std::distance(ordered_subgraphs[id2]._parameters.begin(), in_it); - m_submodels_input_to_prev_output[{id2, in_idx}] = {id, out_idx}; - } - } - } - } - } - - m_compiled_submodels.resize(ordered_subgraphs.size()); - std::vector> submodels(ordered_subgraphs.size()); - size_t id = 0; - for (const auto& subgraph : ordered_subgraphs) { - m_compiled_submodels[id].device = subgraph._affinity; - submodels[id] = std::make_shared(subgraph._results, - subgraph._sinks, - subgraph._parameters, - m_name + '_' + std::to_string(id)); - m_compiled_submodels[id].model = submodels[id]; - - auto meta_devices = get_hetero_plugin()->get_properties_per_device(m_compiled_submodels[id].device, - m_cfg.get_device_properties()); - + auto compile_device_model = [&](CompiledModelDesc& compiled_model_desc, bool add_exclusive) { + auto meta_devices = + get_hetero_plugin()->get_properties_per_device(compiled_model_desc.device, m_cfg.get_device_properties()); // disable caching for subgraphs, because the whole HETERO model is cached - auto device_config = meta_devices[m_compiled_submodels[id].device]; + auto device_config = meta_devices[compiled_model_desc.device]; device_config[ov::cache_dir.name()] = ""; // set exclusive_async_requests in case when model is split - if (ordered_subgraphs.size() > 1) { + if (add_exclusive) { auto supported_internal_properties = - get_hetero_plugin()->get_core()->get_property(m_compiled_submodels[id].device, + get_hetero_plugin()->get_core()->get_property(compiled_model_desc.device, ov::internal::supported_properties); if (std::find(supported_internal_properties.begin(), supported_internal_properties.end(), @@ -202,13 +77,60 @@ void ov::hetero::CompiledModel::compile_model(const std::shared_ptr& device_config.insert(ov::internal::exclusive_async_requests(true)); } } - m_compiled_submodels[id].compiled_model = - get_hetero_plugin()->get_core()->compile_model(m_compiled_submodels[id].model, - m_compiled_submodels[id].device, - device_config); - ++id; - } + compiled_model_desc.compiled_model = get_hetero_plugin()->get_core()->compile_model(compiled_model_desc.model, + compiled_model_desc.device, + device_config); + }; + + if (user_set_affinities) { + // All affinities must be defined by user + ov::hetero::SubgraphsVector ordered_subgraphs; + std::tie(ordered_subgraphs, m_mapping_info) = + get_model_subgraphs(model, query_model_result, user_set_affinities, m_cfg.dump_dot_files()); + + m_compiled_submodels.resize(ordered_subgraphs.size()); + bool add_exclusive = ordered_subgraphs.size() > 1; + size_t id = 0; + for (const auto& subgraph : ordered_subgraphs) { + m_compiled_submodels[id].device = subgraph._affinity; + m_compiled_submodels[id].model = std::make_shared(subgraph._results, + subgraph._sinks, + subgraph._parameters, + m_name + '_' + std::to_string(id)); + compile_device_model(m_compiled_submodels[id], add_exclusive); + ++id; + } + } else { + // Restore properties in order to pass "device priorities" together + // with devices properties + auto full_properties = m_cfg.get_hetero_properties(); + for (const auto& property : m_cfg.get_device_properties()) + full_properties[property.first] = property.second; + // This function modifes original model + auto cloned_model = model->clone(); + std::tie(query_model_result, m_mapping_info) = + get_hetero_plugin()->query_model_update(cloned_model, full_properties, true); + + ov::hetero::op::DeviceSubgraphVector ordered_subgraphs; + for (const auto& op : cloned_model->get_ordered_ops()) { + if (const auto& subgraph = ov::as_type_ptr(op)) { + ordered_subgraphs.push_back(subgraph); + } else { + OPENVINO_ASSERT(ov::op::util::is_output(op) || ov::op::util::is_parameter(op) || + ov::op::util::is_sink(op)); + } + } + m_compiled_submodels.resize(ordered_subgraphs.size()); + bool add_exclusive = ordered_subgraphs.size() > 1; + size_t id = 0; + for (const auto& subgraph : ordered_subgraphs) { + m_compiled_submodels[id].device = subgraph->get_affinity(); + m_compiled_submodels[id].model = subgraph->get_function(); + compile_device_model(m_compiled_submodels[id], add_exclusive); + ++id; + } + } set_inputs_and_outputs(); } @@ -284,12 +206,12 @@ ov::hetero::CompiledModel::CompiledModel(std::istream& model, auto inputs_map_node = heteroNode.child("inputs_to_submodels_inputs"); FOREACH_CHILD(xml_node, inputs_map_node, "pair") { - m_inputs_to_submodels_inputs.emplace_back(GetUInt64Attr(xml_node, "submodel_idx"), + m_mapping_info._inputs_to_submodels_inputs.emplace_back(GetUInt64Attr(xml_node, "submodel_idx"), GetUInt64Attr(xml_node, "node_idx")); } auto outputs_map_node = heteroNode.child("outputs_to_submodels_outputs"); FOREACH_CHILD(xml_node, outputs_map_node, "pair") { - m_outputs_to_submodels_outputs.emplace_back(GetUInt64Attr(xml_node, "submodel_idx"), + m_mapping_info._outputs_to_submodels_outputs.emplace_back(GetUInt64Attr(xml_node, "submodel_idx"), GetUInt64Attr(xml_node, "node_idx")); } auto submodels_input_to_prev_output_node = heteroNode.child("submodels_input_to_prev_output"); @@ -298,7 +220,7 @@ ov::hetero::CompiledModel::CompiledModel(std::istream& model, GetUInt64Attr(xml_node, "in_node_idx")}; std::pair out_pair = {GetUInt64Attr(xml_node, "out_submodel_idx"), GetUInt64Attr(xml_node, "out_node_idx")}; - m_submodels_input_to_prev_output.emplace(in_pair, out_pair); + m_mapping_info._submodels_input_to_prev_output.emplace(in_pair, out_pair); } // clang-format on set_inputs_and_outputs(); @@ -329,103 +251,8 @@ std::shared_ptr ov::hetero::CompiledModel::get_runtime_model() for (size_t i = 0; i < m_compiled_submodels.size(); i++) { rt_models.push_back(m_compiled_submodels.at(i).compiled_model->get_runtime_model()->clone()); } - // Results which should not be present in final graph - std::set result_names_to_be_removed; - // Remap port indexes to names, because order of them will be modified during merge - std::map, std::pair> input_to_prev_output; - for (const auto& kvp : m_submodels_input_to_prev_output) { - const auto& input_node = rt_models[kvp.first.first]->inputs()[kvp.first.second].get_node(); - const auto& output_node = rt_models[kvp.second.first]->outputs()[kvp.second.second].get_node(); - input_to_prev_output[{kvp.first.first, input_node->get_friendly_name()}] = {kvp.second.first, - output_node->get_friendly_name()}; - result_names_to_be_removed.insert(output_node->get_friendly_name()); - } - int submodel_in_index = static_cast(rt_models.size()) - 1; - while (submodel_in_index >= 0 && input_to_prev_output.size() > 0) { - auto& submodel_in = rt_models[submodel_in_index]; - size_t port_in_index = 0; - while (port_in_index < submodel_in->get_parameters().size()) { - auto parameter_to_replace = submodel_in->get_parameters()[port_in_index]; - auto item = input_to_prev_output.find({submodel_in_index, parameter_to_replace->get_friendly_name()}); - if (item == input_to_prev_output.end()) { - port_in_index++; - continue; - } - auto submodel_out_index = item->second.first; - auto submodel_out_result_name = item->second.second; - auto submodel_out = rt_models.at(submodel_out_index); - - // Get all results from previous subgraph except already existed in next subgraph - std::shared_ptr result_to_replace = nullptr; - ov::ResultVector add_results; - for (auto& result : submodel_out->get_results()) { - if (result->get_friendly_name() == submodel_out_result_name) { - result_to_replace = result; - } - auto it = std::find_if(submodel_in->get_results().begin(), - submodel_in->get_results().end(), - [&](const std::shared_ptr& result_to_check) { - return result_to_check == result; - }); - if (it == submodel_in->get_results().end()) - add_results.push_back(result); - } - OPENVINO_ASSERT(result_to_replace != nullptr); - - // Get all parameters from previous subgraph except already existed in next subgraph - ov::ParameterVector add_parameters; - for (auto& parameter : submodel_out->get_parameters()) { - auto it = std::find_if(submodel_in->get_parameters().begin(), - submodel_in->get_parameters().end(), - [&](const std::shared_ptr& parameter_to_check) { - return parameter_to_check == parameter; - }); - if (it == submodel_in->get_parameters().end()) - add_parameters.push_back(parameter); - } - - // Reconnect appropariate target inputs to the new source output - auto result_source = result_to_replace->get_input_source_output(0); - auto parameter_targets = parameter_to_replace->get_output_target_inputs(0); - for (auto parameter_target : parameter_targets) { - parameter_target.replace_source_output(result_source); - } - - // Update parameter and results - submodel_in->remove_parameter(parameter_to_replace); - submodel_in->add_parameters(add_parameters); - submodel_in->add_results(add_results); - - // Remove processed connection - input_to_prev_output.erase(item); - - // Update incoming model since it is merged - for (size_t i = 0; i < rt_models.size(); i++) { - if (rt_models[i] == submodel_out) { - rt_models[i] = submodel_in; - } - } - - // Start check ports from the beginning because number of ports are modified - port_in_index = 0; - } - --submodel_in_index; - } - // Finally all subgraphs should be merged into single one - OPENVINO_ASSERT(input_to_prev_output.size() == 0); - OPENVINO_ASSERT(all_of(rt_models.begin(), rt_models.end(), [&](const std::shared_ptr& rt_model) { - return rt_model == rt_models[0]; - })); - auto runtime_graph = rt_models[0]; - // Cleanup intermidiate results - for (size_t i = 0; i < runtime_graph->get_results().size();) { - auto& result = runtime_graph->get_results()[i]; - if (result_names_to_be_removed.count(result->get_friendly_name())) { - runtime_graph->remove_result(result); - } else { - i++; - } - } + ov::hetero::merge_submodels(rt_models, m_mapping_info._submodels_input_to_prev_output); + auto& runtime_graph = rt_models[0]; OPENVINO_ASSERT(runtime_graph->inputs().size() == inputs().size()); return runtime_graph; } @@ -524,17 +351,33 @@ const std::vector>& ov::hetero::CompiledModel::output void ov::hetero::CompiledModel::set_inputs_and_outputs() { // Restore inputs/outputs from compiled submodels - m_compiled_inputs.reserve(m_inputs_to_submodels_inputs.size()); - for (const auto& it : m_inputs_to_submodels_inputs) { + m_compiled_inputs.reserve(m_mapping_info._inputs_to_submodels_inputs.size()); + for (const auto& it : m_mapping_info._inputs_to_submodels_inputs) { const auto& submodel_idx = it.first; + OPENVINO_ASSERT(submodel_idx < m_compiled_submodels.size(), + "Model contains " + std::to_string(m_compiled_submodels.size()) + + " submodels. Index is out of range: " + std::to_string(submodel_idx)); + const auto& compiled_submodel = m_compiled_submodels[submodel_idx].compiled_model; const auto& input_idx = it.second; - m_compiled_inputs.emplace_back(m_compiled_submodels[submodel_idx].compiled_model->inputs()[input_idx]); + OPENVINO_ASSERT(input_idx < compiled_submodel->inputs().size(), + "Submodel " + std::to_string(submodel_idx) + " has " + + std::to_string(compiled_submodel->inputs().size()) + + " inputs. Index is out of range: " + std::to_string(input_idx)); + m_compiled_inputs.emplace_back(compiled_submodel->inputs()[input_idx]); } - m_compiled_outputs.reserve(m_outputs_to_submodels_outputs.size()); - for (const auto& it : m_outputs_to_submodels_outputs) { + m_compiled_outputs.reserve(m_mapping_info._outputs_to_submodels_outputs.size()); + for (const auto& it : m_mapping_info._outputs_to_submodels_outputs) { const auto& submodel_idx = it.first; + OPENVINO_ASSERT(submodel_idx < m_compiled_submodels.size(), + "Model contains " + std::to_string(m_compiled_submodels.size()) + + " submodels. Index is out of range: " + std::to_string(submodel_idx)); + const auto& compiled_submodel = m_compiled_submodels[submodel_idx].compiled_model; const auto& output_idx = it.second; - m_compiled_outputs.emplace_back(m_compiled_submodels[submodel_idx].compiled_model->outputs()[output_idx]); + OPENVINO_ASSERT(output_idx < compiled_submodel->outputs().size(), + "Submodel " + std::to_string(submodel_idx) + " has " + + std::to_string(compiled_submodel->outputs().size()) + + " outputs. Index is out of range: " + std::to_string(output_idx)); + m_compiled_outputs.emplace_back(compiled_submodel->outputs()[output_idx]); } } @@ -546,20 +389,20 @@ void ov::hetero::CompiledModel::export_model(std::ostream& model_stream) const { heteroNode.append_attribute("name").set_value(m_name.c_str()); auto inputs_map_node = heteroNode.append_child("inputs_to_submodels_inputs"); - for (const auto& it : m_inputs_to_submodels_inputs) { + for (const auto& it : m_mapping_info._inputs_to_submodels_inputs) { auto xml_node = inputs_map_node.append_child("pair"); xml_node.append_attribute("submodel_idx").set_value(std::to_string(it.first).c_str()); xml_node.append_attribute("node_idx").set_value(std::to_string(it.second).c_str()); } auto outputs_map_node = heteroNode.append_child("outputs_to_submodels_outputs"); - for (const auto& it : m_outputs_to_submodels_outputs) { + for (const auto& it : m_mapping_info._outputs_to_submodels_outputs) { auto xml_node = outputs_map_node.append_child("pair"); xml_node.append_attribute("submodel_idx").set_value(std::to_string(it.first).c_str()); xml_node.append_attribute("node_idx").set_value(std::to_string(it.second).c_str()); } auto submodels_input_to_prev_output_node = heteroNode.append_child("submodels_input_to_prev_output"); - for (const auto& it : m_submodels_input_to_prev_output) { + for (const auto& it : m_mapping_info._submodels_input_to_prev_output) { auto xml_node = submodels_input_to_prev_output_node.append_child("record"); xml_node.append_attribute("in_submodel_idx").set_value(std::to_string(it.first.first).c_str()); xml_node.append_attribute("in_node_idx").set_value(std::to_string(it.first.second).c_str()); diff --git a/src/plugins/hetero/src/compiled_model.hpp b/src/plugins/hetero/src/compiled_model.hpp index 3acca0a8be4471..934459f157b31c 100644 --- a/src/plugins/hetero/src/compiled_model.hpp +++ b/src/plugins/hetero/src/compiled_model.hpp @@ -7,6 +7,7 @@ #include "config.hpp" #include "openvino/runtime/icompiled_model.hpp" #include "openvino/runtime/so_ptr.hpp" +#include "subgraph_collector.hpp" namespace ov { namespace hetero { @@ -52,11 +53,7 @@ class CompiledModel : public ov::ICompiledModel { const bool m_loaded_from_cache; std::vector> m_compiled_inputs; std::vector> m_compiled_outputs; - std::vector> m_inputs_to_submodels_inputs, - m_outputs_to_submodels_outputs; - std::map, - std::pair> - m_submodels_input_to_prev_output; + SubgraphsMappingInfo m_mapping_info; struct CompiledModelDesc { std::string device; diff --git a/src/plugins/hetero/src/config.cpp b/src/plugins/hetero/src/config.cpp index b1821f85392ce2..35cae2b56d87da 100644 --- a/src/plugins/hetero/src/config.cpp +++ b/src/plugins/hetero/src/config.cpp @@ -64,4 +64,11 @@ ov::AnyMap Configuration::get_hetero_properties() const { ov::AnyMap Configuration::get_device_properties() const { return device_properties; +} + +bool Configuration::dump_dot_files() const { + bool res = dump_graph; + if (std::getenv("OPENVINO_HETERO_VISUALIZE")) + res = true; + return res; } \ No newline at end of file diff --git a/src/plugins/hetero/src/config.hpp b/src/plugins/hetero/src/config.hpp index 3769bd7f7582c6..65606011976cb3 100644 --- a/src/plugins/hetero/src/config.hpp +++ b/src/plugins/hetero/src/config.hpp @@ -31,9 +31,13 @@ struct Configuration { ov::AnyMap get_device_properties() const; - bool dump_graph; + bool dump_dot_files() const; + std::string device_priorities; ov::AnyMap device_properties; + +private: + bool dump_graph; }; } // namespace hetero } // namespace ov \ No newline at end of file diff --git a/src/plugins/hetero/src/op/device_subgraph.cpp b/src/plugins/hetero/src/op/device_subgraph.cpp new file mode 100644 index 00000000000000..9ce7986c8d6191 --- /dev/null +++ b/src/plugins/hetero/src/op/device_subgraph.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "device_subgraph.hpp" + +using namespace ov::op::util; + +ov::hetero::op::DeviceSubgraph::DeviceSubgraph(const ov::OutputVector& args, + const std::shared_ptr& body, + const std::string& affinity) + : SubGraphOp(args), + _affinity{affinity} { + SubGraphOp::set_function(body); + constructor_validate_and_infer_types(); + for (size_t i = 0; i < body->get_parameters().size(); ++i) + m_input_descriptions[0].push_back(std::make_shared(i, i)); + for (size_t i = 0; i < body->get_output_size(); ++i) + m_output_descriptions[0].push_back(std::make_shared(i, i)); +} + +ov::hetero::op::DeviceSubgraph::DeviceSubgraph(const ov::NodeVector& args, + const std::shared_ptr& body, + const std::string& affinity) + : DeviceSubgraph(as_output_vector(args), body, affinity) {} + +std::shared_ptr ov::hetero::op::DeviceSubgraph::clone_with_new_inputs(const ov::OutputVector& inputs) const { + return std::make_shared(inputs, body().clone(), _affinity); +} + +void ov::hetero::op::DeviceSubgraph::validate_and_infer_types() { + ov::ParameterVector old_parameters; + for (auto op : body_ptr()->get_parameters()) { + old_parameters.push_back(op); + } + + for (size_t i = 0; i < get_input_size(); ++i) { + body_ptr()->replace_parameter( + i, + std::make_shared(get_input_element_type(i), get_input_partial_shape(i))); + } + + body_ptr()->validate_nodes_and_infer_types(); + + for (size_t i = 0; i < body_ptr()->get_parameters().size(); i++) { + body_ptr()->get_parameters()[i]->set_friendly_name(old_parameters[i]->get_friendly_name()); + } + + set_output_size(body_ptr()->get_output_size()); + for (size_t i = 0; i < get_output_size(); ++i) { + set_output_type(i, body_ptr()->get_output_element_type(i), body_ptr()->get_output_partial_shape(i)); + } +} + +bool ov::hetero::op::DeviceSubgraph::visit_attributes(ov::AttributeVisitor& visitor) { + visitor.on_attribute("affinity", _affinity); + visitor.on_attribute("body", body_ptr()); + visitor.on_attribute("input_descriptions", m_input_descriptions[0]); + visitor.on_attribute("output_descriptions", m_output_descriptions[0]); + return true; +} \ No newline at end of file diff --git a/src/plugins/hetero/src/op/device_subgraph.hpp b/src/plugins/hetero/src/op/device_subgraph.hpp new file mode 100644 index 00000000000000..300d02e56650fe --- /dev/null +++ b/src/plugins/hetero/src/op/device_subgraph.hpp @@ -0,0 +1,62 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include "openvino/core/model.hpp" +#include "openvino/core/rt_info.hpp" +#include "openvino/op/op.hpp" +#include "openvino/op/util/sub_graph_base.hpp" + +namespace ov { +namespace hetero { +namespace op { + +/** + * @interface DeviceSubgraph + * @brief An operation that is implemented by a model + */ +class DeviceSubgraph : public ov::op::util::SubGraphOp { +public: + OPENVINO_OP("DeviceSubgraph", "hetero", ov::op::util::SubGraphOp); + + DeviceSubgraph() = default; + + DeviceSubgraph(const OutputVector& args, const std::shared_ptr& body, const std::string& affinity); + + DeviceSubgraph(const NodeVector& args, const std::shared_ptr& body, const std::string& affinity); + + bool visit_attributes(AttributeVisitor& visitor) override; + + void validate_and_infer_types() override; + + std::shared_ptr clone_with_new_inputs(const OutputVector& inputs) const override; + + std::string get_affinity() { + return _affinity; + } + +private: + const ov::Model& body() const { + return *m_bodies[0]; + } + ov::Model& body() { + return *m_bodies[0]; + } + const std::shared_ptr& body_ptr() const { + return m_bodies[0]; + } + std::shared_ptr& body_ptr() { + return m_bodies[0]; + } + + std::string _affinity; +}; +using DeviceSubgraphVector = std::vector>; + +} // namespace op +} // namespace hetero +} // namespace ov diff --git a/src/plugins/hetero/src/plugin.cpp b/src/plugins/hetero/src/plugin.cpp index 0fb907e7b008f9..7c9a63265e8979 100644 --- a/src/plugins/hetero/src/plugin.cpp +++ b/src/plugins/hetero/src/plugin.cpp @@ -68,32 +68,51 @@ ov::hetero::Plugin::DeviceProperties ov::hetero::Plugin::get_properties_per_devi return device_properties; } -ov::SupportedOpsMap ov::hetero::Plugin::query_model(const std::shared_ptr& model, - const ov::AnyMap& properties) const { - OV_ITT_SCOPED_TASK(itt::domains::Hetero, "Plugin::query_model"); - - OPENVINO_ASSERT(model, "OpenVINO Model is empty!"); - +std::pair ov::hetero::Plugin::query_model_update( + std::shared_ptr& model, + const ov::AnyMap& properties, + bool allow_exception) const { Configuration full_config{properties, m_cfg}; DeviceProperties properties_per_device = get_properties_per_device(full_config.device_priorities, full_config.get_device_properties()); + // WARNING: Here is devices with user set priority + auto device_names = ov::DeviceIDParser::get_hetero_devices(full_config.device_priorities); + + auto update_supported_ops = [](ov::SupportedOpsMap& final_results, const ov::SupportedOpsMap& device_results) { + for (const auto& layer_query_result : device_results) + final_results.emplace(layer_query_result); + }; + + ov::SupportedOpsMap supported_ops_temp; + ov::SupportedOpsMap supported_ops_final; std::map query_results; - for (const auto& it : properties_per_device) { - const auto& device_name = it.first; - const auto& device_config = it.second; + ov::hetero::SubgraphsMappingInfo mapping_info; + for (const auto& device_name : device_names) { + // If there are some unsupported operations and it is a last device + // exception should be raised when allowed + const auto& default_device = (!allow_exception || device_name != device_names.back()) ? get_device_name() : ""; + const auto& device_config = properties_per_device.at(device_name); query_results[device_name] = get_core()->query_model(model, device_name, device_config); + // Update supported operations map which includes new operations + update_supported_ops(supported_ops_temp, query_results[device_name]); + // Update supported operations map which includes original operations only + update_supported_ops(supported_ops_final, query_results[device_name]); + mapping_info = + ov::hetero::mask_model_subgraphs_by_ops(model, supported_ops_temp, m_cfg.dump_dot_files(), default_device); } + return {supported_ops_final, mapping_info}; +} - // WARNING: Here is devices with user set priority - auto device_names = ov::DeviceIDParser::get_hetero_devices(full_config.device_priorities); +ov::SupportedOpsMap ov::hetero::Plugin::query_model(const std::shared_ptr& model, + const ov::AnyMap& properties) const { + OV_ITT_SCOPED_TASK(itt::domains::Hetero, "Plugin::query_model"); + + OPENVINO_ASSERT(model, "OpenVINO Model is empty!"); - ov::SupportedOpsMap res; - for (const auto& device_name : device_names) - for (const auto& layer_query_result : query_results[device_name]) - res.emplace(layer_query_result); + std::shared_ptr query_model = model->clone(); - return res; + return query_model_update(query_model, properties).first; } void ov::hetero::Plugin::set_property(const ov::AnyMap& properties) { diff --git a/src/plugins/hetero/src/plugin.hpp b/src/plugins/hetero/src/plugin.hpp index 43ed4ddb407435..b6ac8e95375da2 100644 --- a/src/plugins/hetero/src/plugin.hpp +++ b/src/plugins/hetero/src/plugin.hpp @@ -13,6 +13,7 @@ #include "config.hpp" #include "openvino/runtime/iplugin.hpp" +#include "subgraph_collector.hpp" namespace ov { namespace hetero { @@ -59,6 +60,11 @@ class Plugin : public ov::IPlugin { DeviceProperties get_properties_per_device(const std::string& device_priorities, const ov::AnyMap& properties) const; + std::pair query_model_update( + std::shared_ptr& model, + const ov::AnyMap& properties, + bool allow_exception = false) const; + Configuration m_cfg; }; diff --git a/src/plugins/hetero/src/subgraph_collector.cpp b/src/plugins/hetero/src/subgraph_collector.cpp index aabb1f068f371f..3d576f684998a6 100644 --- a/src/plugins/hetero/src/subgraph_collector.cpp +++ b/src/plugins/hetero/src/subgraph_collector.cpp @@ -6,9 +6,14 @@ #include +#include "graph_debug_dump.hpp" +#include "op/device_subgraph.hpp" #include "openvino/core/except.hpp" +#include "openvino/core/graph_util.hpp" #include "openvino/core/rt_info.hpp" #include "openvino/op/util/op_types.hpp" +#include "openvino/util/common_util.hpp" +#include "transformations/utils/utils.hpp" namespace { @@ -32,18 +37,44 @@ static bool intersects(const Set& lhs, const Set& rhs) { return true; return false; } + +template +static std::vector addition(const std::vector& vector1, const std::vector& vector2) { + std::vector addition; + std::copy_if(vector1.begin(), vector1.end(), std::back_inserter(addition), [&vector2](const T& arg) { + return (std::find(vector2.begin(), vector2.end(), arg) == vector2.end()); + }); + return addition; +} + +template +static size_t get_index(const std::vector& vector, const T& item) { + const auto& it = std::find(vector.begin(), vector.end(), item); + OPENVINO_ASSERT(it != vector.end()); + return static_cast(std::distance(vector.begin(), it)); +} + } // namespace +std::shared_ptr ov::hetero::SubgraphCollector::output_node( + const ov::hetero::SubgraphCollector::Output& output) const { + return output.get_node_shared_ptr(); +} + std::shared_ptr ov::hetero::SubgraphCollector::input_node( const ov::hetero::SubgraphCollector::Input& input) const { - return input.get_source_output().get_node_shared_ptr(); + return output_node(input.get_source_output()); } ov::hetero::SubgraphCollector::SubgraphCollector(const std::shared_ptr& model, const AffinitiesMap& affinities) : _ordered_ops{model->get_ordered_ops()}, + _origin_parameters(model->get_parameters()), + _origin_results(model->get_results()), + _origin_sinks(model->get_sinks()), + _intermediate_parameters{}, + _intermediate_results(), _affinities{affinities}, - _graph_input_nodes{}, _node_input_dependencies{}, _subgraph_inputs{}, _subgraph_parameter_to_prev_result{} { @@ -52,11 +83,14 @@ ov::hetero::SubgraphCollector::SubgraphCollector(const std::shared_ptr, InputSet> node_subgraph_input_dependencies; + NodeMap node_subgraph_input_dependencies; // All inputs that depends on the same subgraph as node - std::unordered_map, InputSet> node_subgraph_cyclic_iput_dependencies; + NodeMap node_subgraph_cyclic_iput_dependencies; for (const auto& node : _ordered_ops) { auto& node_subgraph_input_dependency = node_subgraph_input_dependencies[node]; auto all_node_subgraph_inputs = intersection(_node_input_dependencies[node], _subgraph_inputs); - for (const auto& subgraphInput : all_node_subgraph_inputs) { - if (subgraph_ids[node] == subgraph_ids[subgraphInput.get_node()->shared_from_this()]) { - node_subgraph_input_dependency.emplace(subgraphInput); + for (const auto& subgraph_input : all_node_subgraph_inputs) { + if (subgraph_ids[node] == subgraph_ids[subgraph_input.get_node()->shared_from_this()]) { + node_subgraph_input_dependency.emplace(subgraph_input); } } auto& node_subgraph_cyclic_input_dependency = node_subgraph_cyclic_iput_dependencies[node]; - for (const auto& subgraphInput : all_node_subgraph_inputs) { - if (!ov::op::util::is_parameter(subgraphInput.get_node()) && - !ov::op::util::is_constant(subgraphInput.get_node()) && - subgraph_ids[node] == subgraph_ids[input_node(subgraphInput)]) { - node_subgraph_cyclic_input_dependency.emplace(subgraphInput); + for (const auto& subgraph_input : all_node_subgraph_inputs) { + if (!is_graph_input_node(subgraph_input.get_node()) && + subgraph_ids[node] == subgraph_ids[input_node(subgraph_input)]) { + node_subgraph_cyclic_input_dependency.emplace(subgraph_input); } } } @@ -106,10 +143,10 @@ void ov::hetero::SubgraphCollector::split_cyclic_dependencies() { auto& node_subgraph_cyclic_input_dependency = node_subgraph_cyclic_iput_dependencies[node]; if (!node_subgraph_cyclic_input_dependency.empty()) { // Collect all subgraph inputs that cyclic subgraph output depends on - InputSet cyclicInputsDependencies; + InputSet cyclic_inputs_dependencies; for (const auto& cyclicInput : node_subgraph_cyclic_input_dependency) { for (const auto& input : node_subgraph_input_dependencies[input_node(cyclicInput)]) { - cyclicInputsDependencies.emplace(input); + cyclic_inputs_dependencies.emplace(input); } } for (const auto& input : node->inputs()) { @@ -118,7 +155,7 @@ void ov::hetero::SubgraphCollector::split_cyclic_dependencies() { auto& input_node_subgraph_input_dependency = node_subgraph_input_dependencies[input_node(input)]; if (!intersects(node_subgraph_cyclic_input_dependency, input_node_subgraph_cyclic_input_dependency) && - intersects(cyclicInputsDependencies, input_node_subgraph_input_dependency)) { + intersects(cyclic_inputs_dependencies, input_node_subgraph_input_dependency)) { _subgraph_inputs.insert(input); } } @@ -132,7 +169,7 @@ ov::hetero::SubgraphCollector::SubgraphIdsMap ov::hetero::SubgraphCollector::col NodeMap subgraph_id_ptrs; for (const auto& node : _ordered_ops) { auto all_node_inputs = node->inputs(); - std::vector inputs; + InputVector inputs; for (const auto& input : all_node_inputs) { if (_subgraph_inputs.find(input) == _subgraph_inputs.end()) { inputs.emplace_back(std::move(input)); @@ -160,49 +197,56 @@ ov::hetero::SubgraphCollector::SubgraphIdsMap ov::hetero::SubgraphCollector::col } return result; } - void ov::hetero::SubgraphCollector::split_subgraphs_by_parameter_results() { - // Break graph using insertion of result parameter split - std::vector> results; - { - std::set> subgraph_outputs; - for (const auto& input : _subgraph_inputs) { - if (!ov::op::util::is_parameter(input.get_node()) && !ov::op::util::is_constant(input.get_node())) { - auto input_source_output = input.get_source_output(); - if (!ov::op::util::is_parameter(input_source_output.get_node()) && - !ov::op::util::is_constant(input_source_output.get_node())) { - subgraph_outputs.insert(input_source_output); - } + // Sort subgraph inputs by order + InputVector ordered_subgraph_inputs; + for (auto& op : _ordered_ops) { + for (auto& input : op->inputs()) { + if (_subgraph_inputs.count(input)) { + ordered_subgraph_inputs.push_back(input); } } - for (const auto& output : subgraph_outputs) { - auto output_subgraph_id = _subgraph_ids.at(output.get_node_shared_ptr()); - auto inputs = output.get_target_inputs(); - // Collect input subsets from other subgraphs. Each subset of inputs belongs to the same subgraph - std::map>> input_subsets; - for (const auto& input : inputs) { - auto input_subgraph_id = _subgraph_ids.at(input.get_node()->shared_from_this()); - if (output_subgraph_id != input_subgraph_id) { - input_subsets[input_subgraph_id].emplace(input); - } + } + // Collect subgraph ordered subgraph outputs + OutputVector ordered_subgraph_outputs; + for (const auto& input : ordered_subgraph_inputs) { + if (!is_graph_input_node(input.get_node())) { + auto input_source_output = input.get_source_output(); + if (!is_graph_input_node(input_source_output.get_node())) { + ordered_subgraph_outputs.push_back(input_source_output); } + } + } + // Break graph using insertion of result parameter split + for (const auto& output : ordered_subgraph_outputs) { + auto output_subgraph_id = _subgraph_ids.at(output.get_node_shared_ptr()); + auto inputs = output.get_target_inputs(); + // Collect input subsets from other subgraphs. Each subset of inputs belongs to the same subgraph + std::map input_subsets; + for (const auto& input : inputs) { + auto input_subgraph_id = _subgraph_ids.at(input.get_node()->shared_from_this()); + if (output_subgraph_id != input_subgraph_id) { + input_subsets[input_subgraph_id].emplace(input); + } + } + if (input_subsets.size()) { // Avoid duplicate results on the same output port auto result = std::make_shared(output); - const auto name = output.get_node()->get_friendly_name() + "_" + std::to_string(output.get_index()); - result->set_friendly_name(name + "_result"); ov::copy_runtime_info(output.get_node_shared_ptr(), result); _subgraph_ids.emplace(result, output_subgraph_id); - results.push_back(result); + _intermediate_results.push_back(result); for (const auto& input_subset : input_subsets) { + const auto input_subgraph_id = input_subset.first; + const auto inputs = input_subset.second; // Avoid duplicate parameters in the same subgraph auto parameter = std::make_shared(output.get_element_type(), output.get_partial_shape()); - parameter->set_friendly_name(name + "_parameter"); - for (const auto& input : input_subset.second) { + _intermediate_parameters.push_back(parameter); + for (const auto& input : inputs) { output.remove_target_input(input); ov::copy_runtime_info(input.get_node()->shared_from_this(), parameter); input.replace_source_output(parameter->output(0)); - _subgraph_ids.emplace(parameter, input_subset.first); + _subgraph_ids.emplace(parameter, input_subgraph_id); _subgraph_parameter_to_prev_result.emplace(parameter, result); } } @@ -210,7 +254,7 @@ void ov::hetero::SubgraphCollector::split_subgraphs_by_parameter_results() { } } -std::vector ov::hetero::SubgraphCollector::get_ordered_subgraphs() { +std::pair ov::hetero::SubgraphCollector::run() { // Break graph using insertion of result parameter split split_subgraphs_by_parameter_results(); @@ -218,27 +262,27 @@ std::vector ov::hetero::SubgraphCollect auto subgraphs = collect_subgraphs(); // Subgraph topological sort - std::vector all_subgraphs; + SubgraphsVector all_subgraphs; for (const auto& subgraph : subgraphs) { all_subgraphs.emplace_back(std::move(subgraph.second)); } - std::vector ordered_subgraphs; + SubgraphsVector ordered_subgraphs; + using NodeSet = std::unordered_set>; NodeSet prev_results; size_t subgraph_topo_sorts_step = 0; do { OPENVINO_ASSERT(subgraph_topo_sorts_step < subgraphs.size(), "Cannot sort subgraphs!"); ++subgraph_topo_sorts_step; - std::vector new_ordered_subgraphs; + SubgraphsVector new_ordered_subgraphs; auto is_ordered_subgraph = [&](const Subgraph& subgraph) { auto& parameters = subgraph._parameters; - return std::all_of( - parameters.begin(), - parameters.end(), - [&](const ov::ParameterVector::value_type& parameter) { - return (_graph_input_nodes.find(parameter) != _graph_input_nodes.end()) || - (prev_results.find(_subgraph_parameter_to_prev_result[parameter]) != prev_results.end()); - }); + return std::all_of(parameters.begin(), + parameters.end(), + [&](const ov::ParameterVector::value_type& parameter) { + return (ov::util::contains(_origin_parameters, parameter) || + prev_results.count(_subgraph_parameter_to_prev_result[parameter])); + }); }; std::remove_copy_if(std::begin(all_subgraphs), std::end(all_subgraphs), @@ -257,27 +301,444 @@ std::vector ov::hetero::SubgraphCollect std::end(new_ordered_subgraphs), std::back_inserter(ordered_subgraphs)); } while (!all_subgraphs.empty()); - return ordered_subgraphs; + + // Get submodels mapping information + auto mapping_info = get_subgraphs_mapping_info(ordered_subgraphs); + + return {ordered_subgraphs, mapping_info}; } -std::unordered_map +std::unordered_map ov::hetero::SubgraphCollector::collect_subgraphs() { std::unordered_map subgraphs; - // Extracts subgraph parameters, results and affinities - for (const auto& subgraph_id_ptr_value : _subgraph_ids) { - auto node = subgraph_id_ptr_value.first; - auto& subgraph = subgraphs[subgraph_id_ptr_value.second]; + auto update_subgraph = [&](SubgraphId subgraph_id, const std::shared_ptr& node) { + auto& subgraph = subgraphs[subgraph_id]; + auto update_affinity = [&](const std::shared_ptr& node) { + auto it_affinity = _affinities.find(node); + if (it_affinity != _affinities.end()) { + subgraph._affinity = it_affinity->second; + } + }; if (ov::op::util::is_output(node)) { - subgraph._results.emplace_back(ov::as_type_ptr(node->shared_from_this())); + subgraph._results.emplace_back(ov::as_type_ptr(node)); + update_affinity(input_node(node->input(0))); } else if (ov::op::util::is_parameter(node)) { - subgraph._parameters.emplace_back(ov::as_type_ptr(node->shared_from_this())); + subgraph._parameters.emplace_back(ov::as_type_ptr(node)); + update_affinity(output_node(node->output(0))); } else if (ov::op::util::is_sink(node)) { - subgraph._sinks.emplace_back(ov::as_type_ptr(node->shared_from_this())); + subgraph._sinks.emplace_back(ov::as_type_ptr(node)); + update_affinity(input_node(node->input(0))); + } + }; + // Update subgraph parameters + for (auto& op_vec : {_origin_parameters, _intermediate_parameters}) { + for (const auto& op : op_vec) { + const auto node = std::dynamic_pointer_cast(op); + auto subgraph_id = _subgraph_ids.at(node); + update_subgraph(subgraph_id, node); } - auto it_affinity = _affinities.find(node); - if (it_affinity != _affinities.end()) { - subgraph._affinity = it_affinity->second; + } + // Update subgraph results + for (auto& op_vec : {_origin_results, _intermediate_results}) { + for (const auto& op : op_vec) { + const auto node = std::dynamic_pointer_cast(op); + auto subgraph_id = _subgraph_ids.at(node); + update_subgraph(subgraph_id, node); } } + // Update subgraph sinks + for (const auto& op : _origin_sinks) { + const auto node = std::dynamic_pointer_cast(op); + auto subgraph_id = _subgraph_ids.at(node); + update_subgraph(subgraph_id, node); + } return subgraphs; } + +ov::hetero::SubgraphsMappingInfo ov::hetero::SubgraphCollector::get_subgraphs_mapping_info( + const SubgraphsVector& ordered_subgraphs) { + SubgraphsMappingInfo info; + // Prepare mapping between original inputs/outputs and compiled + // submodels inputs/outputs. Example: + // original input 0 -> submodel 0 input 0, + // original input 1 -> submodel 1 input 0, + // original output 0 -> submodel 1 output 0. + // + // Mapping is required only because before compilation + // submodel may be preprocessed (if legacy API used), + // so original inputs/outputs != submodels inputs/outputs + info._inputs_to_submodels_inputs.resize(_origin_parameters.size()); + info._outputs_to_submodels_outputs.resize(_origin_results.size()); + for (size_t id = 0; id < ordered_subgraphs.size(); id++) { + for (size_t i = 0; i < ordered_subgraphs[id]._parameters.size(); i++) { + for (size_t j = 0; j < _origin_parameters.size(); j++) + if (ordered_subgraphs[id]._parameters[i] == _origin_parameters[j]) + info._inputs_to_submodels_inputs[j] = {id, i}; + } + for (size_t i = 0; i < ordered_subgraphs[id]._results.size(); i++) { + for (size_t j = 0; j < _origin_results.size(); j++) + if (ordered_subgraphs[id]._results[i] == _origin_results[j]) + info._outputs_to_submodels_outputs[j] = {id, i}; + } + } + // Prepare mapping between manually splitted inputs/outputs + // to connect tensors between compiled submodels + for (const auto& kvp : _subgraph_parameter_to_prev_result) { + const auto& intermed_output = ov::as_type_ptr(kvp.second); + const auto& intermed_input = ov::as_type_ptr(kvp.first); + for (size_t out_subgraph_index = 0; out_subgraph_index < ordered_subgraphs.size(); out_subgraph_index++) { + if (ov::util::contains(ordered_subgraphs[out_subgraph_index]._results, intermed_output)) { + for (size_t in_subgraph_index = 0; in_subgraph_index < ordered_subgraphs.size(); in_subgraph_index++) { + if (in_subgraph_index == out_subgraph_index) + continue; + if (ov::util::contains(ordered_subgraphs[in_subgraph_index]._parameters, intermed_input)) { + auto out_idx = get_index(ordered_subgraphs[out_subgraph_index]._results, intermed_output); + auto in_idx = get_index(ordered_subgraphs[in_subgraph_index]._parameters, intermed_input); + info._submodels_input_to_prev_output[{in_subgraph_index, in_idx}] = {out_subgraph_index, + out_idx}; + } + } + } + } + } + return info; +} + +void ov::hetero::merge_submodels(std::vector>& submodels, + const std::map& submodels_input_to_prev_output) { + // Results which should not be present in final graph + std::set result_names_to_be_removed; + // Remap port indexes to names, because order of them will be modified during merge + std::map, std::pair> input_to_prev_output; + for (const auto& kvp : submodels_input_to_prev_output) { + const auto& input_node = submodels[kvp.first.first]->inputs()[kvp.first.second].get_node(); + const auto& output_node = submodels[kvp.second.first]->outputs()[kvp.second.second].get_node(); + input_to_prev_output[{kvp.first.first, input_node->get_friendly_name()}] = {kvp.second.first, + output_node->get_friendly_name()}; + result_names_to_be_removed.insert(output_node->get_friendly_name()); + } + int submodel_in_index = static_cast(submodels.size()) - 1; + while (submodel_in_index >= 0 && input_to_prev_output.size() > 0) { + auto& submodel_in = submodels[submodel_in_index]; + size_t port_in_index = 0; + while (port_in_index < submodel_in->get_parameters().size()) { + auto parameter_to_replace = submodel_in->get_parameters()[port_in_index]; + auto item = input_to_prev_output.find({submodel_in_index, parameter_to_replace->get_friendly_name()}); + if (item == input_to_prev_output.end()) { + port_in_index++; + continue; + } + auto submodel_out_index = item->second.first; + auto submodel_out_result_name = item->second.second; + auto submodel_out = submodels.at(submodel_out_index); + + std::shared_ptr result_to_replace = nullptr; + for (auto& result : submodel_out->get_results()) { + if (result->get_friendly_name() == submodel_out_result_name) { + result_to_replace = result; + } + } + OPENVINO_ASSERT(result_to_replace != nullptr); + // Get all results from previous subgraph except already existed in next subgraph + auto add_results = addition(submodel_out->get_results(), submodel_in->get_results()); + + // Get all sinks from previous subgraph except already existed in next subgraph + auto add_sinks = addition(submodel_out->get_sinks(), submodel_in->get_sinks()); + + // Get all parameters from previous subgraph except already existed in next subgraph + auto add_parameters = addition(submodel_out->get_parameters(), submodel_in->get_parameters()); + + // Reconnect appropariate target inputs to the new source output + auto result_source = result_to_replace->get_input_source_output(0); + auto parameter_targets = parameter_to_replace->get_output_target_inputs(0); + for (auto parameter_target : parameter_targets) { + parameter_target.replace_source_output(result_source); + } + + // Update parameter and results + submodel_in->remove_parameter(parameter_to_replace); + submodel_in->add_parameters(add_parameters); + submodel_in->add_results(add_results); + submodel_in->add_sinks(add_sinks); + + // Remove processed connection + input_to_prev_output.erase(item); + + // Update incoming model since it is merged + for (size_t i = 0; i < submodels.size(); i++) { + if (submodels[i] == submodel_out) { + submodels[i] = submodel_in; + } + } + + // Start check ports from the beginning because number of ports are modified + port_in_index = 0; + } + --submodel_in_index; + } + // Finally all subgraphs should be merged into single one + OPENVINO_ASSERT(input_to_prev_output.size() == 0); + auto& result_model = submodels[0]; + for (size_t i = 1; i < submodels.size(); i++) { + if (submodels[i] != result_model) { + result_model->add_parameters(submodels[i]->get_parameters()); + result_model->add_results(submodels[i]->get_results()); + result_model->add_sinks(submodels[i]->get_sinks()); + } + submodels[i] = result_model; + } + OPENVINO_ASSERT(all_of(submodels.begin(), submodels.end(), [&](const std::shared_ptr& submodel) { + return submodel == result_model; + })); + // Cleanup intermidiate results + for (size_t i = 0; i < result_model->get_results().size();) { + auto& result = result_model->get_results()[i]; + if (result_names_to_be_removed.count(result->get_friendly_name())) { + result_model->remove_result(result); + } else { + i++; + } + } + submodels.resize(1); +} + +std::pair ov::hetero::get_model_subgraphs( + const std::shared_ptr& model, + ov::SupportedOpsMap& supported_ops, + const bool user_set_affinities, + const bool dump_dot_files, + const std::string default_device) { + std::unordered_set devices; + ov::hetero::SubgraphCollector::AffinitiesMap affinities; + ov::SupportedOpsMap debug_supported_ops{supported_ops}; + // Check that all nodes has user or plugin defined affinitie + std::function&, const std::string&)> collect_affinities = + [&](const std::shared_ptr& model, const std::string& default_device) { + for (const auto& node : model->get_ordered_ops()) { + auto it_affinity = supported_ops.find(node->get_friendly_name()); + if (it_affinity != supported_ops.end()) { + affinities[node] = it_affinity->second; + devices.emplace(it_affinity->second); + } else if (!default_device.empty()) { + affinities[node] = default_device; + devices.emplace(default_device); + debug_supported_ops.insert({node->get_friendly_name(), default_device}); + } else if (!user_set_affinities) { + OPENVINO_THROW("Hetero device used default fallback policy, but some layers eg: \n(Name:", + node->get_friendly_name(), + ", Type: ", + node->get_type_name(), + ") were not able to be assigned on any pointed device.\n", + "It happened because these layers are not supported in plugins by default.\n", + "You need to implement custom layers to support them."); + } else { + OPENVINO_THROW( + "Model passed to CompiledModel has affinity assigned, but some layers eg: \n(Name:", + node->get_friendly_name(), + ", Type: ", + node->get_type_name(), + ") were not assigned to any device.\n", + "It might happen if you assigned layers manually and missed some layers or\n", + "if you used some automatic assigning mode which decided that these layers are not\n", + "supported by any plugin"); + } + if (dump_dot_files) { + if (auto multi_subgraph_op = std::dynamic_pointer_cast(node)) { + for (size_t i = 0; i < multi_subgraph_op->get_internal_subgraphs_size(); ++i) { + if (const auto& sub_graph = multi_subgraph_op->get_function(i)) { + collect_affinities(sub_graph, debug_supported_ops.at(node->get_friendly_name())); + } + } + } + } + } + }; + collect_affinities(model, default_device); + if (dump_dot_files) { + ov::hetero::debug::dump_affinities(model, debug_supported_ops, devices); + } + + // Init subgraph collector + ov::hetero::SubgraphCollector subgraph_collector(model, affinities); + + if (dump_dot_files) { + auto subgraph_ids = subgraph_collector.get_subgraph_ids(); + std::map map_id; + std::function&, const ov::hetero::SubgraphCollector::SubgraphId&)> + collect_map_id = [&](const std::shared_ptr& model, + const ov::hetero::SubgraphCollector::SubgraphId& default_id) { + for (const auto& node : model->get_ordered_ops()) { + ov::hetero::SubgraphCollector::SubgraphId subgraph_id; + if (subgraph_ids.count(node)) { + subgraph_id = subgraph_ids.at(node); + } else { + OPENVINO_ASSERT(default_id >= 0, "Invalid default id for node " + node->get_friendly_name()); + subgraph_id = default_id; + } + map_id.emplace(node->get_friendly_name(), subgraph_id); + if (auto multi_subgraph_op = std::dynamic_pointer_cast(node)) { + for (size_t i = 0; i < multi_subgraph_op->get_internal_subgraphs_size(); ++i) { + if (const auto& sub_graph = multi_subgraph_op->get_function(i)) { + collect_map_id(sub_graph, subgraph_id); + } + } + } + } + }; + collect_map_id(model, -1); + ov::hetero::debug::dump_subgraphs(model, debug_supported_ops, map_id); + } + + // Get subgraphs sorted topologically and appropriate mapping information + return subgraph_collector.run(); +} + +ov::hetero::SubgraphsMappingInfo ov::hetero::mask_model_subgraphs_by_ops(std::shared_ptr& model, + ov::SupportedOpsMap& supported_ops, + const bool dump_dot_files, + const std::string default_device) { + const std::string subgraph_id_rt_info_name = "HETERO_SUBGRAPH_ID"; + const std::string input_id_rt_info_name = "HETERO_INPUT_ID"; + const std::string output_id_rt_info_name = "HETERO_OUTPUT_ID"; + const auto name = model->get_friendly_name(); + + SubgraphsVector ordered_subgraphs; + SubgraphsMappingInfo mapping_info; + std::tie(ordered_subgraphs, mapping_info) = + get_model_subgraphs(model, supported_ops, false, dump_dot_files, default_device); + + SubmodelsVector submodels{ordered_subgraphs.size()}; + for (size_t i = 0; i < ordered_subgraphs.size(); i++) { + const auto& subgraph = ordered_subgraphs.at(i); + auto submodel_name = name + '_' + std::to_string(i); + submodels[i] = + std::make_shared(subgraph._results, subgraph._sinks, subgraph._parameters, submodel_name); + const auto& submodel = submodels[i]; + // Check whether model is subgraph already + bool is_subgraph = ov::op::util::has_op_with_type(submodel); + if (is_subgraph) { + for (auto& op : submodel->get_ordered_ops()) { + if (!ov::as_type_ptr(op) && !ov::op::util::is_parameter(op) && + !ov::op::util::is_output(op) && !ov::op::util::is_sink(op)) { + is_subgraph = false; + break; + } + } + } + if (subgraph._affinity != default_device && !is_subgraph) { + // Replace submodel by subgraph operation + ParameterVector subgraph_parameters{submodel->inputs().size()}; + OutputVector args{submodel->inputs().size()}; + for (size_t j = 0; j < submodel->inputs().size(); j++) { + auto const& input = submodel->input(j); + subgraph_parameters[j] = + std::make_shared(input.get_element_type(), input.get_partial_shape()); + supported_ops[subgraph_parameters[j]->get_friendly_name()] = subgraph._affinity; + args[j] = subgraph_parameters[j]->output(0); + } + auto subgraph_op = std::make_shared(args, submodel, subgraph._affinity); + supported_ops[subgraph_op->get_friendly_name()] = subgraph._affinity; + ResultVector subgraph_results{subgraph_op->outputs().size()}; + for (size_t j = 0; j < subgraph_op->outputs().size(); j++) { + const auto& output = subgraph_op->output(j); + subgraph_results[j] = std::make_shared(output); + supported_ops[subgraph_results[j]->get_friendly_name()] = subgraph._affinity; + } + submodels[i] = std::make_shared(subgraph_results, subgraph_parameters); + } + // Store original subgraph id + for (auto& op : submodels[i]->get_ordered_ops()) { + if (auto subgraph_op = ov::as_type_ptr(op)) { + auto& rt_info = op->get_rt_info(); + rt_info[subgraph_id_rt_info_name] = i; + + const auto& parameters = submodels[i]->get_parameters(); + OPENVINO_ASSERT(parameters.size() == op->inputs().size()); + for (auto& input : op->inputs()) { + const auto& source_output = input.get_source_output().get_node()->shared_from_this(); + if (auto parameter = ov::as_type_ptr(source_output)) { + input.get_rt_info()[input_id_rt_info_name] = get_index(parameters, parameter); + } + } + + const auto& results = submodels[i]->get_results(); + OPENVINO_ASSERT(results.size() == op->outputs().size()); + for (auto& output : op->outputs()) { + for (auto& input : output.get_target_inputs()) { + auto target_input = input.get_node()->shared_from_this(); + if (auto result = ov::as_type_ptr(target_input)) { + output.get_rt_info()[output_id_rt_info_name] = get_index(results, result); + } + } + } + } + } + } + + merge_submodels(submodels, mapping_info._submodels_input_to_prev_output); + + model = submodels[0]; + + // Finally update mapping information according to the new operation order + std::map subgraph_id_map; + std::map> input_id_map; + std::map> output_id_map; + size_t subgraph_op_id = 0; + for (auto& op : model->get_ordered_ops()) { + if (ov::as_type_ptr(op)) { + auto& rt_info = op->get_rt_info(); + subgraph_id_map[rt_info[subgraph_id_rt_info_name].as()] = subgraph_op_id; + rt_info.erase(subgraph_id_rt_info_name); + for (size_t j = 0; j < op->inputs().size(); j++) { + auto& input_rt_info = op->input(j).get_rt_info(); + input_id_map[subgraph_op_id][input_rt_info[input_id_rt_info_name].as()] = j; + input_rt_info.erase(input_id_rt_info_name); + } + for (size_t j = 0; j < op->outputs().size(); j++) { + auto& output_rt_info = op->output(j).get_rt_info(); + output_id_map[subgraph_op_id][output_rt_info[output_id_rt_info_name].as()] = j; + output_rt_info.erase(output_id_rt_info_name); + } + subgraph_op_id++; + } + } + SubgraphsMappingInfo new_mapping_info; + if (ordered_subgraphs.size() == subgraph_op_id) { + // Only if all subgraphs were replaced by subgraph operations + // we can provide appropriate mapping information + // otherwise this information is unavailable + auto get_new_subgraph_index = [&subgraph_id_map](const size_t old_subgraph_index) { + OPENVINO_ASSERT(subgraph_id_map.count(old_subgraph_index)); + return subgraph_id_map.at(old_subgraph_index); + }; + auto get_new_input_index = [&input_id_map](const size_t subgraph_index, const size_t old_input_index) { + OPENVINO_ASSERT(input_id_map.at(subgraph_index).count(old_input_index)); + return input_id_map.at(subgraph_index).at(old_input_index); + }; + auto get_new_output_index = [&output_id_map](const size_t subgraph_index, const size_t old_output_index) { + OPENVINO_ASSERT(output_id_map.at(subgraph_index).count(old_output_index)); + return output_id_map.at(subgraph_index).at(old_output_index); + }; + for (auto& item : mapping_info._inputs_to_submodels_inputs) { + const auto& subgraph_index = get_new_subgraph_index(item.first); + const auto& input_index = get_new_input_index(subgraph_index, item.second); + new_mapping_info._inputs_to_submodels_inputs.push_back({subgraph_index, input_index}); + } + for (auto& item : mapping_info._outputs_to_submodels_outputs) { + const auto& subgraph_index = get_new_subgraph_index(item.first); + const auto& output_index = get_new_output_index(subgraph_index, item.second); + new_mapping_info._outputs_to_submodels_outputs.push_back({subgraph_index, output_index}); + } + for (auto& item : mapping_info._submodels_input_to_prev_output) { + const auto& subgraph_in_index = get_new_subgraph_index(item.first.first); + const auto& input_index = get_new_input_index(subgraph_in_index, item.first.second); + + const auto& subgraph_out_index = get_new_subgraph_index(item.second.first); + const auto& output_index = get_new_output_index(subgraph_out_index, item.second.second); + + new_mapping_info._submodels_input_to_prev_output[{subgraph_in_index, input_index}] = {subgraph_out_index, + output_index}; + } + } + return new_mapping_info; +} diff --git a/src/plugins/hetero/src/subgraph_collector.hpp b/src/plugins/hetero/src/subgraph_collector.hpp index cf04a73b0789e9..ceab333d38e293 100644 --- a/src/plugins/hetero/src/subgraph_collector.hpp +++ b/src/plugins/hetero/src/subgraph_collector.hpp @@ -13,49 +13,81 @@ namespace ov { namespace hetero { +using NodeInfo = std::pair; + +struct SubgraphsMappingInfo { + std::vector _inputs_to_submodels_inputs; + std::vector _outputs_to_submodels_outputs; + std::map _submodels_input_to_prev_output; + bool empty() { + return _inputs_to_submodels_inputs.empty() && _outputs_to_submodels_outputs.empty() && + _submodels_input_to_prev_output.empty(); + } +}; +struct Subgraph { + ov::ResultVector _results; + ov::ParameterVector _parameters; + ov::SinkVector _sinks; + std::string _affinity; +}; +using SubgraphsVector = std::vector; +using SubmodelsVector = std::vector>; class SubgraphCollector { public: - struct Subgraph { - ov::ResultVector _results; - ov::ParameterVector _parameters; - ov::SinkVector _sinks; - std::string _affinity; - }; template using NodeMap = std::unordered_map, T>; - using NodeSet = std::unordered_set>; using AffinitiesMap = NodeMap; using SubgraphId = int; using SubgraphIdsMap = NodeMap; using ParameterResultMap = NodeMap>; using Input = ov::Input; + using Output = ov::Output; using InputSet = std::set; - + using OutputSet = std::set; + using InputVector = std::vector; + using OutputVector = std::vector; SubgraphCollector(const std::shared_ptr& model, const AffinitiesMap& affinities); SubgraphIdsMap get_subgraph_ids() { return _subgraph_ids; } - ParameterResultMap get_subgraph_parameter_to_prev_result() { - return _subgraph_parameter_to_prev_result; - } - std::vector get_ordered_subgraphs(); + std::pair run(); private: void init(); + bool is_graph_input_node(const ov::Node* node) const; void split_cyclic_dependencies(); void split_subgraphs_by_parameter_results(); SubgraphIdsMap collect_subgraphs_ids(); std::unordered_map collect_subgraphs(); + SubgraphsMappingInfo get_subgraphs_mapping_info(const std::vector& ordered_subgraphs); std::shared_ptr input_node(const Input& input) const; + std::shared_ptr output_node(const Output& output) const; ov::NodeVector _ordered_ops; + ov::ParameterVector _origin_parameters; + ov::ResultVector _origin_results; + ov::SinkVector _origin_sinks; + ov::ParameterVector _intermediate_parameters; + ov::ResultVector _intermediate_results; AffinitiesMap _affinities; - NodeSet _graph_input_nodes; NodeMap _node_input_dependencies; InputSet _subgraph_inputs; SubgraphIdsMap _subgraph_ids; ParameterResultMap _subgraph_parameter_to_prev_result; }; +void merge_submodels(SubmodelsVector& submodels, const std::map& submodels_input_to_prev_output); + +std::pair get_model_subgraphs(const std::shared_ptr& model, + ov::SupportedOpsMap& supported_ops, + const bool user_set_affinities = false, + const bool dump_dot_files = false, + const std::string default_device = ""); + +SubgraphsMappingInfo mask_model_subgraphs_by_ops(std::shared_ptr& model, + ov::SupportedOpsMap& supported_ops, + const bool dump_dot_files = false, + const std::string default_device = ""); + } // namespace hetero } // namespace ov diff --git a/src/plugins/hetero/src/sync_infer_request.cpp b/src/plugins/hetero/src/sync_infer_request.cpp index ab97eb3df0a129..21fbd0b4f2e2a3 100644 --- a/src/plugins/hetero/src/sync_infer_request.cpp +++ b/src/plugins/hetero/src/sync_infer_request.cpp @@ -24,16 +24,16 @@ ov::hetero::InferRequest::InferRequest(const std::shared_ptrinputs().size(); i++) { const auto& port = compiled_model->inputs()[i]; - const auto& submodel_idx = compiled_model->m_inputs_to_submodels_inputs[i].first; + const auto& submodel_idx = compiled_model->m_mapping_info._inputs_to_submodels_inputs[i].first; m_port_to_subrequest_idx[port] = submodel_idx; } for (size_t i = 0; i < compiled_model->outputs().size(); i++) { const auto& port = compiled_model->outputs()[i]; - const auto& submodel_idx = compiled_model->m_outputs_to_submodels_outputs[i].first; + const auto& submodel_idx = compiled_model->m_mapping_info._outputs_to_submodels_outputs[i].first; m_port_to_subrequest_idx[port] = submodel_idx; } - for (const auto& kvp : compiled_model->m_submodels_input_to_prev_output) { + for (const auto& kvp : compiled_model->m_mapping_info._submodels_input_to_prev_output) { const auto& submodel_idx_in = kvp.first.first; const auto& port_idx_in = kvp.first.second; const auto& submodel_idx_out = kvp.second.first; diff --git a/src/plugins/hetero/tests/unit/subgraph_collector.cpp b/src/plugins/hetero/tests/unit/subgraph_collector.cpp index 1a710a4cc53250..9a707b336fa101 100644 --- a/src/plugins/hetero/tests/unit/subgraph_collector.cpp +++ b/src/plugins/hetero/tests/unit/subgraph_collector.cpp @@ -7,6 +7,7 @@ #include #include "common_test_utils/graph_comparator.hpp" +#include "op/device_subgraph.hpp" #include "openvino/core/except.hpp" #include "openvino/op/ops.hpp" @@ -30,6 +31,27 @@ std::shared_ptr create_test_model() { result->set_friendly_name("res"); return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); } +std::shared_ptr create_test_model2() { + auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + param->set_friendly_name("input"); + auto const_value = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); + const_value->set_friendly_name("const_val"); + auto add1 = std::make_shared(param, const_value); + add1->set_friendly_name("add1"); + auto add2 = std::make_shared(add1, const_value); + add2->set_friendly_name("add2"); + auto subtract = std::make_shared(add2, const_value); + subtract->set_friendly_name("sub"); + auto add3 = std::make_shared(add1, subtract); + add3->set_friendly_name("add3"); + auto reshape_val = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1}, {-1}); + reshape_val->set_friendly_name("reshape_val"); + auto reshape = std::make_shared(add3, reshape_val, true); + reshape->set_friendly_name("reshape"); + auto result = std::make_shared(reshape); + result->set_friendly_name("res"); + return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); +} std::shared_ptr create_subgraph_add() { auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); param->set_friendly_name("input"); @@ -37,24 +59,42 @@ std::shared_ptr create_subgraph_add() { const_value->set_friendly_name("const_val"); auto add = std::make_shared(param, const_value); add->set_friendly_name("add"); - auto result = std::make_shared(add); - result->set_friendly_name("add_0_result"); - return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); + return std::make_shared(ov::OutputVector{add->output(0)}, ov::ParameterVector{param}); +} +std::shared_ptr create_subgraph_add_add() { + auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + param->set_friendly_name("input"); + auto const_value = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); + const_value->set_friendly_name("const_val"); + auto add1 = std::make_shared(param, const_value); + add1->set_friendly_name("add1"); + auto add2 = std::make_shared(add1, const_value); + add2->set_friendly_name("add2"); + return std::make_shared(ov::OutputVector{add2->output(0), add1->output(0)}, ov::ParameterVector{param}); } std::shared_ptr create_subgraph_sub() { auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); - param->set_friendly_name("add_0_parameter"); auto const_value = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); const_value->set_friendly_name("const_val"); auto sub = std::make_shared(param, const_value); sub->set_friendly_name("sub"); - auto result = std::make_shared(sub); - result->set_friendly_name("sub_0_result"); - return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); + return std::make_shared(ov::OutputVector{sub->output(0)}, ov::ParameterVector{param}); +} +std::shared_ptr create_subgraph_add_reshape() { + auto param0 = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + auto param1 = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + auto add = std::make_shared(param0, param1); + add->set_friendly_name("add_second"); + auto reshape_val = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1}, {-1}); + reshape_val->set_friendly_name("reshape_val"); + auto reshape = std::make_shared(add, reshape_val, true); + reshape->set_friendly_name("reshape"); + auto result = std::make_shared(reshape); + result->set_friendly_name("res"); + return std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param0, param1}); } std::shared_ptr create_subgraph_reshape() { auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); - param->set_friendly_name("sub_0_parameter"); auto reshape_val = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1}, {-1}); reshape_val->set_friendly_name("reshape_val"); auto reshape = std::make_shared(param, reshape_val, true); @@ -68,6 +108,7 @@ std::shared_ptr create_subgraph_reshape() { class SubgraphCollectorTest : public testing::Test { void SetUp() override { m_model = create_test_model(); + m_model_ref = m_model->clone(); m_submodels = {}; m_submodels.push_back(create_subgraph_add()); m_submodels.push_back(create_subgraph_sub()); @@ -78,10 +119,11 @@ class SubgraphCollectorTest : public testing::Test { protected: std::shared_ptr m_model; + std::shared_ptr m_model_ref; std::vector> m_submodels; }; -TEST_F(SubgraphCollectorTest, check_subgraphs) { +TEST_F(SubgraphCollectorTest, submodel_split_and_merge) { const std::map supported_ops = { {"input", "MOCK.0"}, {"const_val", "MOCK.0"}, @@ -100,10 +142,13 @@ TEST_F(SubgraphCollectorTest, check_subgraphs) { {"reshape", 3}, {"res", 3}, }; - const std::map expected_parameter_to_prev_result_names = { - {"sub_0_parameter", "sub_0_result"}, - {"add_0_parameter", "add_0_result"}, - }; + const SubgraphsMappingInfo exptected_mapping_info = {{// inputs to submodel inputs + NodeInfo{0, 0}}, + {// outputs to submodel outpts + NodeInfo{2, 0}}, + {// submodel input to previous output + {NodeInfo{1, 0}, NodeInfo{0, 0}}, + {NodeInfo{2, 0}, NodeInfo{1, 0}}}}; SubgraphCollector::AffinitiesMap affinities; SubgraphCollector::SubgraphIdsMap exptected_subgraphs_ids; const auto ordered_ops = m_model->get_ordered_ops(); @@ -114,30 +159,323 @@ TEST_F(SubgraphCollectorTest, check_subgraphs) { OPENVINO_ASSERT(expected_ids.count(name)); exptected_subgraphs_ids[node] = expected_ids.at(name); } + // Collect subgraphs SubgraphCollector subgraph_collector(m_model, affinities); auto actual_subgraphs_ids = subgraph_collector.get_subgraph_ids(); - for (auto& op : ordered_ops) { - ASSERT_EQ(actual_subgraphs_ids.at(op), exptected_subgraphs_ids.at(op)); + ASSERT_EQ(exptected_subgraphs_ids, actual_subgraphs_ids); + ov::hetero::SubgraphsVector actual_subgraphs; + ov::hetero::SubgraphsMappingInfo actual_mapping_info; + std::tie(actual_subgraphs, actual_mapping_info) = subgraph_collector.run(); + + ASSERT_EQ(3, actual_subgraphs.size()); + std::vector> actual_submodels; + for (auto& actual_subgraph : actual_subgraphs) { + actual_submodels.push_back(std::make_shared(actual_subgraph._results, actual_subgraph._parameters)); } - // Subgraphs are not collected yet - ASSERT_EQ(0, subgraph_collector.get_subgraph_parameter_to_prev_result().size()); - // Collect subgraphs - auto actual_subgraphs = subgraph_collector.get_ordered_subgraphs(); - const size_t submodels_number = 3; - ASSERT_EQ(submodels_number, actual_subgraphs.size()); - auto get_submodel = [&](size_t i) { - return std::make_shared(actual_subgraphs.at(i)._results, actual_subgraphs.at(i)._parameters); + for (size_t i = 0; i < actual_submodels.size(); i++) { + auto res = compare_functions(m_submodels.at(i), actual_submodels.at(i)); + ASSERT_TRUE(res.first) << res.second; + } + + // Check mapping info + ASSERT_EQ(exptected_mapping_info._inputs_to_submodels_inputs, actual_mapping_info._inputs_to_submodels_inputs); + ASSERT_EQ(exptected_mapping_info._outputs_to_submodels_outputs, actual_mapping_info._outputs_to_submodels_outputs); + ASSERT_EQ(exptected_mapping_info._submodels_input_to_prev_output, + actual_mapping_info._submodels_input_to_prev_output); + + // Merge submodels into one model back + ov::hetero::merge_submodels(actual_submodels, actual_mapping_info._submodels_input_to_prev_output); + ASSERT_EQ(1, actual_submodels.size()); + auto& actual_model = actual_submodels[0]; + auto res = compare_functions(m_model_ref, actual_model); + ASSERT_TRUE(res.first) << res.second; +} + +TEST_F(SubgraphCollectorTest, submodel_replacement_first_device) { + const std::map supported_ops_mock0 = { + {"input", "MOCK.0"}, + {"const_val", "MOCK.0"}, + {"add", "MOCK.0"}, + {"reshape_val", "MOCK.0"}, + {"reshape", "MOCK.0"}, + {"res", "MOCK.0"}, + }; + { + auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + param->set_friendly_name("input"); + + auto device_subgraph0 = std::make_shared(ov::OutputVector{param->output(0)}, + m_submodels.at(0), + "MOCK.0"); + device_subgraph0->set_friendly_name("device_subgraph0"); + + auto const_value = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); + const_value->set_friendly_name("const_val"); + auto subtract = std::make_shared(device_subgraph0->output(0), const_value); + subtract->set_friendly_name("sub"); + + auto device_subgraph1 = std::make_shared(ov::OutputVector{subtract->output(0)}, + m_submodels.at(2), + "MOCK.0"); + device_subgraph1->set_friendly_name("device_subgraph1"); + + auto result = std::make_shared(device_subgraph1->output(0)); + result->set_friendly_name("res"); + m_model_ref = std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); + } + auto supported_ops = supported_ops_mock0; + auto actual_mapping_info = ov::hetero::mask_model_subgraphs_by_ops(m_model, supported_ops, false, "TEST"); + auto res = compare_functions(m_model_ref, m_model); + ASSERT_TRUE(res.first) << res.second; + + // Only first device was replace, mapping is unavailable + ASSERT_TRUE(actual_mapping_info.empty()); +} + +TEST_F(SubgraphCollectorTest, submodel_replacement_both_devices) { + const std::map supported_ops_mock0 = { + {"input", "MOCK.0"}, + {"const_val", "MOCK.0"}, + {"add", "MOCK.0"}, + {"reshape_val", "MOCK.0"}, + {"reshape", "MOCK.0"}, + {"res", "MOCK.0"}, + }; + const std::map supported_ops_mock1 = { + {"sub", "MOCK.1"}, }; - std::pair res; - for (size_t i = 0; i < submodels_number; i++) { - auto submodel = get_submodel(i); - auto res = compare_functions(m_submodels.at(i), submodel); + const SubgraphsMappingInfo exptected_mapping_info = {{// inputs to submodel inputs + NodeInfo{0, 0}}, + {// outputs to submodel outpts + NodeInfo{2, 0}}, + {// submodel input to previous output + {NodeInfo{1, 0}, NodeInfo{0, 0}}, + {NodeInfo{2, 0}, NodeInfo{1, 0}}}}; + { + auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + param->set_friendly_name("input"); + + auto device_subgraph0 = std::make_shared(ov::OutputVector{param->output(0)}, + m_submodels.at(0), + "MOCK.0"); + device_subgraph0->set_friendly_name("device_subgraph0"); + + auto device_subgraph1 = + std::make_shared(ov::OutputVector{device_subgraph0->output(0)}, + m_submodels.at(1), + "MOCK.1"); + device_subgraph1->set_friendly_name("device_subgraph1"); + + auto device_subgraph2 = + std::make_shared(ov::OutputVector{device_subgraph1->output(0)}, + m_submodels.at(2), + "MOCK.0"); + device_subgraph2->set_friendly_name("device_subgraph2"); + + auto result = std::make_shared(device_subgraph2->output(0)); + result->set_friendly_name("res"); + m_model_ref = std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); + } + ov::hetero::SubgraphsMappingInfo actual_mapping_info; + auto supported_ops = supported_ops_mock0; + ASSERT_EQ(6, supported_ops.size()); + actual_mapping_info = ov::hetero::mask_model_subgraphs_by_ops(m_model, supported_ops, false, "TEST"); + // + 2 subgraphs + 2 params + 2 results + ASSERT_EQ(12, supported_ops.size()); + // Adds mock1 supported operations + supported_ops.insert(supported_ops_mock1.begin(), supported_ops_mock1.end()); + ASSERT_EQ(13, supported_ops.size()); + actual_mapping_info = ov::hetero::mask_model_subgraphs_by_ops(m_model, supported_ops, false); + // + 1 subgraphs + 1 param + 1 result + ASSERT_EQ(16, supported_ops.size()); + auto res = compare_functions(m_model_ref, m_model); + ASSERT_TRUE(res.first) << res.second; + + ASSERT_EQ(exptected_mapping_info._inputs_to_submodels_inputs, actual_mapping_info._inputs_to_submodels_inputs); + ASSERT_EQ(exptected_mapping_info._outputs_to_submodels_outputs, actual_mapping_info._outputs_to_submodels_outputs); + ASSERT_EQ(exptected_mapping_info._submodels_input_to_prev_output, + actual_mapping_info._submodels_input_to_prev_output); +} + +class SubgraphCollectorTest2 : public SubgraphCollectorTest { + void SetUp() override { + m_model = create_test_model2(); + m_model_ref = m_model->clone(); + m_submodels = {}; + m_submodels.push_back(create_subgraph_add_add()); + m_submodels.push_back(create_subgraph_sub()); + m_submodels.push_back(create_subgraph_add_reshape()); + } +}; + +TEST_F(SubgraphCollectorTest2, submodel_split_and_merge) { + const std::map supported_ops = { + {"input", "MOCK.0"}, + {"const_val", "MOCK.0"}, + {"add1", "MOCK.0"}, + {"add2", "MOCK.0"}, + {"sub", "MOCK.1"}, + {"add3", "MOCK.0"}, + {"reshape_val", "MOCK.0"}, + {"reshape", "MOCK.0"}, + {"res", "MOCK.0"}, + }; + const SubgraphsMappingInfo exptected_mapping_info = {{// inputs to submodel inputs + NodeInfo{0, 0}}, + {// outputs to submodel outpts + NodeInfo{2, 0}}, + {// submodel input to previous output + {NodeInfo{1, 0}, NodeInfo{0, 0}}, + {NodeInfo{2, 0}, NodeInfo{0, 1}}, + {NodeInfo{2, 1}, NodeInfo{1, 0}}}}; + SubgraphCollector::AffinitiesMap affinities; + const auto ordered_ops = m_model->get_ordered_ops(); + for (const auto& node : ordered_ops) { + const auto name = node->get_friendly_name(); + OPENVINO_ASSERT(supported_ops.count(name)); + affinities[node] = supported_ops.at(name); + } + // Collect subgraphs + SubgraphCollector subgraph_collector(m_model, affinities); + ov::hetero::SubgraphsVector actual_subgraphs; + ov::hetero::SubgraphsMappingInfo actual_mapping_info; + std::tie(actual_subgraphs, actual_mapping_info) = subgraph_collector.run(); + + ASSERT_EQ(3, actual_subgraphs.size()); + std::vector> actual_submodels; + for (auto& actual_subgraph : actual_subgraphs) { + actual_submodels.push_back(std::make_shared(actual_subgraph._results, actual_subgraph._parameters)); + } + for (size_t i = 0; i < actual_submodels.size(); i++) { + auto res = compare_functions(m_submodels.at(i), actual_submodels.at(i)); ASSERT_TRUE(res.first) << res.second; } - auto actual_parameter_to_prev_result = subgraph_collector.get_subgraph_parameter_to_prev_result(); - ASSERT_EQ(actual_parameter_to_prev_result.size(), expected_parameter_to_prev_result_names.size()); - for (auto& item : actual_parameter_to_prev_result) { - ASSERT_EQ(item.second->get_friendly_name(), - expected_parameter_to_prev_result_names.at(item.first->get_friendly_name())); + + // Check mapping info + ASSERT_EQ(exptected_mapping_info._inputs_to_submodels_inputs, actual_mapping_info._inputs_to_submodels_inputs); + ASSERT_EQ(exptected_mapping_info._outputs_to_submodels_outputs, actual_mapping_info._outputs_to_submodels_outputs); + ASSERT_EQ(exptected_mapping_info._submodels_input_to_prev_output, + actual_mapping_info._submodels_input_to_prev_output); + + // Merge submodels into one model back + ov::hetero::merge_submodels(actual_submodels, actual_mapping_info._submodels_input_to_prev_output); + ASSERT_EQ(1, actual_submodels.size()); + auto& actual_model = actual_submodels[0]; + auto res = compare_functions(m_model_ref, actual_model); + ASSERT_TRUE(res.first) << res.second; +} + +TEST_F(SubgraphCollectorTest2, submodel_replacement_first_device) { + const std::map supported_ops_mock0 = { + {"input", "MOCK.0"}, + {"const_val", "MOCK.0"}, + {"add1", "MOCK.0"}, + {"add2", "MOCK.0"}, + {"add3", "MOCK.0"}, + {"reshape_val", "MOCK.0"}, + {"reshape", "MOCK.0"}, + {"res", "MOCK.0"}, + }; + { + auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + param->set_friendly_name("input"); + + auto device_subgraph0 = std::make_shared(ov::OutputVector{param->output(0)}, + m_submodels.at(0), + "MOCK.0"); + device_subgraph0->set_friendly_name("device_subgraph0"); + + auto const_value = ov::op::v0::Constant::create(ov::element::i64, ov::Shape{1, 1, 1, 1}, {1}); + const_value->set_friendly_name("const_val"); + auto subtract = std::make_shared(device_subgraph0->output(0), const_value); + subtract->set_friendly_name("sub"); + + auto device_subgraph2 = std::make_shared( + ov::OutputVector{device_subgraph0->output(0), subtract->output(0)}, + m_submodels.at(2), + "MOCK.0"); + device_subgraph2->set_friendly_name("device_subgraph2"); + + auto result = std::make_shared(device_subgraph2->output(0)); + result->set_friendly_name("res"); + m_model_ref = std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); } + auto supported_ops = supported_ops_mock0; + ASSERT_EQ(8, supported_ops.size()); + auto actual_mapping_info = ov::hetero::mask_model_subgraphs_by_ops(m_model, supported_ops, false, "TEST"); + // + 2 subgraphs + 3 params + 3 results + ASSERT_EQ(16, supported_ops.size()); + auto res = compare_functions(m_model_ref, m_model); + ASSERT_TRUE(res.first) << res.second; + + // Only first device was replace, mapping is unavailable + ASSERT_TRUE(actual_mapping_info.empty()); } + +TEST_F(SubgraphCollectorTest2, submodel_replacement_both_devices) { + const std::map supported_ops_mock0 = { + {"input", "MOCK.0"}, + {"const_val", "MOCK.0"}, + {"add1", "MOCK.0"}, + {"add2", "MOCK.0"}, + {"add3", "MOCK.0"}, + {"reshape_val", "MOCK.0"}, + {"reshape", "MOCK.0"}, + {"res", "MOCK.0"}, + }; + const std::map supported_ops_mock1 = { + {"sub", "MOCK.1"}, + }; + const SubgraphsMappingInfo exptected_mapping_info = {{// inputs to submodel inputs + NodeInfo{0, 0}}, + {// outputs to submodel outpts + NodeInfo{2, 0}}, + {// submodel input to previous output + {NodeInfo{1, 0}, NodeInfo{0, 0}}, + {NodeInfo{2, 0}, NodeInfo{0, 1}}, + {NodeInfo{2, 1}, NodeInfo{1, 0}}}}; + { + auto param = std::make_shared(ov::element::i64, ov::PartialShape{1, 3, 2, 2}); + param->set_friendly_name("input"); + + auto device_subgraph0 = std::make_shared(ov::OutputVector{param->output(0)}, + m_submodels.at(0), + "MOCK.0"); + device_subgraph0->set_friendly_name("device_subgraph0"); + + auto device_subgraph1 = + std::make_shared(ov::OutputVector{device_subgraph0->output(1)}, + m_submodels.at(1), + "MOCK.1"); + device_subgraph1->set_friendly_name("device_subgraph1"); + + auto device_subgraph2 = std::make_shared( + ov::OutputVector{device_subgraph0->output(0), device_subgraph1->output(0)}, + m_submodels.at(2), + "MOCK.0"); + device_subgraph2->set_friendly_name("device_subgraph2"); + + auto result = std::make_shared(device_subgraph2->output(0)); + result->set_friendly_name("res"); + m_model_ref = std::make_shared(ov::ResultVector{result}, ov::ParameterVector{param}); + } + ov::hetero::SubgraphsMappingInfo actual_mapping_info; + auto supported_ops = supported_ops_mock0; + ASSERT_EQ(8, supported_ops.size()); + actual_mapping_info = ov::hetero::mask_model_subgraphs_by_ops(m_model, supported_ops, false, "TEST"); + // + 2 subgraphs + 3 params + 3 results + ASSERT_EQ(16, supported_ops.size()); + // Adds mock1 supported operations + supported_ops.insert(supported_ops_mock1.begin(), supported_ops_mock1.end()); + ASSERT_EQ(17, supported_ops.size()); + actual_mapping_info = ov::hetero::mask_model_subgraphs_by_ops(m_model, supported_ops, false); + // + 1 subgraphs + 1 param + 1 result + ASSERT_EQ(20, supported_ops.size()); + auto res = compare_functions(m_model_ref, m_model); + ASSERT_TRUE(res.first) << res.second; + + ASSERT_EQ(exptected_mapping_info._inputs_to_submodels_inputs, actual_mapping_info._inputs_to_submodels_inputs); + ASSERT_EQ(exptected_mapping_info._outputs_to_submodels_outputs, actual_mapping_info._outputs_to_submodels_outputs); + ASSERT_EQ(exptected_mapping_info._submodels_input_to_prev_output, + actual_mapping_info._submodels_input_to_prev_output); +} \ No newline at end of file diff --git a/src/plugins/intel_cpu/docs/selective_build.md b/src/plugins/intel_cpu/docs/selective_build.md index 714a385b43e041..e7811091240a2e 100644 --- a/src/plugins/intel_cpu/docs/selective_build.md +++ b/src/plugins/intel_cpu/docs/selective_build.md @@ -69,7 +69,7 @@ cmake .. \ -DENABLE_DEBUG_CAPS=ON \ -DSELECTIVE_BUILD=ON \ -DSELECTIVE_BUILD_STAT= \ --DPYTHON_EXECUTABLE=/usr/bin/python3.7 \ +-DPython3_EXECUTABLE=/usr/bin/python3.7 \ -DCMAKE_INSTALL_PREFIX=`pwd`/install \ -DCMAKE_INSTALL_RPATH=`pwd`/install/runtime/3rdparty/tbb/lib:`pwd`/install/runtime/lib/intel64 diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/grn.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/grn.cpp index 632beec01b42d6..1dfc6ad90540b3 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/grn.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/grn.cpp @@ -4,31 +4,30 @@ #include -#include "single_layer_tests/grn.hpp" +#include "single_op_tests/grn.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; - namespace { -const std::vector netPrecisions = { - InferenceEngine::Precision::BF16, - InferenceEngine::Precision::FP16, - InferenceEngine::Precision::FP32, +using ov::test::GrnLayerTest; + +std::vector model_types = { + ov::element::bf16, + ov::element::f16, + ov::element::f32, }; +std::vector> input_shapes_static = { + {{16, 24}}, + {{3, 16, 24}}, + {{1, 3, 30, 30}}, + {{2, 16, 15, 20}}}; + +std::vector bias = {1e-6f, 0.33f, 1.1f, 2.25f, 100.25f}; + const auto basicCases = ::testing::Combine( - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - // input shapes - ::testing::Values(std::vector{16, 24}, - std::vector{3, 16, 24}, - std::vector{1, 3, 30, 30}, - std::vector{2, 16, 15, 20}), - // bias - ::testing::Values(1e-6f, 0.33f, 1.1f, 2.25f, 100.25f), + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_static)), + ::testing::ValuesIn(bias), ::testing::Values(ov::test::utils::DEVICE_CPU)); INSTANTIATE_TEST_SUITE_P(smoke_GRN_Basic, GrnLayerTest, diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution.cpp index ac6b132dd53e16..790147b0260e0c 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution.cpp @@ -5,152 +5,155 @@ #include #include "common_test_utils/test_constants.hpp" -#include "single_layer_tests/group_convolution.hpp" - -using namespace LayerTestsDefinitions; +#include "single_op_tests/group_convolution.hpp" namespace { - -const std::vector netPrecisions = { - InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP16, - InferenceEngine::Precision::I32}; - -/* ============= 1D GroupConvolution ============= */ -const std::vector> kernels1d = {{3}}; -const std::vector> strides1d = {{1}}; -const std::vector> padBegins1d = {{0}}; -const std::vector> padEnds1d = {{0}}; -const std::vector> dilations1d = {{1}}; -const std::vector numOutChannels1d = {8, 16}; -const std::vector numGroups1d = {2, 8}; -const auto inputShapes1d = std::vector({1, 16, 30}); - -const auto groupConv1DParams_ExplicitPadding = ::testing::Combine( - ::testing::ValuesIn(kernels1d), ::testing::ValuesIn(strides1d), - ::testing::ValuesIn(padBegins1d), ::testing::ValuesIn(padEnds1d), - ::testing::ValuesIn(dilations1d), ::testing::ValuesIn(numOutChannels1d), - ::testing::ValuesIn(numGroups1d), - ::testing::Values(ngraph::op::PadType::EXPLICIT)); -const auto groupConv1DParams_AutoPadValid = ::testing::Combine( - ::testing::ValuesIn(kernels1d), ::testing::ValuesIn(strides1d), +using ov::test::GroupConvolutionLayerTest; + +const std::vector model_types = { + ov::element::f32, + ov::element::f16, + ov::element::i32}; + +/* ============= _1d GroupConvolution ============= */ +const std::vector input_shapes_1d = {{1, 16, 30}}; + +const std::vector> kernels_1d = {{3}}; +const std::vector> strides_1d = {{1}}; +const std::vector> pad_begins_1d = {{0}}; +const std::vector> pad_ends_1d = {{0}}; +const std::vector> dilations_1d = {{1}}; +const std::vector num_out_channels_1d = {8, 16}; +const std::vector num_groups_1d = {2, 8}; + +const auto group_conv_1d_params_explicit_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_1d), + ::testing::ValuesIn(strides_1d), + ::testing::ValuesIn(pad_begins_1d), + ::testing::ValuesIn(pad_ends_1d), + ::testing::ValuesIn(dilations_1d), + ::testing::ValuesIn(num_out_channels_1d), + ::testing::ValuesIn(num_groups_1d), + ::testing::Values(ov::op::PadType::EXPLICIT)); + +const auto group_conv_1d_params_auto_pad_valid = ::testing::Combine( + ::testing::ValuesIn(kernels_1d), ::testing::ValuesIn(strides_1d), ::testing::Values(std::vector({0})), ::testing::Values(std::vector({0})), - ::testing::ValuesIn(dilations1d), ::testing::ValuesIn(numOutChannels1d), - ::testing::ValuesIn(numGroups1d), - ::testing::Values(ngraph::op::PadType::VALID)); + ::testing::ValuesIn(dilations_1d), ::testing::ValuesIn(num_out_channels_1d), + ::testing::ValuesIn(num_groups_1d), + ::testing::Values(ov::op::PadType::VALID)); INSTANTIATE_TEST_SUITE_P( smoke_GroupConvolution1D_ExplicitPadding, GroupConvolutionLayerTest, ::testing::Combine( - groupConv1DParams_ExplicitPadding, ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector(inputShapes1d)), + group_conv_1d_params_explicit_padding, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_1d)), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvolutionLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P( smoke_GroupConvolution1D_AutoPadValid, GroupConvolutionLayerTest, ::testing::Combine( - groupConv1DParams_AutoPadValid, ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({1, 16, 30})), + group_conv_1d_params_auto_pad_valid, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_1d)), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvolutionLayerTest::getTestCaseName); /* ============= 2D GroupConvolution ============= */ -const std::vector> kernels = {{3, 3}}; -const std::vector> strides = {{1, 1}}; -const std::vector> padBegins = {{0, 0}}; -const std::vector> padEnds = {{0, 0}}; -const std::vector> dilations = {{1, 1}}; -const std::vector numOutChannels = {8, 16}; -const std::vector numGroups = {2, 8}; -const auto inputShapes = std::vector({1, 16, 30, 30}); - -const auto groupConv2DParams_ExplicitPadding = ::testing::Combine( - ::testing::ValuesIn(kernels), ::testing::ValuesIn(strides), - ::testing::ValuesIn(padBegins), ::testing::ValuesIn(padEnds), - ::testing::ValuesIn(dilations), ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::EXPLICIT)); -const auto groupConv2DParams_AutoPadValid = ::testing::Combine( - ::testing::ValuesIn(kernels), ::testing::ValuesIn(strides), +const std::vector input_shapes_2d = {{1, 16, 30, 30}}; + +const std::vector> kernels_2d = {{3, 3}}; +const std::vector> strides_2d = {{1, 1}}; +const std::vector> pad_begins_2d = {{0, 0}}; +const std::vector> pad_ends_2d = {{0, 0}}; +const std::vector> dilations_2d = {{1, 1}}; +const std::vector num_out_channels_2d = {8, 16}; +const std::vector num_groups_2d = {2, 8}; + +const auto group_conv2DParams_explicit_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_2d), + ::testing::ValuesIn(strides_2d), + ::testing::ValuesIn(pad_begins_2d), + ::testing::ValuesIn(pad_ends_2d), + ::testing::ValuesIn(dilations_2d), + ::testing::ValuesIn(num_out_channels_2d), + ::testing::ValuesIn(num_groups_2d), + ::testing::Values(ov::op::PadType::EXPLICIT)); + +const auto group_conv2DParams_auto_pad_valid = ::testing::Combine( + ::testing::ValuesIn(kernels_2d), + ::testing::ValuesIn(strides_2d), ::testing::Values(std::vector({0, 0})), ::testing::Values(std::vector({0, 0})), - ::testing::ValuesIn(dilations), ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::VALID)); + ::testing::ValuesIn(dilations_2d), + ::testing::ValuesIn(num_out_channels_2d), + ::testing::ValuesIn(num_groups_2d), + ::testing::Values(ov::op::PadType::VALID)); INSTANTIATE_TEST_SUITE_P( smoke_GroupConvolution2D_ExplicitPadding, GroupConvolutionLayerTest, ::testing::Combine( - groupConv2DParams_ExplicitPadding, ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector(inputShapes)), + group_conv2DParams_explicit_padding, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_2d)), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvolutionLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P( smoke_GroupConvolution2D_AutoPadValid, GroupConvolutionLayerTest, ::testing::Combine( - groupConv2DParams_AutoPadValid, ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({1, 16, 30, 30})), + group_conv2DParams_auto_pad_valid, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_2d)), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvolutionLayerTest::getTestCaseName); /* ============= 3D GroupConvolution ============= */ -const std::vector> kernels3d = {{3, 3, 3}}; -const std::vector> paddings3d = {{0, 0, 0}}; -const std::vector> strides3d = {{1, 1, 1}}; -const std::vector> dilations3d = {{1, 1, 1}}; -const auto inputShapes3d = std::vector({1, 4, 10, 10, 10}); - -const auto groupConv3DParams_ExplicitPadding = ::testing::Combine( - ::testing::ValuesIn(kernels3d), ::testing::ValuesIn(strides3d), - ::testing::ValuesIn(paddings3d), ::testing::ValuesIn(paddings3d), - ::testing::ValuesIn(dilations3d), ::testing::Values(4), - ::testing::Values(2), ::testing::Values(ngraph::op::PadType::EXPLICIT)); -const auto groupConv3DParams_AutoPadValid = ::testing::Combine( - ::testing::ValuesIn(kernels3d), ::testing::ValuesIn(strides3d), +const std::vector input_shapes_3d = {{1, 4, 10, 10, 10}}; + +const std::vector> kernels_3d = {{3, 3, 3}}; +const std::vector> paddings_3d = {{0, 0, 0}}; +const std::vector> strides_3d = {{1, 1, 1}}; +const std::vector> dilations_3d = {{1, 1, 1}}; + +const auto group_conv3DParams_explicit_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_3d), + ::testing::ValuesIn(strides_3d), + ::testing::ValuesIn(paddings_3d), + ::testing::ValuesIn(paddings_3d), + ::testing::ValuesIn(dilations_3d), + ::testing::Values(4), + ::testing::Values(2), + ::testing::Values(ov::op::PadType::EXPLICIT)); + +const auto group_conv3DParams_auto_pad_valid = ::testing::Combine( + ::testing::ValuesIn(kernels_3d), + ::testing::ValuesIn(strides_3d), ::testing::Values(std::vector({0, 0, 0})), ::testing::Values(std::vector({0, 0, 0})), - ::testing::ValuesIn(dilations3d), ::testing::Values(4), - ::testing::Values(2), ::testing::Values(ngraph::op::PadType::VALID)); + ::testing::ValuesIn(dilations_3d), + ::testing::Values(4), + ::testing::Values(2), + ::testing::Values(ov::op::PadType::VALID)); INSTANTIATE_TEST_SUITE_P( smoke_GroupConvolution3D_ExplicitPadding, GroupConvolutionLayerTest, ::testing::Combine( - groupConv3DParams_ExplicitPadding, ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector(inputShapes3d)), + group_conv3DParams_explicit_padding, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_3d)), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvolutionLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P( smoke_GroupConvolution3D_AutoPadValid, GroupConvolutionLayerTest, ::testing::Combine( - groupConv3DParams_AutoPadValid, ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({1, 4, 10, 10, 10})), + group_conv3DParams_auto_pad_valid, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_3d)), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvolutionLayerTest::getTestCaseName); diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution_backprop_data.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution_backprop_data.cpp index 397b52e56703fe..d59b1d2df26902 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution_backprop_data.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/group_convolution_backprop_data.cpp @@ -5,330 +5,281 @@ #include #include "common_test_utils/test_constants.hpp" -#include "single_layer_tests/group_convolution_backprop_data.hpp" - -using namespace LayerTestsDefinitions; +#include "single_op_tests/group_convolution_backprop_data.hpp" namespace { - -const std::vector netPrecisions = { - InferenceEngine::Precision::FP32, - InferenceEngine::Precision::FP16, - InferenceEngine::Precision::I32}; - -const std::vector numOutChannels = {16, 32}; -const std::vector numGroups = {2, 8, 16}; -const std::vector> emptyOutputShape = {{}}; -const std::vector> emptyOutputPadding = {{}}; - -/* ============= 1D GroupConvolution ============= */ -const std::vector> inputShapes1D = {{1, 16, 32}}; - -const std::vector> kernels1D = {{1}, {3}}; -const std::vector> strides1D = {{1}}; -const std::vector> padBegins1D = {{0}}; -const std::vector> padEnds1D = {{0}}; -const std::vector> dilations1D = {{1}}; - -const auto groupConvBackpropData1DParams_ExplicitPadding = ::testing::Combine( - ::testing::ValuesIn(kernels1D), - ::testing::ValuesIn(strides1D), - ::testing::ValuesIn(padBegins1D), - ::testing::ValuesIn(padEnds1D), - ::testing::ValuesIn(dilations1D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::EXPLICIT), - ::testing::ValuesIn(emptyOutputPadding) +using ov::test::GroupConvBackpropLayerTest; + +const std::vector model_types = { + ov::element::f32, + ov::element::f16, + ov::element::i32}; + +const std::vector num_out_channels = {16, 32}; +const std::vector num_groups = {2, 8, 16}; +const std::vector empty_output_shape = {{}}; +const std::vector> empty_output_padding = {{}}; + +/* ============= _1d GroupConvolution ============= */ +const std::vector input_shapes_1d = {{1, 16, 32}}; + +const std::vector> kernels_1d = {{1}, {3}}; +const std::vector> strides_1d = {{1}}; +const std::vector> pad_begins_1d = {{0}}; +const std::vector> pad_ends_1d = {{0}}; +const std::vector> dilations_1d = {{1}}; + +const auto groupConvBackpropData_1dParams_ExplicitPadding = ::testing::Combine( + ::testing::ValuesIn(kernels_1d), + ::testing::ValuesIn(strides_1d), + ::testing::ValuesIn(pad_begins_1d), + ::testing::ValuesIn(pad_ends_1d), + ::testing::ValuesIn(dilations_1d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::EXPLICIT), + ::testing::ValuesIn(empty_output_padding) ); -const auto groupConvBackpropData1DParams_AutoPadValid = ::testing::Combine( - ::testing::ValuesIn(kernels1D), - ::testing::ValuesIn(strides1D), - ::testing::ValuesIn(padBegins1D), - ::testing::ValuesIn(padEnds1D), - ::testing::ValuesIn(dilations1D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::VALID), - ::testing::ValuesIn(emptyOutputPadding) +const auto groupConvBackpropData_1dParams_AutoPadValid = ::testing::Combine( + ::testing::ValuesIn(kernels_1d), + ::testing::ValuesIn(strides_1d), + ::testing::ValuesIn(pad_begins_1d), + ::testing::ValuesIn(pad_ends_1d), + ::testing::ValuesIn(dilations_1d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::VALID), + ::testing::ValuesIn(empty_output_padding) ); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData1D_ExplicitPadding, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_1d_ExplicitPadding, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData1DParams_ExplicitPadding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes1D), - ::testing::ValuesIn(emptyOutputShape), + groupConvBackpropData_1dParams_ExplicitPadding, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_1d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData1D_AutoPadValid, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_1d_AutoPadValid, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData1DParams_AutoPadValid, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes1D), - ::testing::ValuesIn(emptyOutputShape), + groupConvBackpropData_1dParams_AutoPadValid, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shapes_1d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -/* ============= 2D GroupConvolution ============= */ -const std::vector> inputShapes2D = {{1, 16, 10, 10}, - {1, 32, 10, 10}}; -const std::vector> kernels2D = {{1, 1}, {3, 3}}; -const std::vector> strides2D = {{1, 1}}; -const std::vector> padBegins2D = {{0, 0}}; -const std::vector> padEnds2D = {{0, 0}}; -const std::vector> dilations2D = {{1, 1}}; - -const auto groupConvBackpropData2DParams_ExplicitPadding = ::testing::Combine( - ::testing::ValuesIn(kernels2D), - ::testing::ValuesIn(strides2D), - ::testing::ValuesIn(padBegins2D), - ::testing::ValuesIn(padEnds2D), - ::testing::ValuesIn(dilations2D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::EXPLICIT), - ::testing::ValuesIn(emptyOutputPadding) +/* ============= _2d GroupConvolution ============= */ +const std::vector> input_shapes_2d = {{{1, 16, 10, 10}}, + {{1, 32, 10, 10}}}; +const std::vector> kernels_2d = {{1, 1}, {3, 3}}; +const std::vector> strides_2d = {{1, 1}}; +const std::vector> pad_begins_2d = {{0, 0}}; +const std::vector> pad_ends_2d = {{0, 0}}; +const std::vector> dilations_2d = {{1, 1}}; + +const auto groupConvBackpropData_2dParams_ExplicitPadding = ::testing::Combine( + ::testing::ValuesIn(kernels_2d), + ::testing::ValuesIn(strides_2d), + ::testing::ValuesIn(pad_begins_2d), + ::testing::ValuesIn(pad_ends_2d), + ::testing::ValuesIn(dilations_2d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::EXPLICIT), + ::testing::ValuesIn(empty_output_padding) ); -const auto groupConvBackpropData2DParams_AutoPadValid = ::testing::Combine( - ::testing::ValuesIn(kernels2D), - ::testing::ValuesIn(strides2D), - ::testing::ValuesIn(padBegins2D), - ::testing::ValuesIn(padEnds2D), - ::testing::ValuesIn(dilations2D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::VALID), - ::testing::ValuesIn(emptyOutputPadding) +const auto groupConvBackpropData_2dParams_AutoPadValid = ::testing::Combine( + ::testing::ValuesIn(kernels_2d), + ::testing::ValuesIn(strides_2d), + ::testing::ValuesIn(pad_begins_2d), + ::testing::ValuesIn(pad_ends_2d), + ::testing::ValuesIn(dilations_2d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::VALID), + ::testing::ValuesIn(empty_output_padding) ); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData2D_ExplicitPadding, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_2d_ExplicitPadding, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData2DParams_ExplicitPadding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes2D), - ::testing::ValuesIn(emptyOutputShape), + groupConvBackpropData_2dParams_ExplicitPadding, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_2d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData2D_AutoPadValid, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_2d_AutoPadValid, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData2DParams_AutoPadValid, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes2D), - ::testing::ValuesIn(emptyOutputShape), + groupConvBackpropData_2dParams_AutoPadValid, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_2d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -const std::vector> inputShape2D = {{1, 16, 9, 12}}; -const std::vector> outputShapes2D = {{6, 6}, {4, 9}}; +const std::vector input_shape_2d = {{1, 16, 9, 12}}; +const std::vector output_shapes_2d = {{6, 6}, {4, 9}}; -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData2D_OutputShapeDefined, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_2d_OutputShapeDefined, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData2DParams_AutoPadValid, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShape2D), - ::testing::ValuesIn(outputShapes2D), + groupConvBackpropData_2dParams_AutoPadValid, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shape_2d)), + ::testing::ValuesIn(output_shapes_2d), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -const std::vector> outputPadding2D = {{1, 1}, {2, 2}}; -const std::vector> testStrides2D = {{3, 3}}; - -const auto conv2DParams_ExplicitPadding_output_padding = ::testing::Combine( - ::testing::ValuesIn(kernels2D), - ::testing::ValuesIn(testStrides2D), - ::testing::ValuesIn(padBegins2D), - ::testing::ValuesIn(padEnds2D), - ::testing::ValuesIn(dilations2D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::EXPLICIT), - ::testing::ValuesIn(outputPadding2D) +const std::vector> output_padding_2d = {{1, 1}, {2, 2}}; +const std::vector> test_strides_2d = {{3, 3}}; + +const auto conv_2dParams_ExplicitPadding_output_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_2d), + ::testing::ValuesIn(test_strides_2d), + ::testing::ValuesIn(pad_begins_2d), + ::testing::ValuesIn(pad_ends_2d), + ::testing::ValuesIn(dilations_2d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::EXPLICIT), + ::testing::ValuesIn(output_padding_2d) ); -const auto conv2DParams_AutoPadValid_output_padding = ::testing::Combine( - ::testing::ValuesIn(kernels2D), - ::testing::ValuesIn(testStrides2D), +const auto conv_2dParams_AutoPadValid_output_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_2d), + ::testing::ValuesIn(test_strides_2d), ::testing::Values(std::vector({0, 0})), ::testing::Values(std::vector({0, 0})), - ::testing::ValuesIn(dilations2D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::VALID), - ::testing::ValuesIn(outputPadding2D) + ::testing::ValuesIn(dilations_2d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::VALID), + ::testing::ValuesIn(output_padding_2d) ); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData2D_ExplicitPadding_OutputPaddingDefined, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_2d_ExplicitPadding_output_paddingDefined, GroupConvBackpropLayerTest, ::testing::Combine( - conv2DParams_AutoPadValid_output_padding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes2D), - ::testing::ValuesIn(emptyOutputShape), + conv_2dParams_AutoPadValid_output_padding, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_2d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData2D_AutoPadding_OutputPaddingDefined, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_2d_AutoPadding_output_paddingDefined, GroupConvBackpropLayerTest, ::testing::Combine( - conv2DParams_ExplicitPadding_output_padding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes2D), - ::testing::ValuesIn(emptyOutputShape), + conv_2dParams_ExplicitPadding_output_padding, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_2d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -/* ============= 3D GroupConvolution ============= */ -const std::vector> inputShapes3D = {{1, 16, 5, 5, 5}, - {1, 32, 5, 5, 5}}; -const std::vector> kernels3D = {{1, 1, 1}, {3, 3, 3}}; -const std::vector> strides3D = {{1, 1, 1}}; -const std::vector> padBegins3D = {{0, 0, 0}}; -const std::vector> padEnds3D = {{0, 0, 0}}; -const std::vector> dilations3D = {{1, 1, 1}}; - -const auto groupConvBackpropData3DParams_ExplicitPadding = ::testing::Combine( - ::testing::ValuesIn(kernels3D), - ::testing::ValuesIn(strides3D), - ::testing::ValuesIn(padBegins3D), - ::testing::ValuesIn(padEnds3D), - ::testing::ValuesIn(dilations3D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::EXPLICIT), - ::testing::ValuesIn(emptyOutputPadding) +/* ============= _3d GroupConvolution ============= */ +const std::vector> input_shapes_3d = {{{1, 16, 5, 5, 5}}, + {{1, 32, 5, 5, 5}}}; +const std::vector> kernels_3d = {{1, 1, 1}, {3, 3, 3}}; +const std::vector> strides_3d = {{1, 1, 1}}; +const std::vector> pad_begins_3d = {{0, 0, 0}}; +const std::vector> pad_ends_3d = {{0, 0, 0}}; +const std::vector> dilations_3d = {{1, 1, 1}}; + +const auto groupConvBackpropData_3dParams_ExplicitPadding = ::testing::Combine( + ::testing::ValuesIn(kernels_3d), + ::testing::ValuesIn(strides_3d), + ::testing::ValuesIn(pad_begins_3d), + ::testing::ValuesIn(pad_ends_3d), + ::testing::ValuesIn(dilations_3d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::EXPLICIT), + ::testing::ValuesIn(empty_output_padding) ); -const auto groupConvBackpropData3DParams_AutoPadValid = ::testing::Combine( - ::testing::ValuesIn(kernels3D), - ::testing::ValuesIn(strides3D), - ::testing::ValuesIn(padBegins3D), - ::testing::ValuesIn(padEnds3D), - ::testing::ValuesIn(dilations3D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::VALID), - ::testing::ValuesIn(emptyOutputPadding) +const auto groupConvBackpropData_3dParams_AutoPadValid = ::testing::Combine( + ::testing::ValuesIn(kernels_3d), + ::testing::ValuesIn(strides_3d), + ::testing::ValuesIn(pad_begins_3d), + ::testing::ValuesIn(pad_ends_3d), + ::testing::ValuesIn(dilations_3d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::VALID), + ::testing::ValuesIn(empty_output_padding) ); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData3D_ExplicitPadding, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_3d_ExplicitPadding, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData3DParams_ExplicitPadding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes3D), - ::testing::ValuesIn(emptyOutputShape), + groupConvBackpropData_3dParams_ExplicitPadding, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_3d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData3D_AutoPadValid, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_3d_AutoPadValid, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData3DParams_AutoPadValid, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes3D), - ::testing::ValuesIn(emptyOutputShape), + groupConvBackpropData_3dParams_AutoPadValid, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_3d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -const std::vector> inputShape3D = {{1, 16, 10, 10, 10}}; -const std::vector> outputShapes3D = {{8, 8, 8}, {10, 10, 10}}; +const std::vector input_shape_3d = {{1, 16, 10, 10, 10}}; +const std::vector output_shapes_3d = {{8, 8, 8}, {10, 10, 10}}; -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData3D_OutputShapeDefined, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_3d_OutputShapeDefined, GroupConvBackpropLayerTest, ::testing::Combine( - groupConvBackpropData3DParams_AutoPadValid, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShape3D), - ::testing::ValuesIn(outputShapes3D), + groupConvBackpropData_3dParams_AutoPadValid, + ::testing::ValuesIn(model_types), + ::testing::Values(ov::test::static_shapes_to_test_representation(input_shape_3d)), + ::testing::ValuesIn(output_shapes_3d), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -const std::vector> outputPadding3D = {{1, 1, 1}, {2, 2, 2}}; -const std::vector> testStrides3D = {{3, 3, 3}}; - -const auto conv3DParams_ExplicitPadding_output_padding = ::testing::Combine( - ::testing::ValuesIn(kernels3D), - ::testing::ValuesIn(testStrides3D), - ::testing::ValuesIn(padBegins3D), - ::testing::ValuesIn(padEnds3D), - ::testing::ValuesIn(dilations3D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::EXPLICIT), - ::testing::ValuesIn(outputPadding3D) +const std::vector> output_padding_3d = {{1, 1, 1}, {2, 2, 2}}; +const std::vector> test_strides_3d = {{3, 3, 3}}; + +const auto conv_3dParams_ExplicitPadding_output_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_3d), + ::testing::ValuesIn(test_strides_3d), + ::testing::ValuesIn(pad_begins_3d), + ::testing::ValuesIn(pad_ends_3d), + ::testing::ValuesIn(dilations_3d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::EXPLICIT), + ::testing::ValuesIn(output_padding_3d) ); -const auto conv3DParams_AutoPadValid_output_padding = ::testing::Combine( - ::testing::ValuesIn(kernels3D), - ::testing::ValuesIn(testStrides3D), +const auto conv_3dParams_AutoPadValid_output_padding = ::testing::Combine( + ::testing::ValuesIn(kernels_3d), + ::testing::ValuesIn(test_strides_3d), ::testing::Values(std::vector({0, 0, 0})), ::testing::Values(std::vector({0, 0, 0})), - ::testing::ValuesIn(dilations3D), - ::testing::ValuesIn(numOutChannels), - ::testing::ValuesIn(numGroups), - ::testing::Values(ngraph::op::PadType::VALID), - ::testing::ValuesIn(outputPadding3D) + ::testing::ValuesIn(dilations_3d), + ::testing::ValuesIn(num_out_channels), + ::testing::ValuesIn(num_groups), + ::testing::Values(ov::op::PadType::VALID), + ::testing::ValuesIn(output_padding_3d) ); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData3D_ExplicitPadding_OutputPaddingDefined, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_3d_ExplicitPadding_output_paddingDefined, GroupConvBackpropLayerTest, ::testing::Combine( - conv3DParams_AutoPadValid_output_padding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes3D), - ::testing::ValuesIn(emptyOutputShape), + conv_3dParams_AutoPadValid_output_padding, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_3d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); -INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData3D_AutoPadding_OutputPaddingDefined, GroupConvBackpropLayerTest, +INSTANTIATE_TEST_SUITE_P(smoke_GroupConvBackpropData_3d_AutoPadding_output_paddingDefined, GroupConvBackpropLayerTest, ::testing::Combine( - conv3DParams_ExplicitPadding_output_padding, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::ValuesIn(inputShapes3D), - ::testing::ValuesIn(emptyOutputShape), + conv_3dParams_ExplicitPadding_output_padding, + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(input_shapes_3d)), + ::testing::ValuesIn(empty_output_shape), ::testing::Values(ov::test::utils::DEVICE_CPU)), GroupConvBackpropLayerTest::getTestCaseName); diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/gru_cell.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/gru_cell.cpp index 40169d3b12c036..8c2424c72b2fa8 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/gru_cell.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/gru_cell.cpp @@ -4,12 +4,12 @@ #include -#include "single_layer_tests/gru_cell.hpp" +#include "single_op_tests/gru_cell.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; - namespace { +using ov::test::GRUCellTest; + std::vector should_decompose{false, true}; std::vector batch{5}; std::vector hidden_size{1, 10}; @@ -18,12 +18,12 @@ namespace { {"tanh", "relu"}}; std::vector clip = {0.0f, 0.7f}; std::vector linear_before_reset = {true, false}; - std::vector layer_types = { - ngraph::helpers::InputLayerType::CONSTANT, - ngraph::helpers::InputLayerType::PARAMETER + std::vector layer_types = { + ov::test::utils::InputLayerType::CONSTANT, + ov::test::utils::InputLayerType::PARAMETER }; - std::vector netPrecisions = {InferenceEngine::Precision::FP32, - InferenceEngine::Precision::FP16}; + std::vector model_types = {ov::element::f32, + ov::element::f16}; INSTANTIATE_TEST_SUITE_P(smoke_GRUCellCommon, GRUCellTest, ::testing::Combine( @@ -37,7 +37,7 @@ namespace { ::testing::ValuesIn(layer_types), ::testing::ValuesIn(layer_types), ::testing::ValuesIn(layer_types), - ::testing::ValuesIn(netPrecisions), + ::testing::ValuesIn(model_types), ::testing::Values(ov::test::utils::DEVICE_CPU)), GRUCellTest::getTestCaseName); diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/roll.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/roll.cpp index a72c1d1e9d6361..ca6f5e21a11af4 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/roll.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/roll.cpp @@ -4,101 +4,109 @@ #include -#include "single_layer_tests/roll.hpp" +#include "single_op_tests/roll.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; +using ov::test::RollLayerTest; namespace { -const std::vector inputPrecision = { - InferenceEngine::Precision::I8, - InferenceEngine::Precision::U8, - InferenceEngine::Precision::I16, - InferenceEngine::Precision::I32, - InferenceEngine::Precision::FP32, - InferenceEngine::Precision::BF16 +const std::vector model_types = { + ov::element::i8, + ov::element::u8, + ov::element::i16, + ov::element::i32, + ov::element::f32, + ov::element::bf16 }; -const auto testCase2DZeroShifts = ::testing::Combine( - ::testing::Values(std::vector{17, 19}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{0, 0}), // Shift - ::testing::Values(std::vector{0, 1}), // Axes +const auto test_case_2D_zero_shifts = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{17, 19}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{0, 0}), // Shift + ::testing::Values(std::vector{0, 1}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCase1D = ::testing::Combine( - ::testing::Values(std::vector{16}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{5}), // Shift - ::testing::Values(std::vector{0}), // Axes +const auto test_case_1D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({ov::Shape{16}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{5}), // Shift + ::testing::Values(std::vector{0}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCase2D = ::testing::Combine( - ::testing::Values(std::vector{600, 450}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{300, 250}), // Shift - ::testing::Values(std::vector{0, 1}), // Axes +const auto test_case_2D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{600, 450}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{300, 250}), // Shift + ::testing::Values(std::vector{0, 1}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCase3D = ::testing::Combine( - ::testing::Values(std::vector{2, 320, 320}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{160, 160}), // Shift - ::testing::Values(std::vector{1, 2}), // Axes +const auto test_case_3D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{2, 320, 320}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{160, 160}), // Shift + ::testing::Values(std::vector{1, 2}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCaseNegativeUnorderedAxes4D = ::testing::Combine( - ::testing::Values(std::vector{3, 11, 6, 4}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{7, 3}), // Shift - ::testing::Values(std::vector{-3, -2}), // Axes +const auto test_case_negative_unordered_axes_4D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{3, 11, 6, 4}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{7, 3}), // Shift + ::testing::Values(std::vector{-3, -2}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCaseRepeatingAxes5D = ::testing::Combine( - ::testing::Values(std::vector{2, 16, 32, 7, 32}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{16, 15, 10, 2, 1, 7, 2, 8, 1, 1}), // Shift +const auto test_case_repeating_axes_5D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{2, 16, 32, 7, 32}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{16, 15, 10, 2, 1, 7, 2, 8, 1, 1}), // Shift ::testing::Values(std::vector{-1, -2, -3, 1, 0, 3, 3, 2, -2, -3}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCaseNegativeShifts6D = ::testing::Combine( - ::testing::Values(std::vector{4, 16, 3, 6, 5, 2}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{-2, -15, -2, -1, -4, -1}), // Shift - ::testing::Values(std::vector{0, 1, 2, 3, 4, 5}), // Axes +const auto test_case_negative_shifts_6D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{4, 16, 3, 6, 5, 2}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{-2, -15, -2, -1, -4, -1}), // Shift + ::testing::Values(std::vector{0, 1, 2, 3, 4, 5}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const auto testCaseUnordNegAxesAndShifts10D = ::testing::Combine( - ::testing::Values(std::vector{2, 2, 4, 2, 3, 6, 3, 2, 3, 2}), // Input shape - ::testing::ValuesIn(inputPrecision), // Precision - ::testing::Values(std::vector{-2, -1, 1, 1, 1, -2}), // Shift - ::testing::Values(std::vector{-6, -4, -3, 1, -10, -2}), // Axes +const auto test_case_unord_neg_axes_and_shifts_10D = ::testing::Combine( + ::testing::Values( + ov::test::static_shapes_to_test_representation({{2, 2, 4, 2, 3, 6, 3, 2, 3, 2}})), // Input shape + ::testing::ValuesIn(model_types), // Model type + ::testing::Values(std::vector{-2, -1, 1, 1, 1, -2}), // Shift + ::testing::Values(std::vector{-6, -4, -3, 1, -10, -2}), // Axes ::testing::Values(ov::test::utils::DEVICE_CPU) ); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_2d_zero_shifts, RollLayerTest, - testCase2DZeroShifts, RollLayerTest::getTestCaseName); + test_case_2D_zero_shifts, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_1d, RollLayerTest, - testCase1D, RollLayerTest::getTestCaseName); + test_case_1D, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_2d, RollLayerTest, - testCase2D, RollLayerTest::getTestCaseName); + test_case_2D, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_3d, RollLayerTest, - testCase3D, RollLayerTest::getTestCaseName); + test_case_3D, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_negative_unordered_axes_4d, RollLayerTest, - testCaseNegativeUnorderedAxes4D, RollLayerTest::getTestCaseName); + test_case_negative_unordered_axes_4D, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_negative_unordered_axes_5d, RollLayerTest, - testCaseRepeatingAxes5D, RollLayerTest::getTestCaseName); + test_case_repeating_axes_5D, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_negative_shifts_6d, RollLayerTest, - testCaseNegativeShifts6D, RollLayerTest::getTestCaseName); + test_case_negative_shifts_6D, RollLayerTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_TestsRoll_unord_neg_shifts_and_axes_10d, RollLayerTest, - testCaseUnordNegAxesAndShifts10D, RollLayerTest::getTestCaseName); + test_case_unord_neg_axes_and_shifts_10D, RollLayerTest::getTestCaseName); } // namespace diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_ND_update.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_ND_update.cpp index 355ddec8eea859..e0944b30efaba3 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_ND_update.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_ND_update.cpp @@ -3,36 +3,60 @@ // #include -#include -#include "single_layer_tests/scatter_ND_update.hpp" +#include "single_op_tests/scatter_ND_update.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; -using namespace ngraph::opset3; +using ov::test::ScatterNDUpdateLayerTest; namespace { -const std::vector inputPrecisions = { - InferenceEngine::Precision::FP32, - InferenceEngine::Precision::FP16, - InferenceEngine::Precision::I32, +const std::vector model_types = { + ov::element::f32, + ov::element::f16, + ov::element::i32, }; -const std::vector idxPrecisions = { - InferenceEngine::Precision::I32, - InferenceEngine::Precision::I64, +const std::vector idx_types = { + ov::element::i32, + ov::element::i64, }; -// map> -// updateShape is gotten from inputShape and indicesShape +// map> +// update_shape is gotten from input_shape and indices_shape std::map, std::map, std::vector>> sliceSelectInShape { {{10, 9, 9, 11}, {{{4, 1}, {1, 3, 5, 7}}, {{1, 2}, {4, 6}}, {{2, 3}, {0, 1, 1, 2, 2, 2}}, {{1, 4}, {5, 5, 4, 9}}}}, {{10, 9, 10, 9, 10}, {{{2, 2, 1}, {5, 6, 2, 8}}, {{2, 3}, {0, 4, 6, 5, 7, 1}}}}, }; +std::vector combineShapes( + const std::map, std::map, std::vector>>& input_shapes) { + std::vector resVec; + for (auto& input_shape : input_shapes) { + for (auto& item : input_shape.second) { + auto indices_shape = item.first; + size_t indices_rank = indices_shape.size(); + std::vector update_shape; + for (size_t i = 0; i < indices_rank - 1; i++) { + update_shape.push_back(indices_shape[i]); + } + auto src_shape = input_shape.first; + for (size_t j = indices_shape[indices_rank - 1]; j < src_shape.size(); j++) { + update_shape.push_back(src_shape[j]); + } + std::vector in_shapes{src_shape, update_shape}; + resVec.push_back( + ov::test::scatterNDUpdateSpecParams{ + ov::test::static_shapes_to_test_representation(in_shapes), + ov::Shape{indices_shape}, + item.second}); + } + } + return resVec; +} + const auto ScatterNDUpdateCases = ::testing::Combine( - ::testing::ValuesIn(ScatterNDUpdateLayerTest::combineShapes(sliceSelectInShape)), - ::testing::ValuesIn(inputPrecisions), - ::testing::ValuesIn(idxPrecisions), + ::testing::ValuesIn(combineShapes(sliceSelectInShape)), + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(idx_types), ::testing::Values(ov::test::utils::DEVICE_CPU) ); diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_elements_update.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_elements_update.cpp index 15aff5d2c8e35c..1cfe50c943fb84 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_elements_update.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_elements_update.cpp @@ -3,46 +3,59 @@ // #include -#include -#include "single_layer_tests/scatter_elements_update.hpp" +#include "single_op_tests/scatter_elements_update.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; -using namespace ngraph::opset3; +using ov::test::ScatterElementsUpdateLayerTest; namespace { -// map> +// map> std::map, std::map, std::vector>> axesShapeInShape { {{10, 12, 15}, {{{1, 2, 4}, {0, 1, 2}}, {{2, 2, 2}, {-1, -2, -3}}}}, {{15, 9, 8, 12}, {{{1, 2, 2, 2}, {0, 1, 2, 3}}, {{1, 2, 1, 4}, {-1, -2, -3, -4}}}}, {{9, 9, 8, 8, 11, 10}, {{{1, 2, 1, 2, 1, 2}, {5, -3}}}}, }; // index value should not be random data -const std::vector> idxValue = { +const std::vector> idx_value = { {1, 0, 4, 6, 2, 3, 7, 5} }; -const std::vector inputPrecisions = { - InferenceEngine::Precision::FP32, - InferenceEngine::Precision::FP16, - InferenceEngine::Precision::I32, +const std::vector model_types = { + ov::element::f32, + ov::element::f16, + ov::element::i32, }; -const std::vector idxPrecisions = { - InferenceEngine::Precision::I32, - InferenceEngine::Precision::I64, +const std::vector idx_types = { + ov::element::i32, + ov::element::i64, }; -const auto ScatterEltUpdateCases = ::testing::Combine( - ::testing::ValuesIn(ScatterElementsUpdateLayerTest::combineShapes(axesShapeInShape)), - ::testing::ValuesIn(idxValue), - ::testing::ValuesIn(inputPrecisions), - ::testing::ValuesIn(idxPrecisions), +std::vector combine_shapes( + const std::map, std::map, std::vector>>& input_shapes) { + std::vector res_vec; + for (auto& input_shape : input_shapes) { + for (auto& item : input_shape.second) { + for (auto& elt : item.second) { + res_vec.push_back(ov::test::axisShapeInShape{ + ov::test::static_shapes_to_test_representation({input_shape.first, item.first}), + elt}); + } + } + } + return res_vec; +} + +const auto scatter_elt_update_cases = ::testing::Combine( + ::testing::ValuesIn(combine_shapes(axesShapeInShape)), + ::testing::ValuesIn(idx_value), + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(idx_types), ::testing::Values(ov::test::utils::DEVICE_CPU) ); INSTANTIATE_TEST_SUITE_P(smoke_ScatterEltsUpdate, ScatterElementsUpdateLayerTest, - ScatterEltUpdateCases, ScatterElementsUpdateLayerTest::getTestCaseName); + scatter_elt_update_cases, ScatterElementsUpdateLayerTest::getTestCaseName); } // namespace diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_update.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_update.cpp index ded20162f09231..807d2d0eb05e73 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_update.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/scatter_update.cpp @@ -3,47 +3,79 @@ // #include -#include -#include "single_layer_tests/scatter_update.hpp" +#include "single_op_tests/scatter_update.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; -using namespace ngraph::opset3; +using ov::test::ScatterUpdateLayerTest; namespace { -const std::vector inputPrecisions = { - InferenceEngine::Precision::FP32, - InferenceEngine::Precision::FP16, - InferenceEngine::Precision::I32, +const std::vector model_types = { + ov::element::f32, + ov::element::f16, + ov::element::i32, }; -const std::vector idxPrecisions = { - InferenceEngine::Precision::I32, - InferenceEngine::Precision::I64, +const std::vector idx_types = { + ov::element::i32, + ov::element::i64, }; -// map> -std::map, std::map, std::vector>> axesShapeInShape { +// map> +std::map, std::map, std::vector>> axes_shape_in_shape { {{10, 16, 12, 15}, {{{2, 2, 2}, {0, 1, 2, 3}}, {{2, 4}, {0, 1, 2, 3}}, {{8}, {0, 1, 2, 3}}}}, {{10, 9, 10, 9, 10}, {{{8}, {0, 1, 2, 3, 4}}, {{4, 2}, {0, 1, 2, 3, 4}}}}, {{10, 9, 10, 9, 10, 12}, {{{8}, {0, 1, 2, 3, 4, 5}}}}, {{10, 16, 12, 15}, {{{2, 4}, {0, 1, 2, 3}}, {{8}, {-1, -2, -3, -4}}}}, {{10, 9, 10, 9, 10}, {{{8}, {-3, -1, 0, 2, 4}}, {{4, 2}, {-2, 2}}}}, }; + +std::vector combine_shapes( + const std::map, std::map, std::vector>>& input_shapes) { + std::vector res_vec; + for (auto& input_shape : input_shapes) { + auto src_shape = input_shape.first; + auto srcRank = src_shape.size(); + for (auto& item : input_shape.second) { + auto indices_shape = item.first; + auto indices_rank = indices_shape.size(); + for (auto& axis : item.second) { + auto axisP = axis < 0 ? axis + srcRank : axis; + std::vector update_shape; + for (size_t rs = 0; rs < srcRank; rs++) { + if (rs != axisP) { + update_shape.push_back(src_shape[rs]); + } else { + for (size_t ri = 0; ri < indices_rank; ri++) { + update_shape.push_back(indices_shape[ri]); + } + } + } + std::vector in_shapes{src_shape, update_shape}; + res_vec.push_back( + ov::test::axisUpdateShapeInShape{ + ov::test::static_shapes_to_test_representation(in_shapes), + ov::Shape{indices_shape}, + axis}); + } + } + } + return res_vec; +} + //indices should not be random value -const std::vector> idxValue = { +const std::vector> idx_value = { {0, 2, 4, 6, 1, 3, 5, 7} }; -const auto ScatterUpdateCase = ::testing::Combine( - ::testing::ValuesIn(ScatterUpdateLayerTest::combineShapes(axesShapeInShape)), - ::testing::ValuesIn(idxValue), - ::testing::ValuesIn(inputPrecisions), - ::testing::ValuesIn(idxPrecisions), +const auto scatter_update_case = ::testing::Combine( + ::testing::ValuesIn(combine_shapes(axes_shape_in_shape)), + ::testing::ValuesIn(idx_value), + ::testing::ValuesIn(model_types), + ::testing::ValuesIn(idx_types), ::testing::Values(ov::test::utils::DEVICE_CPU) ); -INSTANTIATE_TEST_SUITE_P(smoke_ScatterUpdate, ScatterUpdateLayerTest, ScatterUpdateCase, ScatterUpdateLayerTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_ScatterUpdate, ScatterUpdateLayerTest, scatter_update_case, ScatterUpdateLayerTest::getTestCaseName); } // namespace diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/select.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/select.cpp index 97412eadb3919d..d3ab75a305b06f 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/select.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/select.cpp @@ -4,21 +4,19 @@ #include -#include "single_layer_tests/select.hpp" +#include "single_op_tests/select.hpp" #include "common_test_utils/test_constants.hpp" -using namespace LayerTestsDefinitions; +using ov::test::SelectLayerTest; -const std::vector inputPrecision = { - InferenceEngine::Precision::I8, - InferenceEngine::Precision::I16, - InferenceEngine::Precision::I32, - InferenceEngine::Precision::FP32 - // CPU plug-in doesn't support I64 and U64 precisions at the moment - // InferenceEngine::Precision::I64 +const std::vector model_types = { + ov::element::i8, + ov::element::i16, + ov::element::i32, + ov::element::f32 }; -const std::vector>> noneShapes = { +const std::vector> none_shapes = { {{1}, {1}, {1}}, {{8}, {8}, {8}}, {{4, 5}, {4, 5}, {4, 5}}, @@ -27,14 +25,14 @@ const std::vector>> noneShapes = { {{2, 3, 4, 5, 6}, {2, 3, 4, 5, 6}, {2, 3, 4, 5, 6}} }; -const auto noneCases = ::testing::Combine( - ::testing::ValuesIn(noneShapes), - ::testing::ValuesIn(inputPrecision), - ::testing::Values(ngraph::op::AutoBroadcastType::NONE), +const auto none_cases = ::testing::Combine( + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(none_shapes)), + ::testing::ValuesIn(model_types), + ::testing::Values(ov::op::AutoBroadcastType::NONE), ::testing::Values(ov::test::utils::DEVICE_CPU) ); -const std::vector>> numpyShapes = { +const std::vector> numpy_shapes = { {{1}, {1}, {1}}, {{1}, {16}, {1}}, {{1}, {1}, {16}}, @@ -74,13 +72,13 @@ const std::vector>> numpyShapes = { {{7, 6, 5, 8}, {4, 7, 6, 5, 8}, {6, 1, 8}} }; -const auto numpyCases = ::testing::Combine( - ::testing::ValuesIn(numpyShapes), - ::testing::ValuesIn(inputPrecision), - ::testing::Values(ngraph::op::AutoBroadcastType::NUMPY), +const auto numpy_cases = ::testing::Combine( + ::testing::ValuesIn(ov::test::static_shapes_to_test_representation(numpy_shapes)), + ::testing::ValuesIn(model_types), + ::testing::Values(ov::op::AutoBroadcastType::NUMPY), ::testing::Values(ov::test::utils::DEVICE_CPU) ); -INSTANTIATE_TEST_SUITE_P(smoke_TestsSelect_none, SelectLayerTest, noneCases, SelectLayerTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_TestsSelect_none, SelectLayerTest, none_cases, SelectLayerTest::getTestCaseName); -INSTANTIATE_TEST_SUITE_P(smoke_TestsSelect_numpy, SelectLayerTest, numpyCases, SelectLayerTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_TestsSelect_numpy, SelectLayerTest, numpy_cases, SelectLayerTest::getTestCaseName); diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp index 0d6f932e000b5e..8d7d3ec43462ac 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp @@ -197,6 +197,9 @@ std::vector disabledTestPatterns() { R"(.*smoke_TopK/TopKLayerTest.Inference.*_k=21_.*_sort=value_modelType=f16_trgDev=CPU.*)", // Issue: 121228 R"(smoke_TestsDFT_(1|2|3|4)d/DFTLayerTest.Inference.*bf16.*)", + // Issue: 121313 + R"(smoke_GroupConvBackpropData.*paddingDefined/GroupConvBackpropLayerTest.Inference.*f16.*)", + R"(smoke_GroupConvBackpropData.*paddingDefined/GroupConvBackpropLayerTest.Inference.*f32.*)", }; #if defined(__APPLE__) && defined(OPENVINO_ARCH_ARM64) // Issue: 120950 diff --git a/src/plugins/intel_cpu/thirdparty/CMakeLists.txt b/src/plugins/intel_cpu/thirdparty/CMakeLists.txt index 4c17e2e32373ec..ef8e5cd1da8985 100644 --- a/src/plugins/intel_cpu/thirdparty/CMakeLists.txt +++ b/src/plugins/intel_cpu/thirdparty/CMakeLists.txt @@ -16,6 +16,7 @@ if(ENABLE_LTO) endif() function(ov_add_onednn) + set(CMAKE_DISABLE_FIND_PACKAGE_PythonInterp ON) set(DNNL_ENABLE_JIT_PROFILING ${BUILD_SHARED_LIBS} CACHE BOOL "" FORCE) if(BUILD_SHARED_LIBS AND ENABLE_PROFILING_ITT) set(DNNL_ENABLE_ITT_TASKS ON CACHE BOOL "" FORCE) diff --git a/src/plugins/intel_cpu/tools/commit_slider/utils/cfg_samples/e2e.json b/src/plugins/intel_cpu/tools/commit_slider/utils/cfg_samples/e2e.json index 6d5251c55b2bc6..23cffb03ba6325 100644 --- a/src/plugins/intel_cpu/tools/commit_slider/utils/cfg_samples/e2e.json +++ b/src/plugins/intel_cpu/tools/commit_slider/utils/cfg_samples/e2e.json @@ -7,7 +7,7 @@ {"name" : "MO_ROOT", "val" : "//tools/mo/openvino/tools/"}, {"name" : "OPENVINO_ROOT_DIR", "val" : "//"} ], - "makeCmd" : "cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_PYTHON=ON -DPYTHON_EXECUTABLE=/usr/bin/python3.8 -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.8.so -DPYTHON_INCLUDE_DIR=/usr/include/python3.8 -DTHREADING=TBB -DENABLE_INTEL_GPU=OFF -DENABLE_INTEL_GNA=OFF -DENABLE_MODELS=OFF -DENABLE_SAMPLES=OFF -DENABLE_TESTS=OFF -DENABLE_CPU_DEBUG_CAPS=OFF -DENABLE_HETERO=OFF -DENABLE_TEMPLATE=OFF -DENABLE_CPU_DEBUG_CAPS=OFF -DENABLE_DEBUG_CAPS=OFF -DENABLE_OPENVINO_DEBUG=OFF -DCMAKE_CXX_FLAGS=-Wno-deprecated -DCMAKE_C_FLAGS=-Wno-deprecated -DCMAKE_CXX_FLAGS=-Wno-deprecated-declarations -DCMAKE_C_FLAGS=-Wno-deprecated-declarations ..", + "makeCmd" : "cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_PYTHON=ON -DPython3_EXECUTABLE=/usr/bin/python3.8 -DTHREADING=TBB -DENABLE_INTEL_GPU=OFF -DENABLE_INTEL_GNA=OFF -DENABLE_MODELS=OFF -DENABLE_SAMPLES=OFF -DENABLE_TESTS=OFF -DENABLE_CPU_DEBUG_CAPS=OFF -DENABLE_HETERO=OFF -DENABLE_TEMPLATE=OFF -DENABLE_CPU_DEBUG_CAPS=OFF -DENABLE_DEBUG_CAPS=OFF -DENABLE_OPENVINO_DEBUG=OFF -DCMAKE_CXX_FLAGS=-Wno-deprecated -DCMAKE_C_FLAGS=-Wno-deprecated -DCMAKE_CXX_FLAGS=-Wno-deprecated-declarations -DCMAKE_C_FLAGS=-Wno-deprecated-declarations ..", "runConfig" : { "commitList" : { "getCommitListCmd" : "git log .. --boundary --pretty=\"%h\"" 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 dab52844e7ee3e..1a196ea49e8e95 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/graph/program.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/graph/program.hpp @@ -35,20 +35,22 @@ class ICompilationContext; struct program { using ptr = std::shared_ptr; using cptr = std::shared_ptr; - friend class calculate_prior_boxes; // to be removed when possible - friend class graph_initializations; // to be removed when possible - friend class prepare_padding; // to be removed when possible - friend class propagate_constants; // to be removed when possible - friend class pre_replace_deconv; // to be removed when possible - friend class prepare_primitive_fusing; // to be removed when possible - friend class prepare_quantization; // to be removed when possible - friend class prepare_conv_eltw_fusing; // to be removed when possible - friend class reorder_inputs; // to be removed when possible - friend class remove_redundant_reorders; // to be removed when possible - friend class post_optimize_weights; // to be removed when possible - friend class program_wrapper; // this class is intended to extend the interface of program for - // the usage within tests_core_internal project only - friend class prepare_primitive_fusing_through; // to be removed when possible + friend class calculate_prior_boxes; // to be removed when possible + friend class graph_initializations; // to be removed when possible + friend class prepare_padding; // to be removed when possible + friend class propagate_constants; // to be removed when possible + friend class pre_replace_deconv; // to be removed when possible + friend class prepare_primitive_fusing; // to be removed when possible + friend class prepare_quantization; // to be removed when possible + friend class prepare_conv_eltw_fusing; // to be removed when possible + friend class reorder_inputs; // to be removed when possible + friend class remove_redundant_reorders; // to be removed when possible + friend class post_optimize_weights; // to be removed when possible + friend class prepare_primitive_fusing_through; // to be removed when possible + friend class reorder_transfer; // to be removed when possible + friend class fuse_constant_transposes; // to be removed when possible + friend class program_wrapper; // this class is intended to extend the interface of program for + // the usage within tests_core_internal project only public: struct nodes_ordering { public: diff --git a/src/plugins/intel_gpu/include/intel_gpu/runtime/format.hpp b/src/plugins/intel_gpu/include/intel_gpu/runtime/format.hpp index a8186b9d62f260..fb6bfaa3fc8224 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/runtime/format.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/runtime/format.hpp @@ -80,6 +80,7 @@ struct format { bfvuwzyx, ///< 8d tensor yxfb, ///< batch first, feature and than spatials byxf, ///< used in bitmaps, input from user i.e b images of RGB format + fbyx, fyxb, ///< format not used inside clDNN, but supported in reorder as extension bzyxf, byfx, ///< To be used when onednn gemm allows permute fusing in transformer network. Not for normal use from cldnn. @@ -341,8 +342,9 @@ struct format { return (fmt == yxfb || fmt == byxf || fmt == byfx || fmt == bxfy || fmt == bfyx || fmt == fyxb || - fmt == bfzyx || fmt == bfwzyx || - fmt == bfuwzyx || fmt == bfvuwzyx); + fmt == fbyx || fmt == bfzyx || + fmt == bfwzyx || fmt == bfuwzyx || + fmt == bfvuwzyx); } static format get_default_format(size_t rank, bool is_weights = false, bool is_grouped = false); @@ -352,6 +354,14 @@ struct format { static const std::vector> per_axis_block_size(format fmt); + static format find_format(const std::vector& order, + const std::vector>& block_sizes, + bool is_weights = false, + bool is_grouped = false, + bool is_image_2d = false, + bool is_winograd = false, + bool is_nv12 = false); + /// @brief Checks if @p format is of grouped type static bool is_grouped(type fmt) { return group_num(fmt) != 0; } /// @brief Checks if @p format is of image type @@ -373,6 +383,8 @@ struct format { size_t spatial_num() const { return traits(value).spatial_num; } /// @brief Returns number of group dimensions. size_t group_num() const { return traits(value).group_num; } + /// @brief Returns an order of dimensions. + const std::vector& dims_order() const { return traits(value)._order; } /// @brief Returns an order of dimensions in form of string. const std::string& order() const { return traits(value).order; } /// @brief Returns an internal orders of dimensions form of string. diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/post_optimize_weights.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/post_optimize_weights.cpp index 175a6eef54b48f..4f48148c39549b 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/post_optimize_weights.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/post_optimize_weights.cpp @@ -79,16 +79,19 @@ void post_optimize_weights::optimize_weights(T& node, program& p) { if (weights_reorder_params != nullptr) { bool can_be_fused = prev_node.is_type() && + prev_node.as().is_simple_reorder() && prev_node.get_users().size() == 1 && - prev_node.get_dependencies().size() == 1 && - !prev_node.has_fused_primitives() && - !prev_node.as().has_mean() && - prev_node.as().get_primitive()->subtract_per_feature.empty(); + prev_node.get_dependencies().size() == 1; if (can_be_fused) { // Need to update input data_type for correct merging format reorder with precision reorder - data_types input_dtype = prev_node.get_input_layouts()[0].data_type; auto updated_input_layout = weights_reorder_params->get_input_layout(); + data_types input_dtype = prev_node.get_input_layout().data_type; updated_input_layout.data_type = input_dtype; + + // Need to update input format in case of fusing weights constant with transpose + format input_fmt = prev_node.get_input_layout().format; + updated_input_layout.format = from_weights_layout(to_weights_layout(input_fmt, false)); + weights_reorder_params->set_input_layout(updated_input_layout); auto weights_reorder = _rf.get_weights_reorder(prev_node.get_primitive()->input[0].pid, weights_reorder_params); diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing.cpp index f7b3fd2a08ffe8..4d89826ac54b04 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing.cpp @@ -60,6 +60,7 @@ void prepare_primitive_fusing::run(program& p) { fuse_sigmoid_mul_to_swish(p); fuse_bias(p); fuse_simple_primitives(p); + fuse_constant_transposes(p); optimize_fused_ops(p); } @@ -1186,6 +1187,94 @@ void prepare_primitive_fusing::fuse_simple_primitives(program &p) { p.get_processing_order().calc_processing_order(p); } +void prepare_primitive_fusing::fuse_constant_transposes(program& p) { + std::function get_weightable_node = + [&get_weightable_node](const program_node* node) -> const program_node* { + if (node->get_users().empty()) + return nullptr; + + const auto* next_node = node->get_users().front(); + + if (next_node->is_type() || + next_node->is_type() || + next_node->is_type() || + next_node->is_type() || + next_node->is_type()) { + size_t weights_offset = next_node->get_primitive()->input_size(); + return &next_node->get_dependency(weights_offset) == node ? next_node + : nullptr; + } + + if (node->is_constant() && node->get_users().size() == 1) + return get_weightable_node(next_node); + + return nullptr; + }; + + auto convert_data_format_by_order = [](format fmt, const std::vector& order) -> format { + const auto& old_order = fmt.dims_order(); + auto new_order = old_order; + + for (size_t i = 0; i < order.size(); ++i) { + new_order[i] = old_order[order[i]]; + } + + return format::find_format(new_order, fmt.block_sizes()); + }; + + auto itr = p.get_processing_order().begin(); + while (itr != p.get_processing_order().end()) { + auto& node = *itr++; + + if (!node->is_type()) + continue; + + auto& permute_node = node->as(); + + auto weightable_node = get_weightable_node(&permute_node); + + if (weightable_node == nullptr || !permute_node.get_dependency(0).is_type()) + continue; + + auto& prev_const = permute_node.get_dependency(0).as(); + + if (prev_const.get_users().size() != 1) + continue; + + auto permute_order = permute_node.get_primitive()->permute_order; + // Assumption that fc weights will be reshaped to 2d + if (permute_order.size() != 2 && weightable_node->is_type()) { + if (permute_order == std::vector{0, 2, 1} || + permute_order == std::vector{0, 1, 3, 2}) { + permute_order = {1, 0}; + } else { + continue; + } + } + + format new_fmt = format::any; + try { + new_fmt = convert_data_format_by_order(prev_const.get_output_layout().format, permute_order); + } catch(ov::Exception&) { + continue; + } + + layout updated_const_layout = prev_const.get_output_layout(); + updated_const_layout.format = new_fmt; + updated_const_layout.set_partial_shape(permute_node.get_output_pshape()); + + p.extract_and_remove(permute_node); + + const auto& new_mem = p.get_engine().reinterpret_buffer(prev_const.get_attached_memory(), updated_const_layout); + + auto new_const_prim = std::make_shared(prev_const.id() + "_fused_with_transpose", new_mem); + auto& new_const_node = p.get_or_create(new_const_prim); + + p.replace(prev_const, new_const_node); + new_const_node.recalc_output_layout(false); + } +} + void prepare_primitive_fusing::optimize_fused_ops(program& p) { auto itr = p.get_processing_order().begin(); while (itr != p.get_processing_order().end()) { diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing_through.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing_through.cpp index c85e4cbd8de4b1..899369aa5c7077 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing_through.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/prepare_primitive_fusing_through.cpp @@ -96,7 +96,7 @@ void prepare_primitive_fusing_through::run(program& p) { input_node = &node->get_dependency(0); } else if (node->is_type()) { - if (node->get_dependencies().size() !=2) + if (node->get_dependencies().size() != 2) continue; size_t second_input_idx = 0; diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/remove_redundant_reorders.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/remove_redundant_reorders.cpp index 7ff8390cb9fc4a..362cf5bf63df4c 100644 --- a/src/plugins/intel_gpu/src/graph/graph_optimizer/remove_redundant_reorders.cpp +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/remove_redundant_reorders.cpp @@ -59,13 +59,7 @@ void remove_redundant_reorders::run(program& p) { auto& input = node.input(); auto output_layout = node.get_output_layout(); - if (node.is_output()) - continue; - - if (node.has_mean() || !node.get_primitive()->subtract_per_feature.empty()) - continue; - - if (node.has_fused_primitives()) + if (!node.is_simple_reorder() || node.is_output()) continue; std::function has_quantize_user; @@ -149,12 +143,11 @@ void remove_redundant_reorders::run(program& p) { auto& r_dep_node = dep_node.as(); - bool remove_dep = r_dep_node.get_users().size() == 1 && - !r_dep_node.has_mean() && - r_dep_node.get_primitive()->subtract_per_feature.empty() && - !r_dep_node.is_output() && - !r_dep_node.has_fused_primitives() && - !r_dep_node.get_primitive()->has_surface_input(); + bool remove_dep = r_dep_node.is_simple_reorder() && + r_dep_node.get_users().size() == 1 && + !r_dep_node.is_output() && + !r_dep_node.get_primitive()->has_surface_input() && + !r_node.get_primitive()->weights_reorder_params; // for chains like // fp32 -> reorder -> u8 -> reorder -> fp32 @@ -164,13 +157,10 @@ void remove_redundant_reorders::run(program& p) { continue; } - bool remove_current = - r_dep_node.get_users().size() == 1 && - !r_dep_node.is_output() && - !r_node.has_mean() && - r_node.get_primitive()->subtract_per_feature.empty() && - !r_node.has_fused_primitives() && - !r_node.get_primitive()->has_surface_input(); + bool remove_current = r_node.is_simple_reorder() && + r_dep_node.get_users().size() == 1 && + !r_dep_node.is_output() && + !r_node.get_primitive()->has_surface_input(); if (remove_dep) { // for chains like @@ -271,13 +261,9 @@ void remove_redundant_reorders::run(program& p) { r_node.is_output() && (r_node.get_dependency(0).is_output() || r_node.get_dependency(0).is_type() || r_node.get_dependency(0).can_be_optimized() || r_node.get_dependency(0).get_users().size() != 1) : r_node.is_output(); - if (r_node.has_mean() || - !r_node.get_primitive()->subtract_per_feature.empty() || + if (!r_node.is_simple_reorder() || no_output_optimization || - r_node.has_fused_primitives() || - r_node.get_primitive()->has_surface_input() || - (r_node.get_primitive()->weights_reorder_params && - r_node.get_primitive()->weights_reorder_params->should_be_transposed())) + r_node.get_primitive()->has_surface_input()) continue; auto o_layout = r_node.get_output_layout(); @@ -406,10 +392,7 @@ void remove_redundant_reorders::run(program& p) { auto& input = node.input(); auto output_layout = node.get_output_layout(); - if (node.has_mean() || !node.get_primitive()->subtract_per_feature.empty()) - continue; - - if (node.has_fused_primitives()) + if (!node.is_simple_reorder()) continue; if (input.get_users().size() != 1) @@ -614,11 +597,7 @@ void remove_redundant_reorders::run(program& p) { if (!r_node.is_in_data_flow() || r_node.get_dependencies().size() != 1) continue; - if (r_node.has_mean() || - !r_node.get_primitive()->subtract_per_feature.empty()) - continue; - - if (r_node.has_fused_primitives()) + if (!r_node.is_simple_reorder()) continue; // Remove reorder for Convolution bfyx -> fs_b_yx_fsv32 diff --git a/src/plugins/intel_gpu/src/graph/graph_optimizer/reorder_transfer.cpp b/src/plugins/intel_gpu/src/graph/graph_optimizer/reorder_transfer.cpp new file mode 100644 index 00000000000000..daa9dbd89adfe6 --- /dev/null +++ b/src/plugins/intel_gpu/src/graph/graph_optimizer/reorder_transfer.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "pass_manager.h" +#include "reorder_inst.h" +#include "permute_inst.h" +#include "program_helpers.h" + +using namespace cldnn; + +void reorder_transfer::run(program& p) { + auto itr = p.get_processing_order().begin(); + while (itr != p.get_processing_order().end()) { + auto& node = *itr++; + + if (!node->is_type()) + continue; + + auto& reorder_node = node->as(); + + bool is_simple_type_conversion_reorder = reorder_node.is_constant() && + !reorder_node.is_output() && + reorder_node.get_users().size() == 1 && + reorder_node.get_dependencies().size() == 1 && + reorder_node.is_type_conversion_only(); + if (!is_simple_type_conversion_reorder) + continue; + + auto transfer_through_node = [](cldnn::program_node* node) -> bool { // Conditions can be extended to other ops + return node->is_type() && + node->get_users().size() == 1 && + node->get_dependencies().size() == 1; + }; + + auto change_output_dtype = [](cldnn::program_node* node, cldnn::data_types dtype) { + layout new_layout = node->get_output_layout(); + new_layout.data_type = dtype; + node->set_output_layout(new_layout, false); + }; + + auto* supposed_new_prev = reorder_node.get_users().front(); + cldnn::program_node* new_prev = nullptr; + while (transfer_through_node(supposed_new_prev)) { + change_output_dtype(supposed_new_prev, reorder_node.get_input_layout().data_type); + new_prev = supposed_new_prev; + supposed_new_prev = supposed_new_prev->get_users().front(); + } + + if (new_prev != nullptr) { + auto& new_next = new_prev->get_users().front(); + p.move_node(reorder_node, *new_prev, *new_next); + reorder_node.recalc_output_layout(false); + } + } +} diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/kernel_selector_helper.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/kernel_selector_helper.cpp index 5cc70002debf39..5fd4a17728e0cd 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/kernel_selector_helper.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/kernel_selector_helper.cpp @@ -211,6 +211,8 @@ kernel_selector::data_layout to_data_layout(format f) { return kernel_selector::data_layout::byfx; case format::bxfy: return kernel_selector::data_layout::bxfy; + case format::fbyx: + return kernel_selector::data_layout::fbyx; case format::fyxb: return kernel_selector::data_layout::fyxb; case format::b_fs_yx_fsv2: @@ -310,6 +312,8 @@ cldnn::format from_data_layout(kernel_selector::data_layout l) { return cldnn::format::byfx; case kernel_selector::data_layout::bxfy: return cldnn::format::bxfy; + case kernel_selector::data_layout::fbyx: + return cldnn::format::fbyx; case kernel_selector::data_layout::fyxb: return cldnn::format::fyxb; case kernel_selector::data_layout::b_fs_yx_fsv2: @@ -382,6 +386,7 @@ kernel_selector::weights_layout to_weights_layout(format f, bool is_grouped) { case format::bfyx: case format::oiyx: return kernel_selector::weights_layout::oiyx; + case format::fbyx: case format::ioyx: return kernel_selector::weights_layout::ioyx; case format::iyxo: @@ -390,8 +395,10 @@ kernel_selector::weights_layout to_weights_layout(format f, bool is_grouped) { case format::oyxi: case format::byxf: return kernel_selector::weights_layout::oyxi; + case format::oyix: case format::byfx: return kernel_selector::weights_layout::oyix; + case format::oxiy: case format::bxfy: return kernel_selector::weights_layout::oxiy; case format::yxfb: diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/reorder.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/reorder.cpp index af825934d08400..976d6e38a58ec7 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/reorder.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/reorder.cpp @@ -126,6 +126,8 @@ struct reorder_impl : typed_primitive_impl_ocl { const auto& weights_params = prim->weights_reorder_params; auto& kernel_selector = kernel_selector::ReorderWeightsKernelSelector::Instance(); + OPENVINO_ASSERT(weights_params != nullptr, "[GPU] Attempt to create reorder weights without weights params"); + OPENVINO_ASSERT(impl_param.get_input_layout().bytes_count() == weights_params->get_input_layout().bytes_count(), "[GPU] Input layout doesn't match required reorder weights layout"); diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp index e64498f73f709a..ab10c1ff106f9d 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp @@ -202,7 +202,8 @@ attach_strided_slice_impl::attach_strided_slice_impl() { auto formats = { format::bfyx, - format::bfzyx + format::bfzyx, + format::bfwzyx, }; implementation_map::add(impl_types::ocl, 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 e507014f233491..d6409eab31e9a4 100644 --- a/src/plugins/intel_gpu/src/graph/include/pass_manager.h +++ b/src/plugins/intel_gpu/src/graph/include/pass_manager.h @@ -196,6 +196,7 @@ class prepare_primitive_fusing : public base_pass { void fuse_bias(program &p); void fuse_reorders(program& p); void fuse_simple_primitives(program &p); + void fuse_constant_transposes(program &p); void optimize_fused_ops(program &p); void remove_redundant_reshape(program &p); layout_optimizer& _lo; @@ -406,4 +407,12 @@ class build_implementations : public base_pass { void run(program& p) override; }; +class reorder_transfer : public base_pass { +public: + reorder_transfer() : base_pass("reorder_transfer") {} + +private: + void run(program& p) override; +}; + } // namespace cldnn diff --git a/src/plugins/intel_gpu/src/graph/include/reorder_inst.h b/src/plugins/intel_gpu/src/graph/include/reorder_inst.h index b1637032ffb2d9..00e48ec8715929 100644 --- a/src/plugins/intel_gpu/src/graph/include/reorder_inst.h +++ b/src/plugins/intel_gpu/src/graph/include/reorder_inst.h @@ -41,16 +41,25 @@ struct typed_program_node : public typed_program_node_base { void set_input_layout(layout const& lo) { input_layout = lo; } bool is_type_conversion_only() const { - if (this->has_fused_primitives() || has_mean() || !typed_desc()->subtract_per_feature.empty()) - return false; - auto in_layout = input().get_output_layout(); - auto out_layout = this->get_output_layout(); - auto check_common_layout = in_layout.data_type != out_layout.data_type && - in_layout.format == out_layout.format && - in_layout.data_padding == out_layout.data_padding; - return typed_desc()->truncate && - ((this->is_dynamic() && check_common_layout && in_layout.get_partial_shape().rank() == out_layout.get_partial_shape().rank()) || - (!this->is_dynamic() && check_common_layout && in_layout.get_partial_shape() == out_layout.get_partial_shape())); + auto in_layout = get_input_layout(); + auto out_layout = get_output_layout(); + bool only_precision_changed = in_layout.data_type != out_layout.data_type && + in_layout.format == out_layout.format && + in_layout.data_padding == out_layout.data_padding; + if (is_dynamic()) { + only_precision_changed &= in_layout.get_partial_shape().rank() == out_layout.get_partial_shape().rank(); + } else { + only_precision_changed &= in_layout.get_partial_shape() == out_layout.get_partial_shape(); + } + + return only_precision_changed && is_simple_reorder() && typed_desc()->truncate; + } + + bool is_simple_reorder() const { + return !has_fused_primitives() && + !has_mean() && + get_primitive()->subtract_per_feature.empty() && + !get_primitive()->weights_reorder_params; } std::shared_ptr get_fuse_params() const override { diff --git a/src/plugins/intel_gpu/src/graph/program.cpp b/src/plugins/intel_gpu/src/graph/program.cpp index ab454e6bc6b9d2..4fcb120cdd4220 100644 --- a/src/plugins/intel_gpu/src/graph/program.cpp +++ b/src/plugins/intel_gpu/src/graph/program.cpp @@ -555,6 +555,8 @@ void program::pre_optimize_graph(bool is_internal) { apply_opt_pass(lo); + apply_opt_pass(); + #ifdef GPU_DEBUG_CONFIG GPU_DEBUG_IF(!debug_config->disable_primitive_fusing) { #else @@ -608,7 +610,12 @@ void program::post_optimize_graph(bool is_internal) { reorder_factory rf; layout_optimizer lo; set_layout_optimizer_attributes(lo); - apply_opt_pass(rf); + + bool optimize_data = _config.get_property(ov::intel_gpu::optimize_data); + + if (!is_internal) { + apply_opt_pass(rf); + } apply_opt_pass(lo, false, true); // TODO: do we need it at this place also? @@ -623,7 +630,7 @@ void program::post_optimize_graph(bool is_internal) { apply_opt_pass(); } - if (_config.get_property(ov::intel_gpu::optimize_data)) + if (optimize_data) apply_opt_pass(lo, false, true, true); // pass to remove output reorders while all others graph optimizations were done // update inner program input/output primitive mappings diff --git a/src/plugins/intel_gpu/src/kernel_selector/CMakeLists.txt b/src/plugins/intel_gpu/src/kernel_selector/CMakeLists.txt index 99ebf5331ab305..81637375d811b3 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/CMakeLists.txt +++ b/src/plugins/intel_gpu/src/kernel_selector/CMakeLists.txt @@ -4,7 +4,7 @@ set(TARGET_NAME "openvino_intel_gpu_kernels") -find_host_package(PythonInterp 3 REQUIRED) +find_host_package(Python3 REQUIRED COMPONENTS Interpreter) file(GLOB_RECURSE LIBRARY_SRC "${CMAKE_CURRENT_SOURCE_DIR}/*.h" @@ -37,10 +37,10 @@ set_property(SOURCE ${CODEGEN_CACHE_SOURCES} PROPERTY GENERATED TRUE) add_custom_command(OUTPUT "${CODEGEN_CACHE_DIR}/${PRIM_DB}" COMMAND "${CMAKE_COMMAND}" -E make_directory "${CODEGEN_CACHE_DIR}" - COMMAND "${PYTHON_EXECUTABLE}" "${CODEGEN_SCRIPT}" -out_path "${CODEGEN_CACHE_DIR}" - -out_file_name_prim_db "${PRIM_DB}" - -out_file_name_batch_headers "${PRIM_DB_BATCH_HEADERS}" - -kernels "${CMAKE_CURRENT_SOURCE_DIR}/cl_kernels/" + COMMAND "${Python3_EXECUTABLE}" "${CODEGEN_SCRIPT}" -out_path "${CODEGEN_CACHE_DIR}" + -out_file_name_prim_db "${PRIM_DB}" + -out_file_name_batch_headers "${PRIM_DB_BATCH_HEADERS}" + -kernels "${CMAKE_CURRENT_SOURCE_DIR}/cl_kernels/" DEPENDS ${KERNELS} "${CODEGEN_SCRIPT}" COMMENT "Generating ${CODEGEN_CACHE_DIR}/${PRIM_DB} ..." ) diff --git a/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl b/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl index 23344ae06222ad..49e554703b8b74 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl +++ b/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl @@ -8,7 +8,7 @@ inline void FUNC(get_slice_step)(OPTIONAL_SHAPE_INFO_ARG const __global STRIDE_TYPE* stride, int* step_batch, int* step_feature, - int* step_z, int* step_y, int* step_x) + int* step_w, int* step_z, int* step_y, int* step_x) { const uint batch_index = 0; const uint feature_index = 1; @@ -19,13 +19,23 @@ inline void FUNC(get_slice_step)(OPTIONAL_SHAPE_INFO_ARG const uint z_index = 2; const uint y_index = 3; const uint x_index = 4; +#elif OUTPUT_LAYOUT_BFWZYX + const uint w_index = 2; + const uint z_index = 3; + const uint y_index = 4; + const uint x_index = 5; #endif *step_batch = batch_index < STRIDE_DIMS ? stride[batch_index] : 1; *step_feature = feature_index < STRIDE_DIMS ? stride[feature_index] : 1; #ifdef OUTPUT_LAYOUT_BFYX + *step_w = 0; *step_z = 0; #elif OUTPUT_LAYOUT_BFZYX + *step_w = 0; + *step_z = z_index < STRIDE_DIMS ? stride[z_index] : 1; +#elif OUTPUT_LAYOUT_BFWZYX + *step_w = w_index < STRIDE_DIMS ? stride[w_index] : 1; *step_z = z_index < STRIDE_DIMS ? stride[z_index] : 1; #endif *step_y = y_index < STRIDE_DIMS ? stride[y_index] : 1; @@ -50,10 +60,11 @@ inline int FUNC(check_end_bound)(const end_num, inline void FUNC(get_slice_end)(OPTIONAL_SHAPE_INFO_ARG const __global END_TYPE* end, int* end_batch, int* end_feature, - int* end_z, int* end_y, int* end_x) + int* end_w, int* end_z, int* end_y, int* end_x) { const uint out_batch_num = INPUT0_BATCH_NUM; const uint out_feature_num = INPUT0_FEATURE_NUM; + const uint out_w_num = INPUT0_SIZE_W; const uint out_z_num = INPUT0_SIZE_Z; const uint out_y_num = INPUT0_SIZE_Y; const uint out_x_num = INPUT0_SIZE_X; @@ -66,10 +77,18 @@ inline void FUNC(get_slice_end)(OPTIONAL_SHAPE_INFO_ARG const uint z_index = 2; const uint y_index = 3; const uint x_index = 4; +#elif OUTPUT_LAYOUT_BFWZYX + const uint w_index = 2; + const uint z_index = 3; + const uint y_index = 4; + const uint x_index = 5; #endif END_TYPE batch = batch_index < END_DIMS ? end[batch_index] : 0; END_TYPE feature = feature_index < END_DIMS ? end[feature_index] : 0; -#ifdef OUTPUT_LAYOUT_BFZYX +#ifdef OUTPUT_LAYOUT_BFWZYX + END_TYPE w = w_index < END_DIMS ? end[w_index] : 0; + END_TYPE z = z_index < END_DIMS ? end[z_index] : 0; +#elif OUTPUT_LAYOUT_BFZYX END_TYPE z = z_index < END_DIMS ? end[z_index] : 0; #endif END_TYPE y = y_index < END_DIMS ? end[y_index] : 0; @@ -77,7 +96,10 @@ inline void FUNC(get_slice_end)(OPTIONAL_SHAPE_INFO_ARG batch = (END_BATCH == 0) ? batch : TO_END_TYPE(out_batch_num); feature = (END_FEATURE == 0) ? feature : TO_END_TYPE(out_feature_num); -#ifdef OUTPUT_LAYOUT_BFZYX +#ifdef OUTPUT_LAYOUT_BFWZYX + w = (END_W == 0) ? w: TO_END_TYPE(out_w_num); + z = (END_Z == 0) ? z: TO_END_TYPE(out_z_num); +#elif OUTPUT_LAYOUT_BFZYX z = (END_Z == 0) ? z: TO_END_TYPE(out_z_num); #endif y = (END_Y == 0) ? y : TO_END_TYPE(out_y_num); @@ -86,9 +108,13 @@ inline void FUNC(get_slice_end)(OPTIONAL_SHAPE_INFO_ARG *end_batch = FUNC_CALL(check_end_bound)(batch, out_batch_num); *end_feature = FUNC_CALL(check_end_bound)(feature, out_feature_num); #ifdef OUTPUT_LAYOUT_BFYX + *end_w = 0; *end_z = 0; #elif OUTPUT_LAYOUT_BFZYX *end_z = FUNC_CALL(check_end_bound)(z, out_z_num); +#elif OUTPUT_LAYOUT_BFWZYX + *end_w = FUNC_CALL(check_end_bound)(w, out_w_num); + *end_z = FUNC_CALL(check_end_bound)(z, out_z_num); #endif *end_y = FUNC_CALL(check_end_bound)(y, out_y_num); *end_x = FUNC_CALL(check_end_bound)(x, out_x_num); @@ -97,16 +123,17 @@ inline void FUNC(get_slice_end)(OPTIONAL_SHAPE_INFO_ARG inline void FUNC(check_negative_stride)(OPTIONAL_SHAPE_INFO_ARG const __global END_TYPE* end, const int steps_batch, const int steps_feature, - const int steps_z, const int steps_y, const int steps_x, + const int steps_w, const int steps_z, const int steps_y, const int steps_x, int* begin_batch, int* begin_feature, - int* begin_z, int* begin_y, int* begin_x) + int* begin_w, int* begin_z, int* begin_y, int* begin_x) { - bool is_negative = (steps_batch < 0) || (steps_feature < 0) || (steps_z < 0) || (steps_y < 0) || (steps_x < 0); + bool is_negative = (steps_batch < 0) || (steps_feature < 0) || (steps_w < 0) || (steps_z < 0) || (steps_y < 0) || (steps_x < 0); if (is_negative) { - int end_batch, end_feature, end_z, end_y, end_x; - FUNC_CALL(get_slice_end)(OPTIONAL_SHAPE_INFO_TENSOR end, &end_batch, &end_feature, &end_z, &end_y, &end_x); + int end_batch, end_feature, end_w, end_z, end_y, end_x; + FUNC_CALL(get_slice_end)(OPTIONAL_SHAPE_INFO_TENSOR end, &end_batch, &end_feature, &end_w, &end_z, &end_y, &end_x); const int slice_end_batch = end_batch; const int slice_end_feature = end_feature; + const int slice_end_w = end_w; const int slice_end_z = end_z; const int slice_end_y = end_y; const int slice_end_x = end_x; @@ -115,6 +142,8 @@ inline void FUNC(check_negative_stride)(OPTIONAL_SHAPE_INFO_ARG *begin_batch = slice_end_batch - 1; if ((steps_feature < 0) && (*begin_feature <= slice_end_feature)) *begin_feature = slice_end_feature - 1; + if ((steps_w < 0) && (*begin_w <= slice_end_w)) + *begin_w = slice_end_w - 1; if ((steps_z < 0) && (*begin_z <= slice_end_z)) *begin_z = slice_end_z - 1; if ((steps_y < 0) && (*begin_y <= slice_end_y)) @@ -125,12 +154,13 @@ inline void FUNC(check_negative_stride)(OPTIONAL_SHAPE_INFO_ARG } #else // END_TYPE inline void FUNC(check_negative_stride)(const int steps_batch, const int steps_feature, - const int steps_z, const int steps_y, const int steps_x, + const int steps_w, const int steps_z, const int steps_y, const int steps_x, int* begin_batch, int* begin_feature, - int* begin_z, int* begin_y, int* begin_x) + int* begin_w, int* begin_z, int* begin_y, int* begin_x) { const int slice_end_batch = SLICE_END_BATCH; const int slice_end_feature = SLICE_END_FEATURE; + const int slice_end_w = SLICE_END_W; const int slice_end_z = SLICE_END_Z; const int slice_end_y = SLICE_END_Y; const int slice_end_x = SLICE_END_X; @@ -139,6 +169,8 @@ inline void FUNC(check_negative_stride)(const int steps_batch, const int steps_f *begin_batch = slice_end_batch - 1; if ((steps_feature < 0) && (*begin_feature <= slice_end_feature)) *begin_feature = slice_end_feature - 1; + if ((steps_w < 0) && (*begin_w <= slice_end_w)) + *begin_w = slice_end_w - 1; if ((steps_z < 0) && (*begin_z <= slice_end_z)) *begin_z = slice_end_z - 1; if ((steps_y < 0) && (*begin_y <= slice_end_y)) @@ -165,10 +197,11 @@ inline int FUNC(check_begin_bound)(BEGIN_TYPE begin_num, inline void FUNC(get_slice_begin)(OPTIONAL_SHAPE_INFO_ARG const __global BEGIN_TYPE* begin, int* begin_batch, int* begin_feature, - int* begin_z, int* begin_y, int* begin_x) + int* begin_w, int* begin_z, int* begin_y, int* begin_x) { const uint out_batch_num = INPUT0_BATCH_NUM; const uint out_feature_num = INPUT0_FEATURE_NUM; + const uint out_w_num = INPUT0_SIZE_W; const uint out_z_num = INPUT0_SIZE_Z; const uint out_y_num = INPUT0_SIZE_Y; const uint out_x_num = INPUT0_SIZE_X; @@ -181,10 +214,18 @@ inline void FUNC(get_slice_begin)(OPTIONAL_SHAPE_INFO_ARG const uint z_index = 2; const uint y_index = 3; const uint x_index = 4; +#elif OUTPUT_LAYOUT_BFWZYX + const uint w_index = 2; + const uint z_index = 3; + const uint y_index = 4; + const uint x_index = 5; #endif BEGIN_TYPE batch = batch_index < BEGIN_DIMS ? begin[batch_index] : 0; BEGIN_TYPE feature = feature_index < BEGIN_DIMS ? begin[feature_index] : 0; -#ifdef OUTPUT_LAYOUT_BFZYX +#ifdef OUTPUT_LAYOUT_BFWZYX + BEGIN_TYPE w = w_index < BEGIN_DIMS ? begin[w_index] : 0; + BEGIN_TYPE z = z_index < BEGIN_DIMS ? begin[z_index] : 0; +#elif OUTPUT_LAYOUT_BFZYX BEGIN_TYPE z = z_index < BEGIN_DIMS ? begin[z_index] : 0; #endif BEGIN_TYPE y = y_index < BEGIN_DIMS ? begin[y_index] : 0; @@ -192,7 +233,10 @@ inline void FUNC(get_slice_begin)(OPTIONAL_SHAPE_INFO_ARG batch = (BEGIN_BATCH == 0) ? batch : 0; feature = (BEGIN_FEATURE == 0) ? feature : 0; -#ifdef OUTPUT_LAYOUT_BFZYX +#ifdef OUTPUT_LAYOUT_BFWZYX + w = (BEGIN_W == 0) ? w: 0; + z = (BEGIN_Z == 0) ? z: 0; +#elif OUTPUT_LAYOUT_BFZYX z = (BEGIN_Z == 0) ? z: 0; #endif y = (BEGIN_Y == 0) ? y : 0; @@ -201,8 +245,13 @@ inline void FUNC(get_slice_begin)(OPTIONAL_SHAPE_INFO_ARG *begin_batch = FUNC_CALL(check_begin_bound)(batch, out_batch_num); *begin_feature = FUNC_CALL(check_begin_bound)(feature, out_feature_num); #ifdef OUTPUT_LAYOUT_BFYX + *begin_w = 0; *begin_z = 0; #elif OUTPUT_LAYOUT_BFZYX + *begin_w = 0; + *begin_z = FUNC_CALL(check_begin_bound)(z, out_z_num); +#elif OUTPUT_LAYOUT_BFWZYX + *begin_w = FUNC_CALL(check_begin_bound)(w, out_w_num); *begin_z = FUNC_CALL(check_begin_bound)(z, out_z_num); #endif *begin_y = FUNC_CALL(check_begin_bound)(y, out_y_num); @@ -226,36 +275,40 @@ KERNEL(strided_slice_ref)(OPTIONAL_SHAPE_INFO_ARG const uint batch = get_global_id(0); const uint feature = get_global_id(1); #ifdef STRIDE_TYPE - int step_batch, step_feature, step_z, step_y, step_x; - FUNC_CALL(get_slice_step)(OPTIONAL_SHAPE_INFO_TENSOR stride, &step_batch, &step_feature, &step_z, &step_y, &step_x); + int step_batch, step_feature, step_w, step_z, step_y, step_x; + FUNC_CALL(get_slice_step)(OPTIONAL_SHAPE_INFO_TENSOR stride, &step_batch, &step_feature, &step_w, &step_z, &step_y, &step_x); const int slice_steps_batch = step_batch; const int slice_steps_feature = step_feature; + const int slice_steps_w = step_w; const int slice_steps_z = step_z; const int slice_steps_y = step_y; const int slice_steps_x = step_x; #else // STRIDE_TYPE const int slice_steps_batch = SLICE_STEPS_BATCH; const int slice_steps_feature = SLICE_STEPS_FEATURE; + const int slice_steps_w = SLICE_STEPS_W; const int slice_steps_z = SLICE_STEPS_Z; const int slice_steps_y = SLICE_STEPS_Y; const int slice_steps_x = SLICE_STEPS_X; #endif // STRIDE_TYPE #ifdef BEGIN_TYPE - int begin_batch, begin_feature, begin_z, begin_y, begin_x; - FUNC_CALL(get_slice_begin)(OPTIONAL_SHAPE_INFO_TENSOR begin, &begin_batch, &begin_feature, &begin_z, &begin_y, &begin_x); + int begin_batch, begin_feature, begin_w, begin_z, begin_y, begin_x; + FUNC_CALL(get_slice_begin)(OPTIONAL_SHAPE_INFO_TENSOR begin, &begin_batch, &begin_feature, &begin_w, &begin_z, &begin_y, &begin_x); #ifdef END_TYPE - FUNC_CALL(check_negative_stride)(OPTIONAL_SHAPE_INFO_TENSOR end, slice_steps_batch, slice_steps_feature, slice_steps_z, slice_steps_y, slice_steps_x, &begin_batch, &begin_feature, &begin_z, &begin_y, &begin_x); + FUNC_CALL(check_negative_stride)(OPTIONAL_SHAPE_INFO_TENSOR end, slice_steps_batch, slice_steps_feature, slice_steps_w, slice_steps_z, slice_steps_y, slice_steps_x, &begin_batch, &begin_feature, &begin_w, &begin_z, &begin_y, &begin_x); #else // END_TYPE - FUNC_CALL(check_negative_stride)(slice_steps_batch, slice_steps_feature, slice_steps_z, slice_steps_y, slice_steps_x, &begin_batch, &begin_feature, &begin_z, &begin_y, &begin_x); + FUNC_CALL(check_negative_stride)(slice_steps_batch, slice_steps_feature, slice_steps_w, slice_steps_z, slice_steps_y, slice_steps_x, &begin_batch, &begin_feature, &begin_w, &begin_z, &begin_y, &begin_x); #endif // END_TYPE const int slice_begin_batch = begin_batch; const int slice_begin_feature = begin_feature; + const int slice_begin_w = begin_w; const int slice_begin_z = begin_z; const int slice_begin_y = begin_y; const int slice_begin_x = begin_x; #else // BEGIN_TYPE const int slice_begin_batch = SLICE_BEGIN_BATCH; const int slice_begin_feature = SLICE_BEGIN_FEATURE; + const int slice_begin_w = SLICE_BEGIN_W; const int slice_begin_z = SLICE_BEGIN_Z; const int slice_begin_y = SLICE_BEGIN_Y; const int slice_begin_x = SLICE_BEGIN_X; @@ -264,32 +317,51 @@ KERNEL(strided_slice_ref)(OPTIONAL_SHAPE_INFO_ARG #if NEW_AXIS_MODE // If NEW_AXIS_MODE that just copy input to output #ifdef OUTPUT_LAYOUT_BFYX + const uint w_input = 0; const uint z_input = 0; const uint y_input = (uint)get_global_id(2) / INPUT0_SIZE_X; const uint x_input = (uint)get_global_id(2) % INPUT0_SIZE_X; #elif OUTPUT_LAYOUT_BFZYX + const uint w_input = 0; const uint yx_input = (uint)get_global_id(2) % (INPUT0_SIZE_X * INPUT0_SIZE_Y); const uint z_input = (uint)get_global_id(2) / (INPUT0_SIZE_X * INPUT0_SIZE_Y); const uint y_input = yx_input / INPUT0_SIZE_X; const uint x_input = yx_input % INPUT0_SIZE_X; +#elif OUTPUT_LAYOUT_BFWZYX + const uint zyx_input = (uint)get_global_id(2) % (INPUT0_SIZE_X * INPUT0_SIZE_Y * INPUT0_SIZE_Z); + const uint w_input = (uint)get_global_id(2) / (INPUT0_SIZE_X * INPUT0_SIZE_Y * INPUT0_SIZE_Z); + const uint z_input = zyx_input / (INPUT0_SIZE_X * INPUT0_SIZE_Y); + const uint yx_input = zyx_input % (INPUT0_SIZE_X * INPUT0_SIZE_Y); + const uint y_input = yx_input / INPUT0_SIZE_X; + const uint x_input = yx_input % INPUT0_SIZE_X; #endif const uint input_index = INPUT0_OFFSET + batch * INPUT0_BATCH_PITCH + feature * INPUT0_FEATURE_PITCH + + w_input * INPUT0_W_PITCH + z_input * INPUT0_Z_PITCH + y_input * INPUT0_Y_PITCH + x_input * INPUT0_X_PITCH; output[input_index] = input[input_index]; #else // NEW_AXIS_MODE #ifdef OUTPUT_LAYOUT_BFYX + const uint w = 0; const uint z = 0; const uint y = get_global_id(2) / OUTPUT_SIZE_X; const uint x = get_global_id(2) % OUTPUT_SIZE_X; #elif OUTPUT_LAYOUT_BFZYX + const uint w = 0; const uint yx = get_global_id(2) % (OUTPUT_SIZE_X * OUTPUT_SIZE_Y); const uint z = get_global_id(2) / (OUTPUT_SIZE_X * OUTPUT_SIZE_Y); const uint y = yx / OUTPUT_SIZE_X; const uint x = yx % OUTPUT_SIZE_X; +#elif OUTPUT_LAYOUT_BFWZYX + const uint zyx = (uint)get_global_id(2) % (OUTPUT_SIZE_X * OUTPUT_SIZE_Y * OUTPUT_SIZE_Z); + const uint w = (uint)get_global_id(2) / (OUTPUT_SIZE_X * OUTPUT_SIZE_Y * OUTPUT_SIZE_Z); + const uint z = zyx / (OUTPUT_SIZE_X * OUTPUT_SIZE_Y); + const uint yx = zyx % (OUTPUT_SIZE_X * OUTPUT_SIZE_Y); + const uint y = yx / OUTPUT_SIZE_X; + const uint x = yx % OUTPUT_SIZE_X; #endif #if SHRINK_MODE @@ -297,7 +369,12 @@ KERNEL(strided_slice_ref)(OPTIONAL_SHAPE_INFO_ARG const uint input_index = INPUT0_OFFSET + (slice_begin_batch + in_indices[0] * slice_steps_batch) * INPUT0_BATCH_PITCH + (slice_begin_feature + in_indices[1] * slice_steps_feature) * INPUT0_FEATURE_PITCH + - #if INPUT0_LAYOUT_BFZYX + #if INPUT0_LAYOUT_BFWZYX + (slice_begin_w + in_indices[2] * slice_steps_w) * INPUT0_W_PITCH + + (slice_begin_z + in_indices[3] * slice_steps_z) * INPUT0_Z_PITCH + + (slice_begin_y + in_indices[4] * slice_steps_y) * INPUT0_Y_PITCH + + (slice_begin_x + in_indices[5] * slice_steps_x) * INPUT0_X_PITCH; + #elif INPUT0_LAYOUT_BFZYX (slice_begin_z + in_indices[2] * slice_steps_z) * INPUT0_Z_PITCH + (slice_begin_y + in_indices[3] * slice_steps_y) * INPUT0_Y_PITCH + (slice_begin_x + in_indices[4] * slice_steps_x) * INPUT0_X_PITCH; @@ -309,6 +386,7 @@ KERNEL(strided_slice_ref)(OPTIONAL_SHAPE_INFO_ARG const uint input_index = INPUT0_OFFSET + (slice_begin_batch + batch * slice_steps_batch) * INPUT0_BATCH_PITCH + (slice_begin_feature + feature * slice_steps_feature) * INPUT0_FEATURE_PITCH + + (slice_begin_w + w * slice_steps_w) * INPUT0_W_PITCH + (slice_begin_z + z * slice_steps_z) * INPUT0_Z_PITCH + (slice_begin_y + y * slice_steps_y) * INPUT0_Y_PITCH + (slice_begin_x + x * slice_steps_x) * INPUT0_X_PITCH; @@ -317,6 +395,7 @@ KERNEL(strided_slice_ref)(OPTIONAL_SHAPE_INFO_ARG const uint output_index = OUTPUT_OFFSET + batch * OUTPUT_BATCH_PITCH + feature * OUTPUT_FEATURE_PITCH + + w * OUTPUT_W_PITCH + z * OUTPUT_Z_PITCH + y * OUTPUT_Y_PITCH + x * OUTPUT_X_PITCH; diff --git a/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp b/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp index 92dbe560ef6e1d..20d8e63ae29580 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/jitter.cpp @@ -663,6 +663,11 @@ class WeightTensorJitConstant : public TensorBaseTJitConstant; if (l == WeightsLayout::oiyx || l == WeightsLayout::ioyx || + l == WeightsLayout::oyxi || + l == WeightsLayout::oyix || + l == WeightsLayout::oxiy || + l == WeightsLayout::iyxo || + l == WeightsLayout::yxio || l == WeightsLayout::iozyx || l == WeightsLayout::oizyx || l == WeightsLayout::goiyx || @@ -974,7 +979,10 @@ JitDefinitions WeightTensorJitConstant::GetDefinitions() const { bool is_common_4d_layout = is_common_nd_layout(base_4d_channels, layout); if (is_common_4d_layout) { index_macro_name = _name + "_GET_INDEX(o, i, y, x)"; - if (layout == WeightsLayout::oiyx || layout == WeightsLayout::ioyx) + if (layout == WeightsLayout::oiyx || layout == WeightsLayout::ioyx || + layout == WeightsLayout::oyxi || layout == WeightsLayout::oyix || + layout == WeightsLayout::oxiy || layout == WeightsLayout::iyxo || + layout == WeightsLayout::yxio) index_func_val = called_func_name + "(" + _name + ", 0, o, i, 0, y, x)"; else if (layout == WeightsLayout::os_is_yx_isv16_osv16) index_func_val = called_func_name + "(" + _name + ", 0, o, i, 0, y, x, 16)"; diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_common.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_common.cpp index dfae8451980674..49e3e2a1f2edd4 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_common.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_common.cpp @@ -92,6 +92,7 @@ std::string toString(DataLayout l) { case kernel_selector::DataLayout::byxf: return "BYXF"; case kernel_selector::DataLayout::byfx: return "BYFX"; case kernel_selector::DataLayout::bxfy: return "BXFY"; + case kernel_selector::DataLayout::fbyx: return "FBYX"; case kernel_selector::DataLayout::fyxb: return "FYXB"; case kernel_selector::DataLayout::b_fs_yx_fsv2: return "B_FS_YX_FSV2"; case kernel_selector::DataLayout::b_fs_yx_fsv4: return "B_FS_YX_FSV4"; diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_utils.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_utils.cpp index 59a003c554eb62..a2e0226367d7e7 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_utils.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernel_selector_utils.cpp @@ -289,6 +289,9 @@ std::vector GetOptimalLocalWorkGroupSizes(std::vector gws, const case DataLayout::bxfy: layout_order = { y, f, x, b, z, w, u, v }; break; + case DataLayout::fbyx: + layout_order = { x, y, b, f, z, w, u, v }; + break; case DataLayout::fyxb: layout_order = { b, x, y, f, z, w, u, v }; break; diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernels/reorder/reorder_weights_opt.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernels/reorder/reorder_weights_opt.cpp index 9a9333c757be4f..6ff7daa348485a 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernels/reorder/reorder_weights_opt.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernels/reorder/reorder_weights_opt.cpp @@ -20,6 +20,11 @@ ParamsKey ReorderWeightsOpt::GetSupportedKey() const { k.EnableOutputWeightsType(WeightsType::INT32); k.EnableInputWeightsLayout(WeightsLayout::oiyx); k.EnableInputWeightsLayout(WeightsLayout::ioyx); + k.EnableInputWeightsLayout(WeightsLayout::oyxi); + k.EnableInputWeightsLayout(WeightsLayout::oyix); + k.EnableInputWeightsLayout(WeightsLayout::oxiy); + k.EnableInputWeightsLayout(WeightsLayout::iyxo); + k.EnableInputWeightsLayout(WeightsLayout::yxio); k.EnableInputWeightsLayout(WeightsLayout::oizyx); k.EnableInputWeightsLayout(WeightsLayout::iozyx); k.EnableInputWeightsLayout(WeightsLayout::goiyx); diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp index 8c64249302c85f..88e80f0c05851b 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp @@ -14,11 +14,18 @@ static void makeJitConstForParam(JitConstants& jit, const std::string name, cons jit.AddConstant(MakeJitConstant(name + "_SIZES", vec)); jit.AddConstant(MakeJitConstant(name + "_BATCH", vec[0])); jit.AddConstant(MakeJitConstant(name + "_FEATURE", vec[1])); - if (vec.size() == 5) { // BFZYX + if (vec.size() == 6) { // BFWZYX + jit.AddConstant(MakeJitConstant(name + "_W", vec[2])); + jit.AddConstant(MakeJitConstant(name + "_Z", vec[3])); + jit.AddConstant(MakeJitConstant(name + "_Y", vec[4])); + jit.AddConstant(MakeJitConstant(name + "_X", vec[5])); + } else if (vec.size() == 5) { // BFZYX + jit.AddConstant(MakeJitConstant(name + "_W", 0)); jit.AddConstant(MakeJitConstant(name + "_Z", vec[2])); jit.AddConstant(MakeJitConstant(name + "_Y", vec[3])); jit.AddConstant(MakeJitConstant(name + "_X", vec[4])); } else { // BFYX + jit.AddConstant(MakeJitConstant(name + "_W", 0)); jit.AddConstant(MakeJitConstant(name + "_Z", 0)); jit.AddConstant(MakeJitConstant(name + "_Y", vec[2])); jit.AddConstant(MakeJitConstant(name + "_X", vec[3])); @@ -27,7 +34,7 @@ static void makeJitConstForParam(JitConstants& jit, const std::string name, cons static size_t GetUsedOutDimsCount(const strided_slice_params& params) { auto dims = params.outputs[0].GetDims(); - size_t first_non_unit_dim = 0; // order is xy(z)fb, so by default consider that we use all dims + size_t first_non_unit_dim = 0; // order is xy(zw)fb, so by default consider that we use all dims for (size_t i = 0; i < dims.size(); i++) { if (dims[i].v != 1) { break; @@ -70,7 +77,7 @@ bool StridedSliceKernelRef::Validate(const Params& p, const optional_params& o) if (params.inputs.empty()) return false; - if (params.outputs[0].Dimentions() > 5 || params.inputs[0].Dimentions() > 5) + if (params.outputs[0].Dimentions() > 6 || params.inputs[0].Dimentions() > 6) return false; for (auto& fused_op : params.fused_ops) { @@ -86,7 +93,7 @@ bool StridedSliceKernelRef::Validate(const Params& p, const optional_params& o) size_t used_out_dims = GetUsedOutDimsCount(params); // Count of actual output dims + count of shrinked axes shouldn't exceed 5 to be able to find input index correctly - if (used_out_dims + shrinked_axes > 5) { + if (used_out_dims + shrinked_axes > 6) { return false; } } @@ -99,14 +106,15 @@ CommonDispatchData StridedSliceKernelRef::SetDefault(const strided_slice_params& auto out_layout = params.outputs[0].GetLayout(); std::vector> dims_by_gws = {{ Tensor::DataChannelName::BATCH }, { Tensor::DataChannelName::FEATURE }, - { Tensor::DataChannelName::X, Tensor::DataChannelName::Y, Tensor::DataChannelName::Z }}; + { Tensor::DataChannelName::X, Tensor::DataChannelName::Y, + Tensor::DataChannelName::Z, Tensor::DataChannelName::W }}; // If the new_axis_mask is set, then begin, end, and stride are ignored // and a new length 1 dimension is adding. Input data just copying to output // TODO: remove data copying in case where only shape size changing dispatchData.gws = { params.outputs[0].Batch().v, params.outputs[0].Feature().v, - params.outputs[0].Z().v * params.outputs[0].Y().v * params.outputs[0].X().v }; + params.outputs[0].W().v * params.outputs[0].Z().v * params.outputs[0].Y().v * params.outputs[0].X().v }; dispatchData.lws = GetOptimalLocalWorkGroupSizes(dispatchData.gws, params.engineInfo, in_layout, out_layout, dims_by_gws); @@ -161,33 +169,37 @@ JitConstants StridedSliceKernelRef::GetJitConstants(const strided_slice_params& if (shrink_mode) { jit.AddConstant(MakeJitConstant("SHRINK_MODE", true)); makeJitConstForParam(jit, "SHRINK", params.shrink_axis_mask); - std::vector bfzyx_in_order; - if (params.outputs[0].Dimentions() == 5) - bfzyx_in_order = {"batch", "feature", "z", "y", "x"}; + std::vector bfwzyx_in_order; + if (params.outputs[0].Dimentions() == 6) + bfwzyx_in_order = {"batch", "feature", "w", "z", "y", "x"}; + else if (params.outputs[0].Dimentions() == 5) + bfwzyx_in_order = {"batch", "feature", "z", "y", "x"}; else - bfzyx_in_order = {"batch", "feature", "y", "x"}; + bfwzyx_in_order = {"batch", "feature", "y", "x"}; // Insert zeroes to indices order for shinked axes for (size_t i = 0; i < params.shrink_axis_mask.size(); i++) { if (params.shrink_axis_mask[i] == 1) { - bfzyx_in_order.insert(bfzyx_in_order.begin() + i, "0"); + bfwzyx_in_order.insert(bfwzyx_in_order.begin() + i, "0"); } } - auto get_input_idx_order = [&](std::vector bfzyx_in_order) -> std::string { - return bfzyx_in_order[0] + "," + - bfzyx_in_order[1] + "," + - bfzyx_in_order[2] + "," + - bfzyx_in_order[3] + "," + - bfzyx_in_order[4]; + auto get_input_idx_order = [&](std::vector bfwzyx_in_order) -> std::string { + std::string order = bfwzyx_in_order[0] + "," + + bfwzyx_in_order[1] + "," + + bfwzyx_in_order[2] + "," + + bfwzyx_in_order[3] + "," + + bfwzyx_in_order[4]; + if (bfwzyx_in_order.size() == 6) order += "," + bfwzyx_in_order[5]; + return order; }; - // Erase indices that exceeds 5d tensor. It should be safe, because we check in Validate method that + // Erase indices that exceeds 6d tensor. It should be safe, because we check in Validate method that // shrinked axes don't result in too big dims count - while (bfzyx_in_order.size() > 5) { - bfzyx_in_order.pop_back(); + while (bfwzyx_in_order.size() > 6) { + bfwzyx_in_order.pop_back(); } - jit.AddConstant(MakeJitConstant("INPUT_INDICES_ORDER", get_input_idx_order(bfzyx_in_order))); + jit.AddConstant(MakeJitConstant("INPUT_INDICES_ORDER", get_input_idx_order(bfwzyx_in_order))); } return jit; @@ -211,7 +223,9 @@ KernelsData StridedSliceKernelRef::GetKernelsData(const Params& params, const op if (!newParams.fused_ops.empty()) { std::vector idx_order; - if (input.Dimentions() == 5) { + if (input.Dimentions() == 6) { + idx_order = {"b", "f", "w", "z", "y", "x"}; + } else if (input.Dimentions() == 5) { idx_order = {"b", "f", "z", "y", "x"}; } else if (input.Dimentions() == 4) { idx_order = {"b", "f", "y", "x"}; diff --git a/src/plugins/intel_gpu/src/kernel_selector/tensor_type.cpp b/src/plugins/intel_gpu/src/kernel_selector/tensor_type.cpp index e0e57ede49999e..545f01c6f3801e 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/tensor_type.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/tensor_type.cpp @@ -23,6 +23,7 @@ DataTensor::DataChannelArray DataTensor::dataChannelArray {{ { DataLayout::byxf, { 1, 2, -1, -1, -1, -1, 0, 3 } }, { DataLayout::byfx, { 0, 2, -1, -1, -1, -1, 1, 3 } }, { DataLayout::bxfy, { 2, 0, -1, -1, -1, -1, 1, 3 } }, + { DataLayout::fbyx, { 0, 1, -1, -1, -1, -1, 3, 2 } }, { DataLayout::fyxb, { 1, 2, -1, -1, -1, -1, 3, 0 } }, { DataLayout::b_fs_yx_fsv2, { 0, 1, -1, -1, -1, -1, 2, 3 } }, { DataLayout::b_fs_yx_fsv4, { 0, 1, -1, -1, -1, -1, 2, 3 } }, diff --git a/src/plugins/intel_gpu/src/kernel_selector/tensor_type.h b/src/plugins/intel_gpu/src/kernel_selector/tensor_type.h index 8da7dec329c2a0..85cec1fe17cf42 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/tensor_type.h +++ b/src/plugins/intel_gpu/src/kernel_selector/tensor_type.h @@ -32,6 +32,7 @@ enum DataLayout { yxfb, // 3D+batch byxf, // 3D+batch fyxb, // 3D+batch + fbyx, // 3D+batch bfxy, // 3D+batch byfx, bxfy, @@ -318,6 +319,7 @@ inline bool SimpleLayout(DataLayout l) { case DataLayout::byxf: case DataLayout::byfx: case DataLayout::bxfy: + case DataLayout::fbyx: case DataLayout::fyxb: case DataLayout::bfxy: case DataLayout::bfzyx: diff --git a/src/plugins/intel_gpu/src/plugin/transformations/convert_matmul_to_fc.cpp b/src/plugins/intel_gpu/src/plugin/transformations/convert_matmul_to_fc.cpp index 5d4531a54967c5..a30c88e7d1492d 100644 --- a/src/plugins/intel_gpu/src/plugin/transformations/convert_matmul_to_fc.cpp +++ b/src/plugins/intel_gpu/src/plugin/transformations/convert_matmul_to_fc.cpp @@ -46,12 +46,8 @@ ConvertMatMulToFullyConnected::ConvertMatMulToFullyConnected() { auto fc_input_b = pattern_map.at(weights_m); bool is_convert = false; if (auto convert_node = std::dynamic_pointer_cast(fc_input_b.get_node_shared_ptr())) { - if (is_decompression(convert_node)) { - is_convert = true; - fc_input_b = convert_node->get_input_node_shared_ptr(0); - } else { - return false; - } + is_convert = true; + fc_input_b = convert_node->get_input_node_shared_ptr(0); } auto shape_a = fc_input_a.get_partial_shape(); diff --git a/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp b/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp index 6aff07cfdd4b16..14122656fc5145 100644 --- a/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp +++ b/src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp @@ -50,6 +50,7 @@ #include "transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp" #include "transformations/fp16_compression/convert_compression_only_to_legacy.hpp" +#include "transformations/fp16_compression/mark_decompression_convert_constant_folding.hpp" #include "transformations/common_optimizations/common_optimizations.hpp" #include "transformations/common_optimizations/lin_op_sequence_fusion.hpp" #include "transformations/common_optimizations/weights_dequantize_to_fake_quantize.hpp" @@ -58,7 +59,6 @@ #include "transformations/common_optimizations/transpose_sinking.hpp" #include "transformations/common_optimizations/softmax_fusion.hpp" #include "transformations/common_optimizations/mvn_fusion.hpp" -#include "transformations/common_optimizations/compress_float_constants.hpp" #include "transformations/op_conversions/convert_depth_to_space.hpp" #include "transformations/op_conversions/convert_space_to_depth.hpp" @@ -220,14 +220,17 @@ void TransformationsPipeline::apply(std::shared_ptr func) { // decompose MVNs that sre not supported in GPU, so that they will be marked as precision sensitive in ConvertPrecision manager.register_pass(); - auto is_matmul_output = [](const_node_ptr &node) -> bool { - const auto outputs = node->get_output_target_inputs(0); - return !is_type(outputs.begin()->get_node()); - }; + manager.register_pass(); + pass_config->set_callback( + [](const_node_ptr& node) -> bool { + auto next_node = node->get_output_target_inputs(0).begin()->get_node(); + if (is_type(next_node)) { + next_node = next_node->get_output_target_inputs(0).begin()->get_node(); + } + return !is_type(next_node); + }); - manager.register_pass(); manager.register_pass(ov::element::TypeVector{ov::element::u8}, true); - pass_config->set_callback(is_matmul_output); const bool keep_precision_sensitive_in_fp32_1 = true; const bool convert_input_output_precision = false; diff --git a/src/plugins/intel_gpu/src/runtime/format.cpp b/src/plugins/intel_gpu/src/runtime/format.cpp index a3c6f766bca149..af268e94daae76 100644 --- a/src/plugins/intel_gpu/src/runtime/format.cpp +++ b/src/plugins/intel_gpu/src/runtime/format.cpp @@ -25,6 +25,7 @@ static const std::map format_traits_map { FMT_TRAITS(yxfb, 1, 1, 2, 0, {2, 3, 1, 0}, "yxfb", "bfxy", {}), FMT_TRAITS(byxf, 1, 1, 2, 0, {0, 2, 3, 1}, "byxf", "bfxy", {}), FMT_TRAITS(bfyx, 1, 1, 2, 0, {0, 1, 2, 3}, "bfyx", "bfxy", {}), + FMT_TRAITS(fbyx, 1, 1, 2, 0, {1, 0, 2, 3}, "fbyx", "bfxy", {}), FMT_TRAITS(fyxb, 1, 1, 2, 0, {1, 2, 3, 0}, "fyxb", "bfxy", {}), FMT_TRAITS(byfx, 1, 1, 2, 0, {0, 2, 1, 3}, "byfx", "bfxy", {}), FMT_TRAITS(bxfy, 1, 1, 2, 0, {0, 3, 1, 2}, "bxfy", "bfxy", {}), @@ -45,7 +46,7 @@ static const std::map format_traits_map { FMT_TRAITS(bfuwzyx, 1, 1, 5, 0, {0, 1, 2, 3, 4, 5, 6}, "bfuwzyx", "bfxyzwu", {}), FMT_TRAITS(bfvuwzyx, 1, 1, 6, 0, {0, 1, 2, 3, 4, 5, 6, 7}, "bfvuwzyx", "bfxyzwuv", {}), FMT_TRAITS(fs_b_yx_fsv32, 1, 1, 2, 0, {1, 0, 2, 3}, "fbyx", "bfxy", {{1, 32}}), - FMT_TRAITS(b_fs_yx_32fp, 1, 1, 2, 0, {0, 1, 2, 3}, "bfyx", "bfxy", {}), + FMT_TRAITS(b_fs_yx_32fp, 1, 1, 2, 0, {0, 1, 2, 3}, "bfyx", "bfxy", {{1, 32}}), FMT_TRAITS(b_fs_zyx_fsv16, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "bfzyx", "bfxyz", {{1, 16}}), FMT_TRAITS(bs_fs_zyx_bsv16_fsv32, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "bfzyx", "bfxyz", {{0, 16 }, {1, 32}}), FMT_TRAITS(bs_fs_zyx_bsv16_fsv16, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "bfzyx", "bfxyz", {{0, 16 }, {1, 16}}), @@ -93,9 +94,7 @@ static const std::map format_traits_map { FMT_TRAITS(image_2d_weights_c4_fyx_b, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {}), FMT_TRAITS(image_2d_weights_c1_b_fyx, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {}), FMT_TRAITS(lstm_weights_dio, 1, 1, 2, 0, {0, 1, 3, 2}, "oixy", "oixy", {}), - FMT_TRAITS(os_is_yx_isa8_osv8_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{1, 8}, {0, 8}, {1, 4}}), FMT_TRAITS(os_is_yx_isa8_osv16_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{1, 8}, {0, 16}, {1, 4}}), - FMT_TRAITS(os_is_yx_isa8_osv8_isv4_swizzled_by_4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {}), FMT_TRAITS(os_is_yx_osa4_isa8_osv8_isv2, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 4}, {1, 8}, {0, 8}, {1, 2}}), FMT_TRAITS(os_is_yx_osa4_isa8_osv8_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 4}, {1, 8}, {0, 8}, {1, 4}}), FMT_TRAITS(os_is_zyx_osa4_isa8_osv8_isv2, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "oizyx", "oixyz", {{0, 4}, {1, 8}, {0, 8}, {1, 2}}), @@ -112,9 +111,9 @@ static const std::map format_traits_map { FMT_TRAITS(is_os_yx_isa2_osa8_isv8_osv2, 1, 1, 2, 0, {1, 0, 2, 3}, "ioyx", "oixy", {{1, 2}, {0, 8}, {1, 8}, {0, 2}}), FMT_TRAITS(is_os_yx_isa4_osa8_isv8_osv4, 1, 1, 2, 0, {1, 0, 2, 3}, "ioyx", "oixy", {{1, 4}, {0, 8}, {1, 8}, {0, 4}}), FMT_TRAITS(is_o_yx_isv32, 1, 1, 2, 0, {1, 0, 2, 3}, "oyxi", "oixy", {{1, 32}}), - FMT_TRAITS(is_o32_yx_isv32_swizzled_by_4, 1, 1, 2, 0, {0, 1, 2, 3}, "oyxi", "oixy", {}), - FMT_TRAITS(os_is_y_x8_osv8_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oyxi", "oixy", {}), - FMT_TRAITS(os_is_y_x8_osv8_isv4_swizzled_by_4, 1, 1, 2, 0, {0, 1, 2, 3}, "oyxi", "oixy", {}), + FMT_TRAITS(is_o32_yx_isv32_swizzled_by_4, 1, 1, 2, 0, {0, 1, 2, 3}, "oyxi", "oixy", {{0, 32}, {1, 32}}), + FMT_TRAITS(os_is_y_x8_osv8_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oyxi", "oixy", {{0, 8}, {1, 4}, {2, 8}}), + FMT_TRAITS(os_is_y_x8_osv8_isv4_swizzled_by_4, 1, 1, 2, 0, {0, 1, 2, 3}, "oyxi", "oixy", {{0, 8}, {1, 4}, {2, 8}}), FMT_TRAITS(os_is_yx_osv16_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 16}, {1, 4}}), FMT_TRAITS(os_is_yx_osv8_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 8}, {1, 4}}), FMT_TRAITS(os_is_zyx_osv8_isv4, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "oizyx", "oixyz", {{0, 8}, {1, 4}}), @@ -124,7 +123,7 @@ static const std::map format_traits_map { FMT_TRAITS(os_is_yx_osv32_isv4_swizzled_by_2, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 32}, {1, 4}}), FMT_TRAITS(os_is_yx_osv32_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 32}, {1, 4}}), FMT_TRAITS(os_is_zyx_osv32_isv4, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "oizyx", "oixyz", {{0, 32}, {1, 4}}), - FMT_TRAITS(os_is_yx_osv32_isv32p, 1, 1, 1, 0, {0, 1, 2, 3}, "oiyx", "oixy", {}), + FMT_TRAITS(os_is_yx_osv32_isv32p, 1, 1, 1, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 32}, {1, 32}}), FMT_TRAITS(os_is_zyx_isv16_osv16, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "oizyx", "oixyz", {{1, 16}, {0, 16}}), FMT_TRAITS(is_os_zyx_isv16_osv16, 1, 1, 3, 0, {1, 0, 2, 3, 4}, "iozyx", "oixyz", {{1, 16}, {0, 16}}), FMT_TRAITS(is_os_yx_isv16_osv16, 1, 1, 2, 0, {1, 0, 2, 3}, "ioyx", "oixy", {{1, 16}, {0, 16}}), @@ -140,6 +139,7 @@ static const std::map format_traits_map { FMT_TRAITS(is_os_yx_isa8_osv8_isv4, 1, 1, 2, 0, {1, 0, 2, 3}, "ioyx", "oixy", {{1, 8}, {0, 8}, {1, 4}}), FMT_TRAITS(is_os_yx_osa8_isv16_osv4, 1, 1, 2, 0, {1, 0, 2, 3}, "ioyx", "oixy", {{0, 8}, {1, 16}, {0, 4}}), FMT_TRAITS(os_is_yx_isa8_osv8_isv4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{1, 8}, {0, 8}, {1, 4}}), + FMT_TRAITS(os_is_yx_isa8_osv8_isv4_swizzled_by_4, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{1, 32}, {0, 32}}), FMT_TRAITS(os_is_yx_isa8_osv8_isv2, 1, 1, 2, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{1, 8}, {0, 8}, {1, 2}}), FMT_TRAITS(os_is_osv32_isv32_swizzled_by_4, 1, 1, 0, 0, {0, 1, 2, 3}, "oiyx", "oixy", {{0, 32}, {1, 32}}), FMT_TRAITS(os_is_zyx_isv8_osv16_isv2, 1, 1, 3, 0, {0, 1, 2, 3, 4}, "oizyx", "oixyz", {{1, 8}, {0, 16}, {1, 2}}), @@ -344,4 +344,34 @@ const std::vector> format::per_axis_block_size(format fmt return sizes_for_dims; } + +format format::find_format(const std::vector& order, + const std::vector>& block_sizes, + bool is_weights, + bool is_grouped, + bool is_image_2d, + bool is_winograd, + bool is_nv12) { + auto is_suitable_traits = [&](const std::pair& traits) -> bool { + return traits.second._order == order && + traits.second.block_sizes == block_sizes && + format::is_weights_format(traits.first) == is_weights && + format::is_grouped(traits.first) == is_grouped && + format::is_image_2d(traits.first) == is_image_2d && + format::is_winograd(traits.first) == is_winograd && + format::is_nv12(traits.first) == is_nv12; + }; + + std::vector finded_formats; + for (auto& traits : format_traits_map) { + if (is_suitable_traits(traits)) + finded_formats.emplace_back(traits.first); + } + + OPENVINO_ASSERT(!finded_formats.empty(), "[GPU] Cannot find a format with the specified parameters"); + OPENVINO_ASSERT(finded_formats.size() == 1, "[GPU] Cannot find a format. Specified parameters are ambiguous"); + + return finded_formats.front(); +} + } // namespace cldnn diff --git a/src/plugins/intel_gpu/src/runtime/layout.cpp b/src/plugins/intel_gpu/src/runtime/layout.cpp index e00aa0ff16c1ce..0ca5e60de610ed 100644 --- a/src/plugins/intel_gpu/src/runtime/layout.cpp +++ b/src/plugins/intel_gpu/src/runtime/layout.cpp @@ -138,6 +138,8 @@ static format to_weights_format(format f, bool is_grouped) { switch (f) { case format::bfyx: return format::oiyx; + case format::fbyx: + return format::ioyx; case format::fyxb: return format::iyxo; case format::byxf: diff --git a/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp b/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp index d039d644f7f4a6..052d6574d682d7 100644 --- a/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp +++ b/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp @@ -271,5 +271,57 @@ INSTANTIATE_TEST_SUITE_P(smoke_CompareWithRefs_Common_Dynamic_4D, StridedSliceLa ::testing::Values(emptyAdditionalConfig)), StridedSliceLayerGPUTest::getTestCaseName); + +const std::vector testCasesCommon5D = { + StridedSliceParams{ { 0, 2, 5, 4 }, { 1, 4, 28, 27 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceParams{ { 0, 0, 10, 20 }, { 1, 5, 28, 26 }, { 1, 1, 1, 2 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceParams{ { 0, 0, 0, 20 }, { 1, 2, 30, 30 }, { 1, 1, 2, 1 }, { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { }, { }, { } }, + StridedSliceParams{ { 0, 1, 2, 10 }, { 1, 5, 32, 18 }, { 1, 1, 1, 2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceParams{ { 0, 0, 2, 10 }, { 1, 8, 32, 18 }, { 1, 2, 1, 2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, +}; + +const std::vector inputShapesDynamic5D = { + {{-1, -1, -1, -1, -1}, + {{ 1, 5, 32, 32, 32 }, { 2, 5, 32, 32, 32 }, { 1, 5, 64, 64, 64 }}}, + + {{1, 64, -1, -1, -1}, + {{ 1, 64, 1, 16, 32 }, { 1, 64, 1, 32, 64 }, { 1, 64, 1, 64, 64 }}}, + + {{1, -1, 16, 32, -1}, + {{ 1, 16, 16, 32, 1 }, { 1, 32, 16, 32, 1 }, { 1, 64, 16, 32, 1 }}}, +}; + +INSTANTIATE_TEST_SUITE_P(smoke_CompareWithRefs_Common_Dynamic_5D, StridedSliceLayerGPUTest, + ::testing::Combine( + ::testing::ValuesIn(inputShapesDynamic5D), + ::testing::ValuesIn(testCasesCommon5D), + ::testing::ValuesIn(inputPrecisions), + ::testing::ValuesIn(restInputTypes), + ::testing::Values(emptyAdditionalConfig)), + StridedSliceLayerGPUTest::getTestCaseName); + + +const std::vector testCasesCommon6D = { + StridedSliceParams{ { 0, 2, 5, 4 }, { 1, 4, 28, 27 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceParams{ { 0, 0, 10, 20 }, { 1, 5, 28, 26 }, { 1, 1, 1, 2 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, +}; + +const std::vector inputShapesDynamic6D = { + {{-1, -1, -1, -1, -1, -1}, + {{ 1, 5, 5, 32, 32, 32 }, { 2, 5, 7, 32, 32, 64 }, { 1, 3, 5, 64, 64, 64 }}}, + + {{1, -1, 16, 32, -1, -1}, + {{ 1, 16, 16, 32, 1, 32 }, { 1, 32, 16, 32, 32, 64 }, { 1, 64, 16, 32, 32, 64 }}}, +}; + +INSTANTIATE_TEST_SUITE_P(smoke_CompareWithRefs_Common_Dynamic_6D, StridedSliceLayerGPUTest, + ::testing::Combine( + ::testing::ValuesIn(inputShapesDynamic6D), + ::testing::ValuesIn(testCasesCommon6D), + ::testing::ValuesIn(inputPrecisions), + ::testing::ValuesIn(restInputTypes), + ::testing::Values(emptyAdditionalConfig)), + StridedSliceLayerGPUTest::getTestCaseName); + } // namespace } // namespace GPULayerTestsDefinitions diff --git a/src/plugins/intel_gpu/tests/functional/subgraph_tests/dynamic/matmul_weights_decompression.cpp b/src/plugins/intel_gpu/tests/functional/subgraph_tests/dynamic/matmul_weights_decompression.cpp index 01f7f43749bf2c..5eaa69d4e627c2 100644 --- a/src/plugins/intel_gpu/tests/functional/subgraph_tests/dynamic/matmul_weights_decompression.cpp +++ b/src/plugins/intel_gpu/tests/functional/subgraph_tests/dynamic/matmul_weights_decompression.cpp @@ -194,11 +194,9 @@ const std::vector activations_precisions = {ov::element:: const std::vector weights_precisions = {ov::element::u8}; const std::vector> input_shapes_basic = { {{{-1, -1, -1}, {{1, 4, 16}, {10, 16, 16}}}, {{}, {{16, 32}}}}, - {{{}, {{1, 4, 16}}}, {{}, {{1, 16, 32}}}}, {{{}, {{10, 40, 496}}}, {{}, {{1, 496, 240}}}}, {{{}, {{1, 4, 48}}}, {{}, {{48, 256}}}}, {{{}, {{11, 339, 377}}}, {{}, {{377, 335}}}}, - {{{-1, -1, -1}, {{10, 40, 480}, {11, 40, 480}}}, {{}, {{1, 480, 256}}}}, {{{}, {{1, 4, 32}}}, {{}, {{32, 256}}}}, {{{}, {{1, 4, 512}}}, {{}, {{512, 256}}}}, {{{}, {{1, 16, 32}}}, {{}, {{32, 64}}}}, @@ -220,7 +218,10 @@ INSTANTIATE_TEST_SUITE_P(smoke_MatMulCompressedWeights_basic, const std::vector> input_shapes_corner_cases_basic = { {{{-1, -1, -1}, {{1, 4, 16}}}, {{}, {{1, 16, 32}}}}, + {{{}, {{1, 4, 16}}}, {{}, {{1, 16, 32}}}}, {{{-1, -1, -1}, {{1, 4, 16}}}, {{}, {{16, 32}}}}, + {{{-1, -1, -1, -1}, {{1, 1, 4, 16}}}, {{}, {{1, 1, 16, 32}}}}, + {{{}, {{1, 1, 4, 16}}}, {{}, {{1, 1, 16, 32}}}}, }; const std::vector> input_shapes_corner_cases_big = { {{{-1, -1, -1}, {{10, 40, 480}, {11, 40, 480}}}, {{}, {{1, 480, 256}}}}, diff --git a/src/plugins/intel_gpu/tests/unit/module_tests/format_test.cpp b/src/plugins/intel_gpu/tests/unit/module_tests/format_test.cpp index 2fbdc2fb3c2c73..98169c608f2bfb 100644 --- a/src/plugins/intel_gpu/tests/unit/module_tests/format_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/module_tests/format_test.cpp @@ -148,3 +148,90 @@ INSTANTIATE_TEST_SUITE_P(smoke, axes_test_format, {format::gs_oizyx_gsv16, {{8, 16}}, {{8, 16}}}, }), axes_test_format::PrintToString); + +struct find_format_test_params { + std::vector dims_order; + std::vector> block_sizes; + bool is_weights; + bool is_grouped; + bool is_image_2d; + bool is_winograd; + bool is_nv12; + format expected_format; +}; + +class find_format_test : public testing::TestWithParam { +public: + static std::string PrintToString(testing::TestParamInfo param_info) { + auto& p = param_info.param; + + std::string res = "order = ["; + for (size_t i = 0; i < p.dims_order.size() - 1; ++i) { + res += std::to_string(p.dims_order[i]) + ", "; + } + res += std::to_string(p.dims_order.back()) + "], "; + + res += "block_sizes = ["; + for (auto block : p.block_sizes) { + res += "{ " + std::to_string(block.first) + ", " + std::to_string(block.second) + "}"; + } + res += "], "; + + res += "is_weights = " + std::to_string(p.is_weights) + ", " + + "is_grouped = " + std::to_string(p.is_grouped) + ", " + + "is_image_2d = " + std::to_string(p.is_image_2d) + ", " + + "is_winograd = " + std::to_string(p.is_winograd) + ", " + + "is_nv12 = " + std::to_string(p.is_nv12) + ", " + + "expected_format = " + param_info.param.expected_format.to_string(); + + return res; + } + }; + +TEST_P(find_format_test, simple_test) { + auto p = GetParam(); + + if (p.expected_format == format::any) { + ASSERT_ANY_THROW(format::find_format(p.dims_order, p.block_sizes, + p.is_weights, p.is_grouped, p.is_image_2d, p.is_winograd, p.is_nv12)); + } else { + ASSERT_EQ(format::find_format(p.dims_order, p.block_sizes, + p.is_weights, p.is_grouped, p.is_image_2d, p.is_winograd, p.is_nv12), p.expected_format); + } +} + +INSTANTIATE_TEST_SUITE_P(smoke, find_format_test, + testing::ValuesIn(std::vector{ + // Dims order Block sizes is_weights is_grouped is_image_2d is_winograd is_nv12 Expected format + {{0, 1, 2, 3}, {}, false, false, false, false, false, format::bfyx}, + {{1, 0, 2, 3}, {}, false, false, false, false, false, format::fbyx}, + {{2, 3, 1, 0}, {}, false, false, false, false, false, format::yxfb}, + {{0, 2, 3, 1}, {}, false, false, false, false, false, format::byxf}, + {{1, 2, 3, 0}, {}, false, false, false, false, false, format::fyxb}, + {{0, 2, 1, 3}, {}, false, false, false, false, false, format::byfx}, + {{0, 3, 1, 2}, {}, false, false, false, false, false, format::bxfy}, + {{0, 1, 2, 3}, {{1, 16}}, false, false, false, false, false, format::b_fs_yx_fsv16}, + {{0, 1}, {{0, 8}, {1, 8}}, false, false, false, false, false, format::bs_fs_fsv8_bsv8}, + {{0, 1, 2, 3, 4, 5, 6}, {}, false, false, false, false, false, format::bfuwzyx}, + {{0, 1, 2, 3}, {}, false, false, true, false, true, format::nv12}, + {{0, 1, 2, 3}, {}, false, false, true, false, false, format::image_2d_rgba}, + {{0, 1, 2, 3}, {}, true, false, false, false, false, format::oiyx}, + {{1, 0, 2, 3}, {}, true, false, false, false, false, format::ioyx}, + {{1, 2, 3, 0}, {}, true, false, false, false, false, format::iyxo}, + {{0, 2, 3, 1}, {}, true, false, false, false, false, format::oyxi}, + {{0, 2, 1, 3}, {}, true, false, false, false, false, format::oyix}, + {{0, 3, 1, 2}, {}, true, false, false, false, false, format::oxiy}, + {{2, 3, 1, 0}, {}, true, false, false, false, false, format::yxio}, + {{0, 1, 2, 3}, {{0, 16}}, true, false, false, false, false, format::os_iyx_osv16}, + {{0, 1, 2, 3}, {}, true, false, false, true, false, format::winograd_2x3_s1_weights}, + {{0, 1, 3, 2}, {}, true, false, false, false, false, format::lstm_weights_dio}, + {{0, 1, 2, 3}, {{1, 8}, {0, 8}, {1, 4}}, true, false, false, false, false, format::os_is_yx_isa8_osv8_isv4}, + {{0, 1, 2, 3, 4}, {}, true, true, false, false, false, format::goiyx}, + {{0, 2, 1, 3, 4}, {{1, 16}, {0, 16}}, true, true, false, false, false, format::g_is_os_yx_isv16_osv16}, + + // Expected error throw + {{0, 0, 2, 3}, {}, false, false, false, false, false, format::any}, + {{0, 1, 2, 3}, {{1, 1}}, false, false, false, false, false, format::any}, + {{0, 1, 2, 3}, {}, false, true, false, false, false, format::any} + }), + find_format_test::PrintToString); diff --git a/src/plugins/intel_gpu/tests/unit/passes/prepare_primitive_fusing_test.cpp b/src/plugins/intel_gpu/tests/unit/passes/prepare_primitive_fusing_test.cpp index 448dce28a28703..8f2c2cab50236f 100644 --- a/src/plugins/intel_gpu/tests/unit/passes/prepare_primitive_fusing_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/passes/prepare_primitive_fusing_test.cpp @@ -517,3 +517,79 @@ TEST(prepare_primitive_fusing, eltwise_fusing_residual_connection) { net.execute(); ASSERT_TRUE(conv_inst->has_unfused_subgraph()); } + +TEST(prepare_primitive_fusing, fuse_constant_transposes_removal_check) { + auto& engine = get_test_engine(); + + auto input = engine.allocate_memory({ { 2, 32 }, data_types::f16, format::bfyx }); + auto weights = engine.allocate_memory({{ 32, 2 }, data_types::f32, format::bfyx }); + + topology topology( + input_layout("input", input->get_layout()), + data("weights", weights), + permute("permute", input_info("weights"), {1, 0}), + reorder("reorder_dt", input_info("permute"), format::bfyx, data_types::f16), + fully_connected("fc", input_info("input"), { "reorder_dt" }, "", data_types::f16) + ); + + ExecutionConfig config = get_test_default_config(engine); + config.set_property(ov::intel_gpu::optimize_data(true)); + config.set_property(ov::intel_gpu::allow_new_shape_infer(true)); + + auto prog = program::build_program(engine, topology, config, false, true); + + layout_optimizer lo(true); + program_wrapper::apply_opt_pass(*prog, lo); + + ASSERT_TRUE(!has_node(*prog, "permute")); + ASSERT_EQ(prog->get_node("weights").get_output_layout().format, format::fbyx); +} + +TEST(prepare_primitive_fusing, fuse_constant_transposes_accuracy_test) { + auto& engine = get_test_engine(); + + auto input = engine.allocate_memory({ { 2, 32 }, data_types::f16, format::bfyx }); + auto weights = engine.allocate_memory({{ 32, 2 }, data_types::f32, format::bfyx }); + + tests::random_generator rg(GET_SUITE_NAME); + auto input_data = rg.generate_random_2d(2, 32, -1, 1); + auto weights_data = rg.generate_random_2d(32, 2, -1, 1); + + set_values(input, flatten_2d(format::bfyx, input_data)); + set_values(weights, flatten_2d(format::bfyx, weights_data)); + + topology topology( + input_layout("input", input->get_layout()), + data("weights", weights), + reorder("reorder_dt", input_info("weights"), format::bfyx, data_types::f16, + std::vector(), reorder_mean_mode::subtract, padding(), true), + permute("permute", input_info("reorder_dt"), {1, 0}), + fully_connected("fc", input_info("input"), { "permute" }, "", data_types::f16) + ); + + ExecutionConfig config = get_test_default_config(engine); + config.set_property(ov::intel_gpu::optimize_data(true)); + config.set_property(ov::intel_gpu::allow_new_shape_infer(true)); + + cldnn::network network(engine, topology, config); + network.set_input_data("input", input); + + auto outputs = network.execute(); + auto output = outputs.at("fc").get_memory(); + cldnn::mem_lock output_ptr(output, get_test_stream()); + + ExecutionConfig config_ref = get_test_default_config(engine); + config_ref.set_property(ov::intel_gpu::optimize_data(false)); + config_ref.set_property(ov::intel_gpu::allow_new_shape_infer(true)); + + cldnn::network network_ref(engine, topology, config_ref); + network_ref.set_input_data("input", input); + + auto outputs_ref = network_ref.execute(); + auto output_ref = outputs_ref.at("fc").get_memory(); + cldnn::mem_lock output_ptr_ref(output_ref, get_test_stream()); + + for (size_t i = 0; i < output_ptr_ref.size(); ++i) { + ASSERT_EQ(output_ptr[i], output_ptr_ref[i]); + } +} diff --git a/src/plugins/intel_gpu/tests/unit/passes/reorder_transfer.cpp b/src/plugins/intel_gpu/tests/unit/passes/reorder_transfer.cpp new file mode 100644 index 00000000000000..7731da37ef1e1e --- /dev/null +++ b/src/plugins/intel_gpu/tests/unit/passes/reorder_transfer.cpp @@ -0,0 +1,48 @@ +// Copyright (C) 2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "test_utils.h" +#include "program_wrapper.h" +#include "fully_connected_inst.h" +#include "permute_inst.h" + +using namespace cldnn; +using namespace ::tests; + +TEST(reorder_transfer, transfer_per_permute) { + auto& engine = get_test_engine(); + + auto input = engine.allocate_memory({ { 2, 32 }, data_types::f16, format::bfyx }); + auto weights = engine.allocate_memory({{ 32, 2 }, data_types::f32, format::bfyx }); + + topology topology( + input_layout("input", input->get_layout()), + data("weights", weights), + reorder("reorder_dt", input_info("weights"), format::bfyx, data_types::f16, + std::vector(), reorder_mean_mode::subtract, padding(), true), + permute("permute", input_info("reorder_dt"), {1, 0}), + fully_connected("fc", input_info("input"), { "permute" }, "", data_types::f16) + ); + + ExecutionConfig config = get_test_default_config(engine); + config.set_property(ov::intel_gpu::optimize_data(true)); + config.set_property(ov::intel_gpu::allow_new_shape_infer(true)); + auto prog = program::build_program(engine, topology, config, false, true); + + for (auto& node : prog->get_processing_order()) { + if (!node->is_type()) + node->get_output_layouts(); + } + + program_wrapper::apply_opt_pass(*prog); + auto& processing_order = prog->get_processing_order(); + + auto reorder_node = std::find(processing_order.begin(), processing_order.end(), &prog->get_node("reorder_dt")); + size_t reorder_dist = std::distance(processing_order.begin(), reorder_node); + + auto permute_node = std::find(processing_order.begin(), processing_order.end(), &prog->get_node("permute")); + size_t permute_dist = std::distance(processing_order.begin(), permute_node); + + ASSERT_TRUE(reorder_dist > permute_dist); +} diff --git a/src/plugins/intel_gpu/tests/unit/test_cases/hash_key_gpu_test.cpp b/src/plugins/intel_gpu/tests/unit/test_cases/hash_key_gpu_test.cpp index a40469eb8a8cc8..367277fa0e061b 100644 --- a/src/plugins/intel_gpu/tests/unit/test_cases/hash_key_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/test_cases/hash_key_gpu_test.cpp @@ -176,7 +176,7 @@ class check_hash_value: public ::testing::Test { const auto params_hash = prim_inst->get_impl_params()->hash(); ASSERT_EQ(primitive_hash, 16293979194373117693UL); - ASSERT_EQ(params_hash, 4771142562684430881UL); + ASSERT_EQ(params_hash, 550629972043680951UL); } void test_reshape_basic(bool is_caching_test) { diff --git a/src/plugins/intel_gpu/tests/unit/test_cases/strided_slice_gpu_test.cpp b/src/plugins/intel_gpu/tests/unit/test_cases/strided_slice_gpu_test.cpp index 71e193b47abde1..7a0280380b766c 100644 --- a/src/plugins/intel_gpu/tests/unit/test_cases/strided_slice_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/unit/test_cases/strided_slice_gpu_test.cpp @@ -118,6 +118,120 @@ class strided_slice_gpu: public ::testing::Test { } } + void test_2x2x2x2x2_full(bool is_caching_test) { + // Input (BFZYX): 2x2x2x2x2 + // Begin (BFZYX): 0x0x0x0x0 + // End (BFZYX): 2x2x2x2x2 + // Stride (BFZYX): 1x1x1x1x1 + // Output (BFZYX): 2x2x2x2x2 + + auto& engine = get_test_engine(); + auto input = engine.allocate_memory({ ov::PartialShape{ 2, 2, 2, 2, 2 }, data_types::f32, format::bfzyx }); + + set_values(input, { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, + 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, + }); + std::vector begin_data = { 0, 0, 0, 0, 0 }; + std::vector end_data = { 2, 2, 2, 2, 2 }; + std::vector strides_data = { 1, 1, 1, 1, 1 }; + + topology topology; + topology.add(input_layout("input", input->get_layout())); + topology.add(strided_slice("strided_slice", input_info("input"), begin_data, end_data, strides_data, {}, {}, {}, {}, {}, {2, 2, 2, 2, 2})); + + cldnn::network::ptr network = get_network(engine, topology, get_test_default_config(engine), get_test_stream_ptr(), is_caching_test); + + network->set_input_data("input", input); + + auto outputs = network->execute(); + + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "strided_slice"); + + auto output = outputs.at("strided_slice").get_memory(); + + std::vector answers = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, + 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, + }; + + cldnn::mem_lock output_ptr(output, get_test_stream()); + + ASSERT_EQ(output_ptr.size(), answers.size()); + for (size_t i = 0; i < answers.size(); ++i) + { + ASSERT_TRUE(are_equal(answers[i], output_ptr[i])); + } + } + + + void test_2x2x2x2x2x2_full(bool is_caching_test) { + // Input (BFWZYX): 2x2x2x2x2x2 + // Begin (BFWZYX): 0x0x0x0x0x0 + // End (BFWZYX): 2x2x2x2x2x2 + // Stride (BFWZYX): 1x1x1x1x1x1 + // Output (BFWZYX): 2x2x2x2x2x2 + + auto& engine = get_test_engine(); + auto input = engine.allocate_memory({ ov::PartialShape{ 2, 2, 2, 2, 2, 2 }, data_types::f32, format::bfwzyx }); + + set_values(input, { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, + 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, + 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, + 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, + 48.0f, 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, + 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, 63.0f, + }); + std::vector begin_data = { 0, 0, 0, 0, 0, 0 }; + std::vector end_data = { 2, 2, 2, 2, 2, 2 }; + std::vector strides_data = { 1, 1, 1, 1, 1, 1 }; + + topology topology; + topology.add(input_layout("input", input->get_layout())); + topology.add(strided_slice("strided_slice", input_info("input"), begin_data, end_data, strides_data, {}, {}, {}, {}, {}, {2, 2, 2, 2, 2, 2})); + + auto config = get_test_default_config(engine); + config.set_property(ov::intel_gpu::force_implementations(ov::intel_gpu::ImplForcingMap{ {"strided_slice", {format::bfwzyx, "", impl_types::ocl}} })); + + cldnn::network::ptr network = get_network(engine, topology, config, get_test_stream_ptr(), is_caching_test); + + network->set_input_data("input", input); + + auto outputs = network->execute(); + + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "strided_slice"); + + auto output = outputs.at("strided_slice").get_memory(); + + std::vector answers = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, + 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, + 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, + 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, + 48.0f, 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, + 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, 63.0f, + }; + + cldnn::mem_lock output_ptr(output, get_test_stream()); + + ASSERT_EQ(output_ptr.size(), answers.size()); + for (size_t i = 0; i < answers.size(); ++i) + { + ASSERT_TRUE(are_equal(answers[i], output_ptr[i])); + } + } + void test_2x2x2x2_full_pad(bool is_caching_test) { // Input (BFYX): 2x2x2x2 // Begin (BFYX): 0x0x0x0 @@ -601,6 +715,94 @@ class strided_slice_gpu: public ::testing::Test { } } + void test_2x2x2x2x1x1(bool is_caching_test) { + // Input (BFWZYX): 2x2x2x2x1x1 + // Output (BFWZYX): 1x2x2x2x1x1 + + auto& engine = get_test_engine(); + auto input = engine.allocate_memory({ data_types::f32, format::bfwzyx, { 2, 2, 1, 1, 2, 2 }}); + + set_values(input, { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, + 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + }); + std::vector begin_data = { 0, 0, 0, 0, 0, 0 }; + std::vector end_data = { 1, 2, 2, 2, 1, 1 }; + std::vector strides_data = { 1, 1, 1, 1, 1, 1 }; + + topology topology; + topology.add(input_layout("input", input->get_layout())); + topology.add(strided_slice("strided_slice", input_info("input"), begin_data, end_data, strides_data, {}, {}, {}, {}, {}, {1, 2, 2, 2, 1, 1})); + + cldnn::network::ptr network = get_network(engine, topology, get_test_default_config(engine), get_test_stream_ptr(), is_caching_test); + + network->set_input_data("input", input); + + auto outputs = network->execute(); + + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "strided_slice"); + + auto output = outputs.at("strided_slice").get_memory(); + + std::vector answers = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, + }; + + cldnn::mem_lock output_ptr(output, get_test_stream()); + + for (size_t i = 0; i < answers.size(); ++i) + { + ASSERT_TRUE(are_equal(answers[i], output_ptr[i])); + } + } + + void test_2x2x2x2x1x1_2(bool is_caching_test, impl_types impl_type = impl_types::any) { + // Input (BFWZYX): 2x2x2x2x1x1 + // Output (BFWZYX): 2x1x1x1x1x1 + + auto& engine = get_test_engine(); + auto input = engine.allocate_memory({ data_types::f32, format::bfwzyx, { 2, 2, 1, 1, 2, 2 } }); + + set_values(input, { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, + 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, + }); + std::vector begin_data = { 0, 0, 0, 0 }; + std::vector end_data = { 2, 2, 2, 2 }; + std::vector strides_data = { 1, 2, 2, 2 }; + + topology topology; + topology.add(input_layout("input", input->get_layout())); + topology.add(strided_slice("strided_slice", input_info("input"), begin_data, end_data, strides_data, {}, {}, {}, {}, {}, {2, 1, 1, 1, 1})); + + auto config = get_test_default_config(engine); + if (impl_type != impl_types::any) + config.set_property(ov::intel_gpu::force_implementations(ov::intel_gpu::ImplForcingMap{ {"strided_slice", {format::bfwzyx, "", impl_types::cpu}} })); + + cldnn::network::ptr network = get_network(engine, topology, config, get_test_stream_ptr(), is_caching_test); + + network->set_input_data("input", input); + + auto outputs = network->execute(); + + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "strided_slice"); + + auto output = outputs.at("strided_slice").get_memory(); + + std::vector answers = { + 0.0f, 8.0f, + }; + + cldnn::mem_lock output_ptr(output, get_test_stream()); + + for (size_t i = 0; i < answers.size(); ++i) + { + ASSERT_TRUE(are_equal(answers[i], output_ptr[i])); + } + } + void test_2x2x2x2_full_negative_stride(bool is_caching_test) { // Input (BFYX): 2x2x2x2 // Begin (BFYX): 0x0x0x0 @@ -1933,6 +2135,47 @@ class strided_slice_gpu_i8: public ::testing::Test { ASSERT_TRUE(are_equal(answers[i], output_ptr[i])); } } + + void test_2x2x2x2x1x1(bool is_caching_test) { + // Input (BFWZYX): 2x2x2x2x1x1 + // Output (BFWZYX): 1x2x2x2x1x1 + + auto& engine = get_test_engine(); + auto input = engine.allocate_memory({ data_types::i8, format::bfwzyx, { 2, 2, 1, 1, 2, 2 } }); + + set_values(input, { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + }); + std::vector begin_data = { 0, 0, 0 }; + std::vector end_data = { 1, 2, 2 }; + std::vector strides_data = { 1, 1, 1 }; + + topology topology; + topology.add(input_layout("input", input->get_layout())); + topology.add(strided_slice("strided_slice", input_info("input"), begin_data, end_data, strides_data, {}, {}, {}, {}, {}, {1, 2, 2, 2, 1, 1})); + + cldnn::network::ptr network = get_network(engine, topology, get_test_default_config(engine), get_test_stream_ptr(), is_caching_test); + + network->set_input_data("input", input); + + auto outputs = network->execute(); + + ASSERT_EQ(outputs.size(), size_t(1)); + ASSERT_EQ(outputs.begin()->first, "strided_slice"); + + auto output = outputs.at("strided_slice").get_memory(); + + std::vector answers = { + 0, 1, 2, 3, 4, 5, 6, 7, + }; + + cldnn::mem_lock output_ptr(output, get_test_stream()); + + for (size_t i = 0; i < answers.size(); ++i) { + ASSERT_TRUE(are_equal(answers[i], output_ptr[i])); + } + } }; class strided_slice_gpu_f32_i32: public ::testing::Test { @@ -1999,6 +2242,14 @@ TEST_F(strided_slice_gpu_constants, test_2x2x2x2_full) { this->test_2x2x2x2_full(false); } +TEST_F(strided_slice_gpu, test_2x2x2x2x2_full) { + this->test_2x2x2x2x2_full(false); +} + +TEST_F(strided_slice_gpu, test_2x2x2x2x2x2_full) { + this->test_2x2x2x2x2x2_full(false); +} + TEST_F(strided_slice_gpu, test_2x2x2x2_full_pad) { this->test_2x2x2x2_full_pad(false); } @@ -2087,6 +2338,18 @@ TEST_F(strided_slice_gpu_constants, test_2x2x2x1x1_2) { this->test_2x2x2x1x1_2(false); } +TEST_F(strided_slice_gpu, test_2x2x2x2x1x1) { + this->test_2x2x2x2x1x1(false); +} + +TEST_F(strided_slice_gpu, test_2x2x2x2x1x1_2) { + this->test_2x2x2x2x1x1_2(false); +} + +TEST_F(strided_slice_gpu_i8, test_2x2x2x2x1x1) { + this->test_2x2x2x2x1x1(false); +} + TEST_F(strided_slice_gpu_f32_i32, test_1x1x1x8x1_new_axis_5d) { this->test_1x1x1x8x1_new_axis_5d(false); } 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 5266e27dc932f0..dcc1e256c7ef00 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 @@ -118,6 +118,27 @@ using VVVVVF = std::vector>; // split of bfyx filters template using VVVVVVF = std::vector>; // split of bfyx filters +template +inline VF flatten_2d(cldnn::format input_format, VVF &data) { + size_t a = data.size(); + size_t b = data[0].size(); + + VF vec(a * b, (T)(0.0f)); + size_t idx = 0; + + switch (input_format.value) { + case cldnn::format::bfyx: + for (size_t bi = 0; bi < a; ++bi) + for (size_t fi = 0; fi < b; ++fi) + vec[idx++] = data[bi][fi]; + break; + + default: + assert(0); + } + return vec; +} + template inline VF flatten_4d(cldnn::format input_format, VVVVF &data) { size_t a = data.size(); diff --git a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_query_model.hpp b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_query_model.hpp deleted file mode 100644 index 33b076c73621dd..00000000000000 --- a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_query_model.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "functional_test_utils/crash_handler.hpp" -#include "op_impl_check/op_impl_check.hpp" - -namespace ov { -namespace test { -namespace subgraph { - -TEST_P(OpImplCheckTest, checkPluginImplementationQueryModel) { - if (function == nullptr) { - GTEST_FAIL() << "Target model is empty!"; - } - - // in case of crash jump will be made and work will be continued - ov::test::utils::CrashHandler crashHandler; - - // place to jump in case of a crash - int jmpRes = 0; -#ifdef _WIN32 - jmpRes = setjmp(ov::test::utils::env); -#else - jmpRes = sigsetjmp(ov::test::utils::env, 1); -#endif - if (jmpRes == ov::test::utils::JMP_STATUS::ok) { - crashHandler.StartTimer(); - summary.setDeviceName(targetDevice); - try { - auto queryNetworkResult = core->query_model(function, targetDevice); - std::set expected; - for (auto &&node : function->get_ops()) { - expected.insert(node->get_friendly_name()); - } - - std::set actual; - for (auto &&res : queryNetworkResult) { - actual.insert(res.first); - } - - if (expected != actual) { - throw std::runtime_error("Expected and actual results are different"); - } - summary.updateOPsImplStatus(function, true); - } catch (const std::exception &e) { - summary.updateOPsImplStatus(function, false); - GTEST_FAIL() << "Exception in the Core::compile_model() method call: " << e.what(); - } catch (...) { - summary.updateOPsImplStatus(function, false); - GTEST_FAIL() << "Error in the Core::query_model() method call!"; - } - } else if (jmpRes == ov::test::utils::JMP_STATUS::anyError) { - summary.updateOPsImplStatus(function, false); - GTEST_FAIL() << "Crash happens"; - } else if (jmpRes == ov::test::utils::JMP_STATUS::alarmErr) { - summary.updateOPsImplStatus(function, false); - GTEST_FAIL() << "Hang happens"; - } -} - -} // namespace subgraph -} //namespace test -} // namespace ov diff --git a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_compile_model.hpp b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_test.hpp similarity index 65% rename from src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_compile_model.hpp rename to src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_test.hpp index 99df2dff9cf1be..6e74aaec926f70 100644 --- a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_compile_model.hpp +++ b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/include/op_impl_check/op_impl_check_test.hpp @@ -9,14 +9,14 @@ namespace ov { namespace test { namespace subgraph { -TEST_P(OpImplCheckTest, checkPluginImplementationCompileModel) { +TEST_P(OpImplCheckTest, checkPluginImplementation) { if (function == nullptr) { GTEST_FAIL() << "Target model is empty!"; } + summary.updateOPsImplStatus(function, false); // in case of crash jump will be made and work will be continued ov::test::utils::CrashHandler crashHandler; - // place to jump in case of a crash int jmpRes = 0; #ifdef _WIN32 @@ -28,20 +28,30 @@ TEST_P(OpImplCheckTest, checkPluginImplementationCompileModel) { crashHandler.StartTimer(); summary.setDeviceName(targetDevice); try { - auto executableNetwork = core->compile_model(function, targetDevice, configuration); - summary.updateOPsImplStatus(function, true); + auto queryNetworkResult = core->query_model(function, targetDevice); + { + std::set expected; + for (auto &&node : function->get_ops()) { + expected.insert(node->get_friendly_name()); + } + + std::set actual; + for (auto &&res : queryNetworkResult) { + actual.insert(res.first); + } + + if (expected == actual) { + summary.updateOPsImplStatus(function, true); + } + } } catch (const std::exception &e) { - summary.updateOPsImplStatus(function, false); GTEST_FAIL() << "Exception in the Core::compile_model() method call: " << e.what(); } catch (...) { - summary.updateOPsImplStatus(function, false); GTEST_FAIL() << "Error in the Core::compile_model() method call!"; } } else if (jmpRes == ov::test::utils::JMP_STATUS::anyError) { - summary.updateOPsImplStatus(function, false); GTEST_FAIL() << "Crash happens"; } else if (jmpRes == ov::test::utils::JMP_STATUS::alarmErr) { - summary.updateOPsImplStatus(function, false); GTEST_FAIL() << "Hang happens"; } } diff --git a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check_tests.cpp b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check_tests.cpp index d3dec08c552167..a135903d434373 100644 --- a/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check_tests.cpp +++ b/src/tests/functional/plugin/conformance/test_runner/op_conformance_runner/src/op_impl_check/op_impl_check_tests.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "op_impl_check/op_impl_check_compile_model.hpp" -#include "op_impl_check/op_impl_check_query_model.hpp" +#include "op_impl_check/op_impl_check_test.hpp" #include "op_impl_check/single_op_graph.hpp" #include "conformance.hpp" diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/grn.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/grn.hpp new file mode 100644 index 00000000000000..10c01bd61ff504 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/grn.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/grn.hpp" + +namespace ov { +namespace test { +TEST_P(GrnLayerTest, Inference) { + run(); +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/group_convolution.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/group_convolution.hpp new file mode 100644 index 00000000000000..7fbbad5a80a7d0 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/group_convolution.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/group_convolution.hpp" + +namespace ov { +namespace test { +TEST_P(GroupConvolutionLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/group_convolution_backprop_data.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/group_convolution_backprop_data.hpp new file mode 100644 index 00000000000000..c9967776bb8f75 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/group_convolution_backprop_data.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/group_convolution_backprop_data.hpp" + +namespace ov { +namespace test { +TEST_P(GroupConvBackpropLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/gru_cell.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/gru_cell.hpp new file mode 100644 index 00000000000000..7ef4391ec29f98 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/gru_cell.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/gru_cell.hpp" + +namespace ov { +namespace test { +TEST_P(GRUCellTest, Inference) { + run(); +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/roll.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/roll.hpp new file mode 100644 index 00000000000000..3e1f1cc9ff3393 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/roll.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/roll.hpp" + +namespace ov { +namespace test { +TEST_P(RollLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/scatter_ND_update.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/scatter_ND_update.hpp new file mode 100644 index 00000000000000..ddcb9cedd87b47 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/scatter_ND_update.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/scatter_ND_update.hpp" + +namespace ov { +namespace test { +TEST_P(ScatterNDUpdateLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/scatter_elements_update.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/scatter_elements_update.hpp new file mode 100644 index 00000000000000..66e7badad7f0b9 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/scatter_elements_update.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/scatter_elements_update.hpp" + +namespace ov { +namespace test { +TEST_P(ScatterElementsUpdateLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/scatter_update.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/scatter_update.hpp new file mode 100644 index 00000000000000..10d72df004ecd6 --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/scatter_update.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/scatter_update.hpp" + +namespace ov { +namespace test { +TEST_P(ScatterUpdateLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/plugin/shared/include/single_op_tests/select.hpp b/src/tests/functional/plugin/shared/include/single_op_tests/select.hpp new file mode 100644 index 00000000000000..758b216a7acfec --- /dev/null +++ b/src/tests/functional/plugin/shared/include/single_op_tests/select.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_op/select.hpp" + +namespace ov { +namespace test { +TEST_P(SelectLayerTest, Inference) { + run(); +} +} // namespace test +} // namespace ov \ No newline at end of file diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/grn.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/grn.hpp new file mode 100644 index 00000000000000..2aaec42dbcdff7 --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/grn.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +typedef std::tuple< + ov::element::Type, // Model type + std::vector, // Input shapes + float, // Bias + std::string // Device name +> grnParams; + +class GrnLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest{ +public: + static std::string getTestCaseName(const testing::TestParamInfo& obj); +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/group_convolution.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/group_convolution.hpp new file mode 100644 index 00000000000000..9353d281cd647f --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/group_convolution.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +typedef std::tuple< + std::vector, + std::vector, + std::vector, + std::vector, + std::vector, + size_t, + size_t, + ov::op::PadType> groupConvSpecificParams; +typedef std::tuple< + groupConvSpecificParams, + ov::element::Type, + std::vector, + std::string> groupConvLayerTestParamsSet; + +class GroupConvolutionLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo& obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/group_convolution_backprop_data.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/group_convolution_backprop_data.hpp new file mode 100644 index 00000000000000..61543976040b2e --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/group_convolution_backprop_data.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +using groupConvBackpropSpecificParams = std::tuple< + std::vector, // kernels + std::vector, // strides + std::vector, // pad begins + std::vector, // pad ends + std::vector, // dilations + size_t, // num output channels + size_t, // num groups + ov::op::PadType, // padding type + std::vector>; // output padding + +using groupConvBackpropLayerTestParamsSet = std::tuple< + groupConvBackpropSpecificParams, + ov::element::Type, // Model type + std::vector, // Input shape + ov::Shape, // Output shapes + std::string>; // Device name + +class GroupConvBackpropLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/gru_cell.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/gru_cell.hpp new file mode 100644 index 00000000000000..4cedfd0918bf2b --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/gru_cell.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" +#include "common_test_utils/test_enums.hpp" + +namespace ov { +namespace test { +using GRUCellParams = typename std::tuple< + bool, // using decompose to sub-ops transformation + size_t, // batch + size_t, // hidden size + size_t, // input size + std::vector, // activations + float, // clip + bool, // linear_before_reset + ov::test::utils::InputLayerType, // W input type (Constant or Parameter) + ov::test::utils::InputLayerType, // R input type (Constant or Parameter) + ov::test::utils::InputLayerType, // B input type (Constant or Parameter) + ov::element::Type, // Model type + std::string>; // Device name + +class GRUCellTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/roll.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/roll.hpp new file mode 100644 index 00000000000000..c43c48ad471784 --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/roll.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +typedef std::tuple< + std::vector, // Input shapes + ov::element::Type, // Model type + std::vector, // Shift + std::vector, // Axes + ov::test::TargetDevice // Device name +> rollParams; + +class RollLayerTest : public testing::WithParamInterface, virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo& obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_ND_update.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_ND_update.hpp new file mode 100644 index 00000000000000..6089e792b82989 --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_ND_update.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +using scatterNDUpdateSpecParams = std::tuple< + std::vector, // input, update shapes + ov::Shape, // indices shape + std::vector // indices value +>; + +using scatterNDUpdateParamsTuple = typename std::tuple< + scatterNDUpdateSpecParams, + ov::element::Type, // Model type + ov::element::Type, // Indices type + ov::test::TargetDevice // Device name +>; + +class ScatterNDUpdateLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_elements_update.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_elements_update.hpp new file mode 100644 index 00000000000000..0a7ebea7a20809 --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_elements_update.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +using axisShapeInShape = std::tuple< + std::vector, // Input, update/indices shapes + int // Axis +>; +using scatterElementsUpdateParamsTuple = typename std::tuple< + axisShapeInShape, // Shape description + std::vector, // Indices value + ov::element::Type, // Model type + ov::element::Type, // Indices type + ov::test::TargetDevice // Device name +>; + +class ScatterElementsUpdateLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_update.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_update.hpp new file mode 100644 index 00000000000000..901640b2c22f01 --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/scatter_update.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +using axisUpdateShapeInShape = std::tuple< + std::vector, // input, update shapes + ov::Shape, // indices shape + int64_t>; // axis +using scatterUpdateParamsTuple = typename std::tuple< + axisUpdateShapeInShape, + std::vector, // Indices value + ov::element::Type, // Model type + ov::element::Type, // Indices type + ov::test::TargetDevice // Device name +>; + +class ScatterUpdateLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/select.hpp b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/select.hpp new file mode 100644 index 00000000000000..1281f19d26e9ea --- /dev/null +++ b/src/tests/functional/shared_test_classes/include/shared_test_classes/single_op/select.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +#include "shared_test_classes/base/ov_subgraph.hpp" + +namespace ov { +namespace test { +typedef std::tuple< + std::vector, // mask, then, else shapes + ov::element::Type, // then, else types + ov::op::AutoBroadcastSpec, // broadcast + ov::test::TargetDevice // Device name +> selectTestParams; + +class SelectLayerTest : public testing::WithParamInterface, + virtual public ov::test::SubgraphBaseTest { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + +protected: + void SetUp() override; +}; +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/grn.cpp b/src/tests/functional/shared_test_classes/src/single_op/grn.cpp new file mode 100644 index 00000000000000..41b5ea03cea0bf --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/grn.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/grn.hpp" + +#include "openvino/op/parameter.hpp" +#include "openvino/op/result.hpp" +#include "openvino/op/grn.hpp" + +namespace ov { +namespace test { +std::string GrnLayerTest::getTestCaseName(const testing::TestParamInfo& obj) { + ov::element::Type model_type; + std::vector shapes; + std::string target_device; + float bias; + std::tie(model_type, shapes, bias, target_device) = obj.param; + + std::ostringstream result; + result << "IS=("; + for (size_t i = 0lu; i < shapes.size(); i++) { + result << ov::test::utils::partialShape2str({shapes[i].first}) << (i < shapes.size() - 1lu ? "_" : ""); + } + result << ")_TS="; + for (size_t i = 0lu; i < shapes.front().second.size(); i++) { + result << "{"; + for (size_t j = 0lu; j < shapes.size(); j++) { + result << ov::test::utils::vec2str(shapes[j].second[i]) << (j < shapes.size() - 1lu ? "_" : ""); + } + result << "}_"; + } + result << "modelType=" << model_type.get_type_name() << '_'; + result << "bias=" << bias << '_'; + result << "trgDev=" << '_'; + return result.str(); +} + +void GrnLayerTest::SetUp() { + ov::element::Type model_type; + std::vector shapes; + float bias; + std::tie(model_type, shapes, bias, targetDevice) = GetParam(); + init_input_shapes(shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.front()); + auto grn = std::make_shared(param, bias); + auto result = std::make_shared(grn); + function = std::make_shared(result, ov::ParameterVector{param}, "Grn"); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/group_convolution.cpp b/src/tests/functional/shared_test_classes/src/single_op/group_convolution.cpp new file mode 100644 index 00000000000000..f3efcbb2055845 --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/group_convolution.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/group_convolution.hpp" + +#include "ngraph_functions/builders.hpp" +#include "openvino/op/parameter.hpp" +#include "openvino/op/result.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/group_conv.hpp" + +namespace ov { +namespace test { +std::string GroupConvolutionLayerTest::getTestCaseName(const testing::TestParamInfo& obj) { + groupConvSpecificParams group_conv_params; + ov::element::Type model_type; + std::vector shapes; + std::string target_device; + std::tie(group_conv_params, model_type, shapes, target_device) = obj.param; + ov::op::PadType pad_type; + std::vector kernel, stride, dilation; + std::vector pad_begin, pad_end; + size_t conv_out_channels, num_groups; + std::tie(kernel, stride, pad_begin, pad_end, dilation, conv_out_channels, num_groups, pad_type) = group_conv_params; + + std::ostringstream result; + result << "IS=("; + for (size_t i = 0lu; i < shapes.size(); i++) { + result << ov::test::utils::partialShape2str({shapes[i].first}) << (i < shapes.size() - 1lu ? "_" : ""); + } + result << ")_TS="; + for (size_t i = 0lu; i < shapes.front().second.size(); i++) { + result << "{"; + for (size_t j = 0lu; j < shapes.size(); j++) { + result << ov::test::utils::vec2str(shapes[j].second[i]) << (j < shapes.size() - 1lu ? "_" : ""); + } + result << "}_"; + } + result << "K=" << ov::test::utils::vec2str(kernel) << "_"; + result << "S=" << ov::test::utils::vec2str(stride) << "_"; + result << "PB=" << ov::test::utils::vec2str(pad_begin) << "_"; + result << "PE=" << ov::test::utils::vec2str(pad_end) << "_"; + result << "D=" << ov::test::utils::vec2str(dilation) << "_"; + result << "O=" << conv_out_channels << "_"; + result << "G=" << num_groups << "_"; + result << "AP=" << pad_type << "_"; + result << "modelType=" << model_type.get_type_name() << "_"; + result << "trgDev=" << target_device; + return result.str(); +} + +void GroupConvolutionLayerTest::SetUp() { + groupConvSpecificParams group_conv_params; + ov::element::Type model_type; + std::vector shapes; + std::tie(group_conv_params, model_type, shapes, targetDevice) = this->GetParam(); + ov::op::PadType pad_type; + std::vector kernel, stride, dilation; + std::vector pad_begin, pad_end; + size_t conv_out_channels, num_groups; + std::tie(kernel, stride, pad_begin, pad_end, dilation, conv_out_channels, num_groups, pad_type) = group_conv_params; + init_input_shapes(shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.front()); + + auto group_conv = ngraph::builder::makeGroupConvolution(param, model_type, kernel, stride, pad_begin, + pad_end, dilation, pad_type, conv_out_channels, num_groups); + + auto result = std::make_shared(group_conv); + function = std::make_shared(result, ov::ParameterVector{param}, "groupConvolution"); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/group_convolution_backprop_data.cpp b/src/tests/functional/shared_test_classes/src/single_op/group_convolution_backprop_data.cpp new file mode 100644 index 00000000000000..118bfc1ce7f977 --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/group_convolution_backprop_data.cpp @@ -0,0 +1,85 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/group_convolution_backprop_data.hpp" + +#include "ngraph_functions/builders.hpp" +#include "openvino/op/parameter.hpp" +#include "openvino/op/result.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/group_conv.hpp" + +namespace ov { +namespace test { +std::string GroupConvBackpropLayerTest::getTestCaseName(testing::TestParamInfo obj) { + groupConvBackpropSpecificParams group_conv_backprop_data_params; + ov::element::Type model_type; + std::vector shapes; + ov::Shape output_shape; + std::string target_device; + std::tie(group_conv_backprop_data_params, model_type, shapes, output_shape, target_device) = obj.param; + ov::op::PadType pad_type; + std::vector kernel, stride, dilation; + std::vector pad_begin, pad_end, out_padding; + size_t conv_out_channels, num_groups; + std::tie(kernel, stride, pad_begin, pad_end, dilation, conv_out_channels, num_groups, pad_type, out_padding) = group_conv_backprop_data_params; + + std::ostringstream result; + result << "IS=("; + for (size_t i = 0lu; i < shapes.size(); i++) { + result << ov::test::utils::partialShape2str({shapes[i].first}) << (i < shapes.size() - 1lu ? "_" : ""); + } + result << ")_TS="; + for (size_t i = 0lu; i < shapes.front().second.size(); i++) { + result << "{"; + for (size_t j = 0lu; j < shapes.size(); j++) { + result << ov::test::utils::vec2str(shapes[j].second[i]) << (j < shapes.size() - 1lu ? "_" : ""); + } + result << "}_"; + } + result << "OS=" << ov::test::utils::vec2str(output_shape) << "_"; + result << "K" << ov::test::utils::vec2str(kernel) << "_"; + result << "S" << ov::test::utils::vec2str(stride) << "_"; + result << "PB" << ov::test::utils::vec2str(pad_begin) << "_"; + result << "PE" << ov::test::utils::vec2str(pad_end) << "_"; + result << "D=" << ov::test::utils::vec2str(dilation) << "_"; + result << "OP=" << ov::test::utils::vec2str(out_padding) << "_"; + result << "O=" << conv_out_channels << "_"; + result << "G=" << num_groups << "_"; + result << "AP=" << pad_type << "_"; + result << "netPRC=" << model_type.get_type_name() << "_"; + result << "trgDev=" << target_device; + return result.str(); +} + +void GroupConvBackpropLayerTest::SetUp() { + groupConvBackpropSpecificParams group_conv_backprop_data_params; + ov::element::Type model_type; + std::vector shapes; + ov::Shape output_shape; + std::tie(group_conv_backprop_data_params, model_type, shapes, output_shape, targetDevice) = this->GetParam(); + ov::op::PadType pad_type; + std::vector kernel, stride, dilation; + std::vector pad_begin, pad_end, out_padding; + size_t conv_out_channels, num_groups; + std::tie(kernel, stride, pad_begin, pad_end, dilation, conv_out_channels, num_groups, pad_type, out_padding) = group_conv_backprop_data_params; + init_input_shapes(shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.front()); + + std::shared_ptr group_conv; + if (!output_shape.empty()) { + auto outShape = ov::op::v0::Constant::create(ov::element::i64, {output_shape.size()}, output_shape); + group_conv = ngraph::builder::makeGroupConvolutionBackpropData(param, outShape, model_type, kernel, stride, pad_begin, + pad_end, dilation, pad_type, conv_out_channels, num_groups, false, out_padding); + } else { + group_conv = ngraph::builder::makeGroupConvolutionBackpropData(param, model_type, kernel, stride, pad_begin, + pad_end, dilation, pad_type, conv_out_channels, num_groups, false, out_padding); + } + + auto result = std::make_shared(group_conv); + function = std::make_shared(result, ov::ParameterVector{param}, "GroupConvolutionBackpropData"); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/gru_cell.cpp b/src/tests/functional/shared_test_classes/src/single_op/gru_cell.cpp new file mode 100644 index 00000000000000..648a1a6cc27a11 --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/gru_cell.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/gru_cell.hpp" + +#include "common_test_utils/ov_tensor_utils.hpp" +#include "openvino/op/parameter.hpp" +#include "openvino/op/result.hpp" +#include "openvino/op/constant.hpp" +#include "openvino/op/gru_cell.hpp" +#include "openvino/pass/manager.hpp" +#include "transformations/op_conversions/gru_cell_decomposition.hpp" + +namespace ov { +namespace test { +using ov::test::utils::InputLayerType; + +std::string GRUCellTest::getTestCaseName(const testing::TestParamInfo &obj) { + bool should_decompose; + size_t batch; + size_t hidden_size; + size_t input_size; + std::vector activations; + std::vector activations_alpha; + std::vector activations_beta; + float clip; + bool linear_before_reset; + std::vector> input_shapes; + InputLayerType WType; + InputLayerType RType; + InputLayerType BType; + ov::element::Type model_type; + std::string targetDevice; + std::tie(should_decompose, batch, hidden_size, input_size, activations, clip, + linear_before_reset, WType, RType, BType, model_type, targetDevice) = obj.param; + input_shapes = { + {{batch, input_size}, + {batch, hidden_size}, + {3 * hidden_size, input_size}, + {3 * hidden_size, hidden_size}, + {(linear_before_reset? 4 : 3) * hidden_size}}, + }; + std::ostringstream result; + result << "decomposition" << should_decompose << "_"; + result << "batch=" << batch << "_"; + result << "hidden_size=" << hidden_size << "_"; + result << "input_size=" << input_size << "_"; + result << "IS=" << ov::test::utils::vec2str(input_shapes) << "_"; + result << "activations=" << ov::test::utils::vec2str(activations) << "_"; + result << "clip=" << clip << "_"; + result << "linear_before_reset=" << linear_before_reset << "_"; + result << "WType=" << WType << "_"; + result << "RType=" << RType << "_"; + result << "BType=" << BType << "_"; + result << "netPRC=" << model_type.get_type_name() << "_"; + result << "targetDevice=" << targetDevice << "_"; + return result.str(); +} + +void GRUCellTest::SetUp() { + bool should_decompose; + size_t batch; + size_t hidden_size; + size_t input_size; + std::vector activations; + std::vector activations_alpha; + std::vector activations_beta; + float clip; + bool linear_before_reset; + InputLayerType WType; + InputLayerType RType; + InputLayerType BType; + ov::element::Type model_type; + std::tie(should_decompose, batch, hidden_size, input_size, activations, clip, linear_before_reset, + WType, RType, BType, model_type, targetDevice) = this->GetParam(); + + std::vector> input_shapes = { + {{batch, input_size}, + {batch, hidden_size}, + {3 * hidden_size, input_size}, + {3 * hidden_size, hidden_size}, + {(linear_before_reset? 4 : 3) * hidden_size}}, + }; + + std::vector param_shapes{input_shapes[0], input_shapes[1]}; + if (WType == InputLayerType::PARAMETER) + param_shapes.push_back(input_shapes[2]); + + if (RType == InputLayerType::PARAMETER) + param_shapes.push_back(input_shapes[3]); + + if (BType == InputLayerType::PARAMETER) + param_shapes.push_back(input_shapes[4]); + + init_input_shapes(ov::test::static_shapes_to_test_representation(param_shapes)); + + ov::ParameterVector params{std::make_shared(model_type, inputDynamicShapes[0]), + std::make_shared(model_type, inputDynamicShapes[1])}; + + ov::NodeVector inputs{params[0], params[1]}; + if (WType == InputLayerType::PARAMETER) { + auto param = std::make_shared(model_type, inputDynamicShapes[params.size()]); + params.push_back(param); + inputs.push_back(param); + } else { + auto tensor = ov::test::utils::create_and_fill_tensor(model_type, input_shapes[2]); + auto constant = std::make_shared(tensor); + inputs.push_back(constant); + } + + if (RType == InputLayerType::PARAMETER) { + auto param = std::make_shared(model_type, inputDynamicShapes[params.size()]); + params.push_back(param); + inputs.push_back(param); + } else { + auto tensor = ov::test::utils::create_and_fill_tensor(model_type, input_shapes[3]); + auto constant = std::make_shared(tensor); + inputs.push_back(constant); + } + + if (BType == InputLayerType::PARAMETER) { + auto param = std::make_shared(model_type, inputDynamicShapes[params.size()]); + params.push_back(param); + inputs.push_back(param); + } else { + auto tensor = ov::test::utils::create_and_fill_tensor(model_type, input_shapes[4]); + auto constant = std::make_shared(tensor); + inputs.push_back(constant); + } + + auto gru_cell = std::make_shared(inputs[0], inputs[1], inputs[2], inputs[3], inputs[4], + hidden_size, activations, activations_alpha, activations_beta, + clip, linear_before_reset); + + auto result = std::make_shared(gru_cell); + + function = std::make_shared(result, params, "gru_cell"); + if (should_decompose) { + ov::pass::Manager m; + m.register_pass(); + m.run_passes(function); + } +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/roll.cpp b/src/tests/functional/shared_test_classes/src/single_op/roll.cpp new file mode 100644 index 00000000000000..0c6462387b330a --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/roll.cpp @@ -0,0 +1,55 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/roll.hpp" + +namespace ov { +namespace test { +std::string RollLayerTest::getTestCaseName(const testing::TestParamInfo& obj) { + std::vector input_shapes; + ov::element::Type model_type; + std::vector shift; + std::vector axes; + std::string target_device; + std::tie(input_shapes, model_type, shift, axes, target_device) = obj.param; + + std::ostringstream result; + result << "IS=("; + for (size_t i = 0lu; i < input_shapes.size(); i++) { + result << ov::test::utils::partialShape2str({input_shapes[i].first}) + << (i < input_shapes.size() - 1lu ? "_" : ""); + } + result << ")_TS="; + for (size_t i = 0lu; i < input_shapes.front().second.size(); i++) { + result << "{"; + for (size_t j = 0lu; j < input_shapes.size(); j++) { + result << ov::test::utils::vec2str(input_shapes[j].second[i]) << (j < input_shapes.size() - 1lu ? "_" : ""); + } + result << "}_"; + } + result << "modelType=" << model_type.to_string() << "_"; + result << "Shift=" << ov::test::utils::vec2str(shift) << "_"; + result << "Axes=" << ov::test::utils::vec2str(axes) << "_"; + result << "trgDev=" << target_device; + return result.str(); +} + +void RollLayerTest::SetUp() { + std::vector input_shapes; + ov::element::Type model_type; + std::vector shift; + std::vector axes; + std::string target_device; + std::tie(input_shapes, model_type, shift, axes, targetDevice) = this->GetParam(); + + init_input_shapes(input_shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.at(0)); + auto shift_const = std::make_shared(ov::element::i64, ov::Shape{shift.size()}, shift); + auto axes_const = std::make_shared(ov::element::i64, ov::Shape{axes.size()}, axes); + auto roll = std::make_shared(param, shift_const, axes_const); + function = std::make_shared(roll->outputs(), ov::ParameterVector{param}, "Roll"); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/scatter_ND_update.cpp b/src/tests/functional/shared_test_classes/src/single_op/scatter_ND_update.cpp new file mode 100644 index 00000000000000..536807edfb941b --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/scatter_ND_update.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/scatter_ND_update.hpp" + +namespace ov { +namespace test { +std::string ScatterNDUpdateLayerTest::getTestCaseName(const testing::TestParamInfo &obj) { + auto shapes_ss = [](const InputShape& shape) { + std::stringstream ss; + ss << "_IS=(" << ov::test::utils::partialShape2str({shape.first}) << ")_TS="; + for (size_t j = 0lu; j < shape.second.size(); j++) + ss << "{" << ov::test::utils::vec2str(shape.second[j]) << "}"; + return ss; + }; + + scatterNDUpdateSpecParams shapes_desc; + std::vector input_shapes; + ov::Shape indices_shape; + std::vector indices_value; + ov::element::Type model_type, indices_type; + std::string target_device; + std::tie(shapes_desc, model_type, indices_type, target_device) = obj.param; + std::tie(input_shapes, indices_shape, indices_value) = shapes_desc; + + std::ostringstream result; + result << "InputShape=" << shapes_ss(input_shapes.at(0)).str() << "_"; + result << "IndicesShape=" << ov::test::utils::vec2str(indices_shape) << "_"; + result << "IndicesValue=" << ov::test::utils::vec2str(indices_value) << "_"; + result << "UpdateShape=" << shapes_ss(input_shapes.at(1)).str() << "_"; + result << "modelType=" << model_type.to_string() << "_"; + result << "idxType=" << indices_type.to_string() << "_"; + result << "trgDev=" << target_device; + return result.str(); +} + +void ScatterNDUpdateLayerTest::SetUp() { + scatterNDUpdateSpecParams shapes_desc; + std::vector input_shapes; + ov::Shape indices_shape; + std::vector indices_value; + ov::element::Type model_type, indices_type; + std::tie(shapes_desc, model_type, indices_type, targetDevice) = this->GetParam(); + std::tie(input_shapes, indices_shape, indices_value) = shapes_desc; + + init_input_shapes(input_shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.at(0)); + auto update_param = std::make_shared(model_type, inputDynamicShapes.at(1)); + auto indices_const = std::make_shared(indices_type, indices_shape, indices_value); + auto scatter_nd = std::make_shared(param, indices_const, update_param); + function = std::make_shared(scatter_nd->outputs(), ov::ParameterVector{param, update_param}, "ScatterNDUpdate"); +} +} // namespace test +} // namespace ov + diff --git a/src/tests/functional/shared_test_classes/src/single_op/scatter_elements_update.cpp b/src/tests/functional/shared_test_classes/src/single_op/scatter_elements_update.cpp new file mode 100644 index 00000000000000..9a2947820bb35e --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/scatter_elements_update.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/scatter_elements_update.hpp" + +namespace ov { +namespace test { +std::string ScatterElementsUpdateLayerTest::getTestCaseName(const testing::TestParamInfo &obj) { + auto shapes_ss = [](const InputShape& shape) { + std::stringstream ss; + ss << "_IS=(" << ov::test::utils::partialShape2str({shape.first}) << ")_TS="; + for (size_t j = 0lu; j < shape.second.size(); j++) + ss << "{" << ov::test::utils::vec2str(shape.second[j]) << "}"; + return ss; + }; + + axisShapeInShape shapes_desc; + std::vector input_shapes; + int axis; + std::vector indices_value; + ov::element::Type model_type, indices_type; + std::string target_device; + std::tie(shapes_desc, indices_value, model_type, indices_type, target_device) = obj.param; + std::tie(input_shapes, axis) = shapes_desc; + std::ostringstream result; + result << "InputShape=" << shapes_ss(input_shapes.at(0)).str() << "_"; + result << "IndicesShape=" << ov::test::utils::vec2str(input_shapes.at(1).second) << "_"; + result << "Axis=" << axis << "_"; + result << "modelType=" << model_type.to_string() << "_"; + result << "idxType=" << indices_type.to_string() << "_"; + result << "trgDev=" << target_device; + return result.str(); +} + +void ScatterElementsUpdateLayerTest::SetUp() { + axisShapeInShape shapes_desc; + std::vector input_shapes; + int axis; + std::vector indices_value; + ov::element::Type model_type, indices_type; + std::string target_device; + std::tie(shapes_desc, indices_value, model_type, indices_type, targetDevice) = this->GetParam(); + std::tie(input_shapes, axis) = shapes_desc; + + init_input_shapes(input_shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.at(0)); + auto update_param = std::make_shared(model_type, inputDynamicShapes.at(1)); + auto indices_const = std::make_shared(indices_type, targetStaticShapes.at(0).at(1), indices_value); + auto axis_const = + std::make_shared(ov::element::i32, ov::Shape{}, std::vector{axis}); + auto scatter_elements_update = std::make_shared(param, indices_const, update_param, axis_const); + function = std::make_shared(scatter_elements_update->outputs(), ov::ParameterVector{param, update_param}, "ScatterElementsUpdate"); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/scatter_update.cpp b/src/tests/functional/shared_test_classes/src/single_op/scatter_update.cpp new file mode 100644 index 00000000000000..e5442942823e93 --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/scatter_update.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/scatter_update.hpp" + +namespace ov { +namespace test { +std::string ScatterUpdateLayerTest::getTestCaseName(const testing::TestParamInfo &obj) { + auto shapes_ss = [](const InputShape& shape) { + std::stringstream ss; + ss << "_IS=(" << ov::test::utils::partialShape2str({shape.first}) << ")_TS="; + for (size_t j = 0lu; j < shape.second.size(); j++) + ss << "{" << ov::test::utils::vec2str(shape.second[j]) << "}"; + return ss; + }; + + axisUpdateShapeInShape shapes_desc; + std::vector input_shapes; + int64_t axis; + ov::Shape indices_shape; + std::vector indices_value; + ov::element::Type model_type, indices_type; + std::string target_device; + std::tie(shapes_desc, indices_value, model_type, indices_type, target_device) = obj.param; + std::tie(input_shapes, indices_shape, axis) = shapes_desc; + + std::ostringstream result; + result << "InputShape=" << shapes_ss(input_shapes.at(0)).str() << "_"; + result << "IndicesShape=" << ov::test::utils::vec2str(indices_shape) << "_"; + result << "IndicesValue=" << ov::test::utils::vec2str(indices_value) << "_"; + result << "UpdateShape=" << shapes_ss(input_shapes.at(1)).str() << "_"; + result << "Axis=" << axis << "_"; + result << "modelType=" << model_type.to_string() << "_"; + result << "idxType=" << indices_type.to_string() << "_"; + result << "trgDev=" << target_device; + return result.str(); +} + +void ScatterUpdateLayerTest::SetUp() { + axisUpdateShapeInShape shapes_desc; + std::vector input_shapes; + int64_t axis; + ov::Shape indices_shape; + std::vector indices_value; + ov::element::Type model_type, indices_type; + std::tie(shapes_desc, indices_value, model_type, indices_type, targetDevice) = this->GetParam(); + std::tie(input_shapes, indices_shape, axis) = shapes_desc; + + init_input_shapes(input_shapes); + + auto param = std::make_shared(model_type, inputDynamicShapes.at(0)); + auto update_param = std::make_shared(model_type, inputDynamicShapes.at(1)); + auto indices_const = std::make_shared(indices_type, indices_shape, indices_value); + auto axis_const = + std::make_shared(ov::element::i64, ov::Shape{}, std::vector{axis}); + auto scatter = std::make_shared(param, indices_const, update_param, axis_const); + function = std::make_shared(scatter->outputs(), ov::ParameterVector{param, update_param}, "ScatterUpdate"); +} +} // namespace test +} // namespace ov diff --git a/src/tests/functional/shared_test_classes/src/single_op/select.cpp b/src/tests/functional/shared_test_classes/src/single_op/select.cpp new file mode 100644 index 00000000000000..4a56bd2153cdcb --- /dev/null +++ b/src/tests/functional/shared_test_classes/src/single_op/select.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_op/select.hpp" + +namespace ov { +namespace test { +std::string SelectLayerTest::getTestCaseName(const testing::TestParamInfo &obj) { + auto shapes_ss = [](const InputShape& shape) { + std::stringstream ss; + ss << "_IS=(" << ov::test::utils::partialShape2str({shape.first}) << ")_TS="; + for (size_t j = 0lu; j < shape.second.size(); j++) + ss << "{" << ov::test::utils::vec2str(shape.second[j]) << "}"; + return ss; + }; + + std::vector input_shapes; + ov::element::Type model_type; + ov::op::AutoBroadcastSpec broadcast; + std::string target_device; + std::tie(input_shapes, model_type, broadcast, target_device) = obj.param; + std::ostringstream result; + result << "COND=BOOL" << shapes_ss(input_shapes[0]).str() << + "_THEN=" << model_type.to_string() << shapes_ss(input_shapes[1]).str() << + "_ELSE=" << model_type.to_string() << shapes_ss(input_shapes[2]).str(); + result << "_broadcastSpec=" << broadcast.m_type; + result << "_trgDev=" << target_device; + return result.str(); +} + +void SelectLayerTest::SetUp() { + std::vector input_shapes; + ov::element::Type model_type; + ov::op::AutoBroadcastSpec broadcast; + std::tie(input_shapes, model_type, broadcast, targetDevice) = this->GetParam(); + + init_input_shapes(input_shapes); + + auto param = std::make_shared(ov::element::boolean, inputDynamicShapes[0]); + ov::ParameterVector params{param}; + for (size_t i = 1; i < inputDynamicShapes.size(); i++) { + param = std::make_shared(model_type, inputDynamicShapes[i]); + params.push_back(param); + } + auto select = std::make_shared(params[0], params[1], params[2], broadcast); + function = std::make_shared(select->outputs(), params, "Select"); +} +} // namespace test +} // namespace ov diff --git a/tests/conditional_compilation/test_utils.py b/tests/conditional_compilation/test_utils.py index 312065cea0d8e4..76e384f92cf0a4 100644 --- a/tests/conditional_compilation/test_utils.py +++ b/tests/conditional_compilation/test_utils.py @@ -83,7 +83,7 @@ def make_build(openvino_root_dir, build_dir, install_dir, build_target: dict = N nproc = multiprocessing.cpu_count() cmd = ( f"cmake -DENABLE_PROFILING_ITT=ON -DCMAKE_BUILD_TYPE=Release " - f"-DPYTHON_EXECUTABLE={sys.executable} {additional_args_line}" + f"-DPython3_EXECUTABLE={sys.executable} {additional_args_line}" f"-S {openvino_root_dir} -B {build_dir} && " f"cmake --build {build_dir} -j{nproc} && " f"{' '.join(build_target_arg_line)}" diff --git a/tests/layer_tests/ovc_python_api_tests/test_paddle.py b/tests/layer_tests/ovc_python_api_tests/test_paddle.py index a91e3f9e723e38..80b8efefea3cf9 100644 --- a/tests/layer_tests/ovc_python_api_tests/test_paddle.py +++ b/tests/layer_tests/ovc_python_api_tests/test_paddle.py @@ -101,3 +101,35 @@ def test_mo_import_from_memory_paddle_fe(self, create_model, ie_device, precisio if mo_params is not None: test_params.update(mo_params) self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False) + + +class TestPaddleConversionParams(CommonMOConvertTest): + paddle_is_imported = False + try: + import paddle + paddle_is_imported = True + except ImportError: + pass + + test_data = [ + {'params_test': {'input': paddle.shape(paddle.to_tensor(np.random.rand(2, 3, 4)))}, + 'fw_model': make_pd_hapi_graph_model([1, 2]), + 'ref_model': make_ref_graph_model([2, 3, 4])}, + {'params_test': {'input': paddle.to_tensor(np.random.rand(5, 6)).shape}, + 'fw_model': make_pd_hapi_graph_model([1, 2, 3]), + 'ref_model': make_ref_graph_model([5, 6])}, + {'params_test': {'input': (paddle.to_tensor(np.random.rand(4, 2, 7)).shape, paddle.int32)}, + 'fw_model': make_pd_hapi_graph_model([2, 3]), + 'ref_model': make_ref_graph_model([4, 2, 7], np.int32)}, + ] if paddle_is_imported else [] + + @pytest.mark.parametrize("params", test_data) + @pytest.mark.nightly + def test_conversion_params(self, params, ie_device, precision, ir_version, + temp_dir, use_new_frontend, use_old_api): + fw_model = params['fw_model'] + test_params = params['params_test'] + ref_model = params['ref_model'] + + test_params.update({'input_model': fw_model}) + self._test_by_ref_graph(temp_dir, test_params, ref_model, compare_tensor_names=False) diff --git a/tests/layer_tests/ovc_python_api_tests/test_pytorch.py b/tests/layer_tests/ovc_python_api_tests/test_pytorch.py index 52d6669045928e..5ae2dcac31c83e 100644 --- a/tests/layer_tests/ovc_python_api_tests/test_pytorch.py +++ b/tests/layer_tests/ovc_python_api_tests/test_pytorch.py @@ -1145,3 +1145,75 @@ def test_failed_extension(self): with self.assertRaisesRegex(Exception, ".*Cannot recognize input model.*"): with tempfile.NamedTemporaryFile() as tmpfile: convert_model(tmpfile.name) + + +def create_model_three_inputs(): + from torch import nn + + class NeuralNetwork(nn.Module): + def __init__(self): + super(NeuralNetwork, self).__init__() + self.linear_relu_stack = nn.Sequential( + nn.ReLU(), + nn.Sigmoid(), + ) + + def forward(self, x, y, z): + out = self.linear_relu_stack(x + y + z), + return out + return NeuralNetwork() + + +def make_ref_model_three_inputs(shape, dtype=np.float32): + x = ov.opset8.parameter(PartialShape( + shape), name="x", dtype=dtype) + y = ov.opset8.parameter(PartialShape( + shape), name="y", dtype=dtype) + z = ov.opset8.parameter(PartialShape( + shape), name="z", dtype=dtype) + add1 = ov.opset8.add(x, y) + add2 = ov.opset8.add(add1, z) + + relu = ov.opset8.relu(add2) + + if dtype not in [np.float32, Type.dynamic]: + relu = ov.opset8.convert(relu, np.float32) + + sigm = ov.opset8.sigmoid(relu) + + parameter_list = [x, y, z] + model = Model([sigm], parameter_list, "test") + return model + + +class TestPytorchConversionParams(CommonMOConvertTest): + + test_data = [ + {'params_test': {'input': [(torch.Size([2, 3, 4]), torch.float32), + (torch.empty(2, 3, 4).size(), torch.float32), + (torch.empty(2, 3, 4).shape, torch.float32)]}, + 'fw_model': create_model_three_inputs(), + 'ref_model': make_ref_model_three_inputs([2,3,4], np.float32)}, + {'params_test': {'input': [(torch.Size([5, 2]), torch.int32), + (torch.empty(5, 2).size(), torch.int32), + (torch.empty(5, 2).shape, torch.int32)]}, + 'fw_model': create_model_three_inputs(), + 'ref_model': make_ref_model_three_inputs([5, 2], np.int32)}, + {'params_test': {'input': [(torch.Size([1, 3, 5]), torch.float32)]}, + 'fw_model': make_pt_model_one_input(), + 'ref_model': make_ref_pt_model_one_input([1, 3, 5], np.float32)}, + {'params_test': {'input': [(torch.empty(7, 3).size(), torch.int32)]}, + 'fw_model': make_pt_model_one_input(), + 'ref_model': make_ref_pt_model_one_input([7, 3], np.int32)}, + ] + + @pytest.mark.parametrize("params", test_data) + @pytest.mark.nightly + def test_conversion_params(self, params, ie_device, precision, ir_version, + temp_dir, use_new_frontend, use_old_api): + fw_model = params['fw_model'] + test_params = params['params_test'] + ref_model = params['ref_model'] + + test_params.update({'input_model': fw_model}) + self._test_by_ref_graph(temp_dir, test_params, ref_model, compare_tensor_names=False) diff --git a/tests/layer_tests/ovc_python_api_tests/test_tf.py b/tests/layer_tests/ovc_python_api_tests/test_tf.py index e8c098ff9cae56..b894ec7153e910 100644 --- a/tests/layer_tests/ovc_python_api_tests/test_tf.py +++ b/tests/layer_tests/ovc_python_api_tests/test_tf.py @@ -10,11 +10,10 @@ from common.mo_convert_test_class import CommonMOConvertTest from common.layer_test_class import CommonLayerTest +import tensorflow as tf def create_tf_graph_def(tmp_dir): - import tensorflow as tf - tf.compat.v1.reset_default_graph() with tf.compat.v1.Session() as sess: @@ -41,8 +40,6 @@ def create_tf_graph_def(tmp_dir): def create_keras_model(temp_dir): - import tensorflow as tf - tf.keras.backend.clear_session() tf.compat.v1.reset_default_graph() @@ -69,8 +66,6 @@ def create_keras_model(temp_dir): def create_tf1_wrap_function(tmp_dir): - import tensorflow as tf - def f(x, y): return tf.nn.sigmoid(tf.nn.relu(x + y)) @@ -91,7 +86,6 @@ def f(x, y): def create_tf_session(tmp_dir): - import tensorflow as tf from tensorflow.python.eager.context import graph_mode with graph_mode(): @@ -119,8 +113,6 @@ def create_tf_session(tmp_dir): def create_tf_module(tmp_dir): - import tensorflow as tf - class Net(tf.Module): def __init__(self, name=None): super(Net, self).__init__(name=name) @@ -143,8 +135,6 @@ def __call__(self, x, y): def create_tf_module_dynamic(tmp_dir): - import tensorflow as tf - class Net(tf.Module): def __init__(self, name=None): super(Net, self).__init__(name=name) @@ -169,7 +159,6 @@ def __call__(self, x, y): def create_keras_layer(tmp_dir): - import tensorflow as tf class LayerModel(tf.keras.layers.Layer): def __init__(self): @@ -193,7 +182,6 @@ def call(self, x, y): def create_keras_layer_dynamic(tmp_dir): - import tensorflow as tf class LayerModel(tf.keras.layers.Layer): def __init__(self): @@ -219,8 +207,6 @@ def call(self, x, y): def create_tf_checkpoint(tmp_dir): - import tensorflow as tf - input_names = ["Input1", "Input2"] input_shape = [1, 2, 3] @@ -245,8 +231,6 @@ def create_tf_checkpoint(tmp_dir): def create_tf_function(temp_dir): - import tensorflow as tf - @tf.function( input_signature=[tf.TensorSpec(shape=[1, 2, 3], dtype=tf.float32), tf.TensorSpec(shape=[1, 2, 3], dtype=tf.float32)]) @@ -268,8 +252,6 @@ def f(x1, x2): def create_tf_graph(temp_dir): - import tensorflow as tf - tf.compat.v1.reset_default_graph() with tf.compat.v1.Session() as sess: @@ -296,8 +278,6 @@ def create_tf_graph(temp_dir): def create_tf_saved_model_dir(temp_dir): - import tensorflow as tf - input_names = ["Input1", "Input2"] input_shape = [1, 2, 3] @@ -322,7 +302,6 @@ def create_tf_saved_model_dir(temp_dir): def create_tf_stateful_partioned_call_net(temp_dir): - import tensorflow as tf tf.compat.v1.reset_default_graph() data_shape = [1, 1, 10, 10] @@ -359,7 +338,6 @@ def first_func(input, filter): def create_keras_layer_input_list(): - import tensorflow as tf class LayerModel(tf.keras.layers.Layer): def __init__(self): @@ -386,7 +364,6 @@ def call(self, x, y): def create_keras_layer_input_list_one_inp(): - import tensorflow as tf class LayerModel(tf.keras.layers.Layer): def __init__(self): @@ -408,7 +385,6 @@ def call(self, x): def create_keras_layer_input_dict(): - import tensorflow as tf class LayerModel(tf.keras.layers.Layer): def __init__(self): @@ -434,7 +410,6 @@ def call(self, args): def create_keras_layer_input_dict_one_inp(): - import tensorflow as tf class LayerModel(tf.keras.layers.Layer): def __init__(self): @@ -522,7 +497,6 @@ def create_keras_layer_with_input_shapes_case4(tmp_dir): def create_keras_layer_with_tf_function_call(tmp_dir): - import tensorflow as tf class LayerModel(tf.Module): def __init__(self): super(LayerModel, self).__init__() @@ -538,7 +512,6 @@ def __call__(self, input1, input2): def create_keras_layer_with_tf_function_call_default_compressed_to_fp16(tmp_dir): - import tensorflow as tf class LayerModel(tf.Module): def __init__(self): super(LayerModel, self).__init__() @@ -554,7 +527,6 @@ def __call__(self, input1, input2): def create_keras_layer_with_tf_function_call_no_signature(tmp_dir): - import tensorflow as tf class LayerModel(tf.Module): def __init__(self): super(LayerModel, self).__init__() @@ -572,7 +544,6 @@ def __call__(self, input1, input2): def create_keras_layer_with_tf_function_call_no_signature_single_input(tmp_dir): - import tensorflow as tf class LayerModel(tf.Module): def __init__(self): super(LayerModel, self).__init__() @@ -590,7 +561,6 @@ def __call__(self, input1): def create_keras_layer_with_string_tensor(tmp_dir): - import tensorflow as tf class LayerModel(tf.Module): def __init__(self): super(LayerModel, self).__init__() @@ -612,6 +582,69 @@ def __call__(self, input1, input2): return model, model_ref, {} +def create_tf_model_three_inputs(shape=[1, 2, 3, 4], type=tf.float32): + tf.compat.v1.reset_default_graph() + + with tf.compat.v1.Session() as sess: + inp1 = tf.compat.v1.placeholder(type, shape, 'Input1') + inp2 = tf.compat.v1.placeholder(type, shape, 'Input2') + inp3 = tf.compat.v1.placeholder(type, shape, 'Input3') + + relu1 = tf.nn.relu(inp1, name='Relu1') + relu2 = tf.nn.relu(inp2, name='Relu2') + relu3 = tf.nn.relu(inp3, name='Relu3') + + add = relu1 + relu2 + relu3 + + tf.compat.v1.global_variables_initializer() + tf_net = sess.graph + return tf_net + + +def create_ref_model_three_inputs(shape=[1, 2, 3, 4], dtype=np.float32): + inp1 = ov.opset8.parameter(PartialShape( + shape), name="Input1", dtype=dtype) + inp2 = ov.opset8.parameter(PartialShape( + shape), name="Input2", dtype=dtype) + inp3 = ov.opset8.parameter(PartialShape( + shape), name="Input3", dtype=dtype) + + relu1 = ov.opset8.relu(inp1) + relu2 = ov.opset8.relu(inp2) + relu3 = ov.opset8.relu(inp3) + + add1 = ov.opset8.add(relu1, relu2) + add2 = ov.opset8.add(add1, relu3) + + parameter_list = [inp1, inp2, inp3] + model = Model([add2], parameter_list, "test") + return model + + +def create_tf_model_single_input(shape=[1, 2, 3, 4], type=tf.float32): + tf.compat.v1.reset_default_graph() + + with tf.compat.v1.Session() as sess: + inp = tf.compat.v1.placeholder(type, shape, 'Input') + relu = tf.nn.relu(inp, name='Relu') + output = tf.nn.sigmoid(relu, name='Sigmoid') + + tf.compat.v1.global_variables_initializer() + tf_net = sess.graph + + return tf_net + + +def create_ref_model_single_input(shape=[1, 2, 3, 4], dtype=np.float32): + inp = ov.opset8.parameter(PartialShape( + shape), name="Input", dtype=dtype) + relu = ov.opset8.relu(inp) + sigm = ov.opset8.sigmoid(relu) + parameter_list = [inp] + model = Model([sigm], parameter_list, "test") + return model + + class TestMoConvertTF(CommonMOConvertTest): test_data = [ # TF2 @@ -667,7 +700,6 @@ def test_unnamed_saved_model_dir(self, ie_device, precision, ir_version, temp_di self._test_by_ref_graph(temp_dir, test_params, graph_ref, compare_tensor_names=False) def test_zero_copy(self, ie_device, precision, ir_version, temp_dir): - import tensorflow as tf from openvino.tools.ovc import convert_model from openvino.runtime import compile_model class LayerModel(tf.Module): @@ -716,7 +748,6 @@ def __call__(self, input): assert np.array_equal(ov_infer2['Identity:0'], [ 0., 8., 16.]) def test_turn_off_sharing(self, ie_device, precision, ir_version, temp_dir): - import tensorflow as tf from openvino.tools.ovc import convert_model from openvino.runtime import compile_model class LayerModel(tf.Module): @@ -767,7 +798,6 @@ def __call__(self, input): def test_memory_loss(self, ie_device, precision, ir_version, temp_dir): # This test checks that the memory allocated for constants # is not lost after returning the model from convert_model() method. - import tensorflow as tf tf.compat.v1.reset_default_graph() from openvino.tools.ovc import convert_model @@ -820,7 +850,6 @@ def test_memory_loss(self, ie_device, precision, ir_version, temp_dir): assert CommonLayerTest().compare_ie_results_with_framework(ov_infer1, {"add:0": [2.6, 9.6, 12.4]}, eps) def test_scalar(self, ie_device, precision, ir_version, temp_dir): - import tensorflow as tf tf.compat.v1.reset_default_graph() from openvino.tools.ovc import convert_model @@ -861,7 +890,6 @@ def __call__(self, input): assert CommonLayerTest().compare_ie_results_with_framework(ov_infer, {"Identity:0": 3.2}, eps) def test_unnamed_variable(self, ie_device, precision, ir_version, temp_dir): - import tensorflow as tf tf.compat.v1.reset_default_graph() from openvino.tools.ovc import convert_model @@ -905,7 +933,6 @@ class TFConvertTest(unittest.TestCase): @pytest.mark.nightly @pytest.mark.precommit def test_tf_function_no_signature(self): - import tensorflow as tf from openvino.tools.ovc import convert_model @tf.function() @@ -920,8 +947,6 @@ def function(x1, x2): class TestTFLoadByModel(unittest.TestCase): def test_load_by_model_tf_graph_iterator(self): def simple_tf_model(): - import tensorflow as tf - tf.compat.v1.reset_default_graph() with tf.compat.v1.Session() as sess: @@ -955,3 +980,37 @@ def test_incorrect_inputs_2(self): # check that it accepts specified names as is without parsing into 2 different inputs with self.assertRaisesRegex(Exception, 'No node with name Input1\[1, 2, 3\],Input2\[1, 2, 3\]'): convert_model(tf_model, input='Input1[1, 2, 3],Input2[1, 2, 3]') + + +class TestTFConversionParams(CommonMOConvertTest): + test_data = [ + {'params_test': {'input': [tf.shape(tf.zeros((2, 3, 4))), tf.zeros((2, 3, 4)).shape, tf.TensorShape((2, 3, 4))]}, + 'fw_model': create_tf_model_three_inputs([1, 2, 3, 4]), + 'ref_model': create_ref_model_three_inputs([2, 3, 4])}, + {'params_test': {'input': [tf.float32, tf.float32, tf.float32]}, + 'fw_model': create_tf_model_three_inputs([2, 3], tf.int32), + 'ref_model': create_ref_model_three_inputs([2, 3], np.float32)}, + {'params_test': {'input': tf.shape(tf.zeros((5, 8, 2)))}, + 'fw_model': create_tf_model_single_input(), + 'ref_model': create_ref_model_single_input([5, 8, 2])}, + {'params_test': {'input': tf.zeros((9, 2)).shape}, + 'fw_model': create_tf_model_single_input(), + 'ref_model': create_ref_model_single_input([9, 2])}, + {'params_test': {'input': tf.TensorShape((4, 8, 3))}, + 'fw_model': create_tf_model_single_input(), + 'ref_model': create_ref_model_single_input([4, 8, 3])}, + {'params_test': {'input': tf.int32}, + 'fw_model': create_tf_model_single_input(), + 'ref_model': create_ref_model_single_input([1, 2, 3, 4], np.int32)} + ] + + @pytest.mark.parametrize("params", test_data) + @pytest.mark.nightly + def test_mo_convert_tf_model(self, params, ie_device, precision, ir_version, + temp_dir, use_new_frontend, use_old_api): + fw_model = params['fw_model'] + test_params = params['params_test'] + ref_model = params['ref_model'] + + test_params.update({'input_model': fw_model}) + self._test_by_ref_graph(temp_dir, test_params, ref_model, compare_tensor_names=False) \ No newline at end of file diff --git a/thirdparty/gtest/CMakeLists.txt b/thirdparty/gtest/CMakeLists.txt index 76e0463ea01492..f527552903c1d7 100644 --- a/thirdparty/gtest/CMakeLists.txt +++ b/thirdparty/gtest/CMakeLists.txt @@ -6,6 +6,7 @@ # Google Tests framework # +set(CMAKE_DISABLE_FIND_PACKAGE_PythonInterp ON) set(gtest_force_shared_crt ON CACHE BOOL "disable static CRT for google test") set(BUILD_SHARED_LIBS OFF) diff --git a/thirdparty/onnx/CMakeLists.txt b/thirdparty/onnx/CMakeLists.txt index a87c4fc42b3940..c9752a833f7b7c 100644 --- a/thirdparty/onnx/CMakeLists.txt +++ b/thirdparty/onnx/CMakeLists.txt @@ -23,14 +23,12 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") ov_add_compiler_flags(/wd4244) endif() +set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}") set(ONNX_USE_PROTOBUF_SHARED_LIBS OFF CACHE BOOL "Use dynamic protobuf by ONNX library" FORCE) set(ONNX_NAMESPACE ${OV_ONNX_NAMESPACE}) set(ONNX_USE_LITE_PROTO ${ONNX_USE_LITE_PROTO_DEFAULT} CACHE BOOL "Use protobuf lite for ONNX library" FORCE) set(ONNX_ML ON CACHE BOOL "Use ONNX ML" FORCE) -set(ONNX_CUSTOM_PROTOC_EXECUTABLE ${PROTOC_EXECUTABLE}) - -# clear Python_ADDITIONAL_VERSIONS to find only python library matching PYTHON_EXECUTABLE -unset(Python_ADDITIONAL_VERSIONS CACHE) +set(ONNX_CUSTOM_PROTOC_EXECUTABLE "${PROTOC_EXECUTABLE}") # build targets diff --git a/tools/mo/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt b/tools/mo/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt index 4a1a7d9099a6c8..9ae9e55a27a049 100644 --- a/tools/mo/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt +++ b/tools/mo/unit_tests/mock_mo_frontend/mock_mo_python_api/CMakeLists.txt @@ -25,15 +25,11 @@ set(PYBIND_FE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/mock_mo_python_api.cpp) source_group("src" FILES ${PYBIND_FE_SRC}) -if(PYTHON_VERSION_MINOR GREATER_EQUAL 11) +if(Python3_VERSION_MINOR GREATER_EQUAL 11) set(pybind11_min_version 2.9.2) else() set(pybind11_min_version 2.8.0) endif() -if(CMAKE_CROSSCOMPILING) - # since this version pybind11 has PYBIND11_PYTHONLIBS_OVERWRITE - set(pybind11_min_version 2.10.1) -endif() find_package(pybind11 ${pybind11_min_version} QUIET) @@ -43,6 +39,13 @@ if(NOT pybind11_FOUND) EXCLUDE_FROM_ALL) endif() +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18) + set(python3_development_component Development.Module) +else() + set(python3_development_component Development) +endif() + +find_package(Python3 REQUIRED COMPONENTS Interpreter ${python3_development_component}) pybind11_add_module(${PYBIND_FE_NAME} MODULE NO_EXTRAS ${PYBIND_FE_SRC}) target_link_libraries(${PYBIND_FE_NAME} PRIVATE openvino::runtime) diff --git a/tools/openvino_dev/CMakeLists.txt b/tools/openvino_dev/CMakeLists.txt index 42ad4031d69955..061e9c4e8e6b82 100644 --- a/tools/openvino_dev/CMakeLists.txt +++ b/tools/openvino_dev/CMakeLists.txt @@ -106,14 +106,14 @@ add_custom_command(OUTPUT ${openvino_wheel_path} COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/readme.txt" "${CMAKE_CURRENT_BINARY_DIR}" COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/setup.cfg" "${CMAKE_CURRENT_BINARY_DIR}" COMMAND ${CMAKE_COMMAND} -E env OPENVINO_VERSION=${WHEEL_VERSION} - ${PYTHON_EXECUTABLE} ${SETUP_PY} + ${Python3_EXECUTABLE} ${SETUP_PY} --quiet --no-user-cfg bdist_wheel --dist-dir ${openvino_wheels_output_dir} --build=${WHEEL_BUILD} COMMAND ${CMAKE_COMMAND} -E env OPENVINO_VERSION=${WHEEL_VERSION} - ${PYTHON_EXECUTABLE} ${SETUP_PY} clean + ${Python3_EXECUTABLE} ${SETUP_PY} clean WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMENT "Building Python wheel ${openvino_wheel_name}" VERBATIM) diff --git a/tools/ovc/openvino/tools/ovc/cli_parser.py b/tools/ovc/openvino/tools/ovc/cli_parser.py index 7bf03f5f54803d..87fc0225206fa5 100644 --- a/tools/ovc/openvino/tools/ovc/cli_parser.py +++ b/tools/ovc/openvino/tools/ovc/cli_parser.py @@ -14,22 +14,13 @@ import openvino from openvino.tools.ovc.error import Error from openvino.tools.ovc.help import get_convert_model_help_specifics +from openvino.tools.ovc.moc_frontend.shape_utils import to_partial_shape, is_shape_type +from openvino.tools.ovc.moc_frontend.type_utils import to_ov_type, is_type from openvino.tools.ovc.utils import get_mo_root_dir # Helper class for storing input cut information _InputCutInfo = namedtuple("InputCutInfo", ["name", "shape", "type", "value"], defaults=[None, None, None, None]) -def is_shape_type(value): - if isinstance(value, PartialShape): - return True - if isinstance(value, Shape): - return True - if isinstance(value, list) or isinstance(value, tuple): - for dim in value: - if not (isinstance(dim, Dimension) or isinstance(dim, int)): - return False - return True - return False def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type, type]): """ @@ -43,7 +34,7 @@ def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type, if isinstance(input, (tuple, list)) or is_shape_type(input): # If input represents list with shape, wrap it to list. Single PartialShape also goes to this condition. # Check of all dimensions will be in is_shape_type(val) method below - if len(input) > 0 and isinstance(input[0], (int, Dimension)) or isinstance(input, PartialShape): + if is_shape_type(input): input = [input] # Check values of tuple or list and collect to InputCutInfo @@ -55,14 +46,14 @@ def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type, if name is not None: raise Exception("More than one input name provided: {}".format(input)) name = val - elif isinstance(val, (type, Type)): + elif is_type(val): if inp_type is not None: raise Exception("More than one input type provided: {}".format(input)) - inp_type = val + inp_type = to_ov_type(val) elif is_shape_type(val) or val is None: if shape is not None: raise Exception("More than one input shape provided: {}".format(input)) - shape = PartialShape(val) if val is not None else None + shape = to_partial_shape(val) if val is not None else None else: raise Exception("Incorrect input parameters provided. Expected tuple with input name, " "input type or input shape. Got unknown object: {}".format(val)) @@ -72,14 +63,16 @@ def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type, inp_type, None) # Case when only type is set - if isinstance(input, (type, Type)): - return _InputCutInfo(None, None, input, None) # pylint: disable=no-member + if is_type(input): + return _InputCutInfo(None, None, to_ov_type(input), None) # pylint: disable=no-member # We don't expect here single unnamed value. If list of int is set it is considered as shape. # Setting of value is expected only using InputCutInfo or string analog. raise Exception("Unexpected object provided for input. Expected tuple, Shape, PartialShape, Type or str. Got {}".format(type(input))) + + def is_single_input(input: [tuple, list]): """ Checks if input has parameters for single input. @@ -94,14 +87,14 @@ def is_single_input(input: [tuple, list]): if name is not None: return False name = val - elif isinstance(val, (type, Type)): + elif is_type(val): if inp_type is not None: return False - inp_type = val + inp_type = to_ov_type(val) elif is_shape_type(val): if shape is not None: return False - shape = PartialShape(val) + shape = to_partial_shape(val) else: return False return True diff --git a/tools/ovc/openvino/tools/ovc/moc_frontend/shape_utils.py b/tools/ovc/openvino/tools/ovc/moc_frontend/shape_utils.py index defbe552b1d759..685996469091be 100644 --- a/tools/ovc/openvino/tools/ovc/moc_frontend/shape_utils.py +++ b/tools/ovc/openvino/tools/ovc/moc_frontend/shape_utils.py @@ -1,8 +1,11 @@ # Copyright (C) 2018-2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +import sys + import numpy as np -from openvino.runtime import PartialShape, Dimension # pylint: disable=no-name-in-module,import-error +from openvino.runtime import Shape, PartialShape, Dimension # pylint: disable=no-name-in-module,import-error + from openvino.tools.ovc.error import Error @@ -62,3 +65,46 @@ def get_dynamic_dims(shape: [PartialShape, list, tuple]): dynamic_dims.append(idx) return dynamic_dims + + +def tensor_to_int_list(tensor): + assert hasattr(tensor, 'numpy'), "Could not get value of provided tensor: {}".format(tensor) + tensor_numpy = tensor.numpy() + assert tensor_numpy.dtype == np.int32, "Unexpected type of provided tensor. Expected int32, got: {}".format( + tensor_numpy.dtype) + return tensor_numpy.tolist() + +def to_partial_shape(shape): + if 'tensorflow' in sys.modules: + import tensorflow as tf + if isinstance(shape, tf.Tensor): + return PartialShape(tensor_to_int_list(shape)) + if isinstance(shape, tf.TensorShape): + return PartialShape(list(shape)) + if 'paddle' in sys.modules: + import paddle + if isinstance(shape, paddle.Tensor): + return PartialShape(tensor_to_int_list(shape)) + return PartialShape(shape) + + +def is_shape_type(value): + if isinstance(value, PartialShape): + return True + if 'tensorflow' in sys.modules: + import tensorflow as tf + if isinstance(value, (tf.TensorShape, tf.Tensor)): + return True + if 'paddle' in sys.modules: + import paddle + if isinstance(value, paddle.Tensor): + return True + if isinstance(value, Shape): + return True + if isinstance(value, list) or isinstance(value, tuple): + for dim in value: + if not (isinstance(dim, Dimension) or isinstance(dim, int)): + return False + return True + return False + diff --git a/tools/ovc/openvino/tools/ovc/moc_frontend/type_utils.py b/tools/ovc/openvino/tools/ovc/moc_frontend/type_utils.py new file mode 100644 index 00000000000000..954143fda9b357 --- /dev/null +++ b/tools/ovc/openvino/tools/ovc/moc_frontend/type_utils.py @@ -0,0 +1,81 @@ +# Copyright (C) 2018-2023 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import sys + +from openvino.runtime import Type + +import openvino as ov + + +def is_type(val): + if isinstance(val, (type, Type)): + return True + if 'tensorflow' in sys.modules: + import tensorflow as tf + if isinstance(val, tf.dtypes.DType): + return True + if 'torch' in sys.modules: + import torch + if isinstance(val, torch.dtype): + return True + if 'paddle' in sys.modules: + import paddle + if isinstance(val, paddle.dtype): + return True + return False + + +def to_ov_type(val): + if isinstance(val, Type): + return val + if isinstance(val, type): + return Type(val) + if 'tensorflow' in sys.modules: + import tensorflow as tf + if isinstance(val, tf.dtypes.DType): + return Type(val.as_numpy_dtype()) + if 'torch' in sys.modules: + import torch + + if isinstance(val, torch.dtype): + torch_to_ov_type = { + torch.float32: ov.Type.f32, + torch.float16: ov.Type.f16, + torch.float64: ov.Type.f64, + torch.bfloat16: ov.Type.bf16, + torch.uint8: ov.Type.u8, + torch.int8: ov.Type.i8, + torch.int16: ov.Type.i16, + torch.int32: ov.Type.i32, + torch.int64: ov.Type.i64, + torch.bool: ov.Type.boolean, + } + if val not in torch_to_ov_type: + raise Exception("The provided data time is not supported {}.".format(val)) + + return torch_to_ov_type[val] + + if 'paddle' in sys.modules: + import paddle + + if isinstance(val, paddle.dtype): + paddle_to_ov_type = { + paddle.float32: ov.Type.f32, + paddle.float16: ov.Type.f16, + paddle.float64: ov.Type.f64, + paddle.bfloat16: ov.Type.bf16, + paddle.uint8: ov.Type.u8, + paddle.int8: ov.Type.i8, + paddle.int16: ov.Type.i16, + paddle.int32: ov.Type.i32, + paddle.int64: ov.Type.i64, + paddle.bool: ov.Type.boolean, + } + + if val not in paddle_to_ov_type: + raise Exception("The provided data time is not supported {}.".format(val)) + + return paddle_to_ov_type[val] + raise Exception("Unexpected type object. Expected ov.Type, np.dtype, tf.dtypes.DType. Got {}".format(type(val))) + diff --git a/tools/ovc/unit_tests/ovc/package_BOM.txt b/tools/ovc/unit_tests/ovc/package_BOM.txt index 5c8c73a2ac8c47..c7b37c2c147607 100644 --- a/tools/ovc/unit_tests/ovc/package_BOM.txt +++ b/tools/ovc/unit_tests/ovc/package_BOM.txt @@ -22,6 +22,7 @@ openvino/tools/ovc/moc_frontend/pipeline.py openvino/tools/ovc/moc_frontend/preprocessing.py openvino/tools/ovc/moc_frontend/pytorch_frontend_utils.py openvino/tools/ovc/moc_frontend/shape_utils.py +openvino/tools/ovc/moc_frontend/type_utils.py openvino/tools/ovc/ovc.py openvino/tools/ovc/telemetry_params.py openvino/tools/ovc/telemetry_stub.py