diff --git a/src/bindings/python/setup.cfg b/src/bindings/python/setup.cfg index 15abb7dc3de..cf1949d0869 100644 --- a/src/bindings/python/setup.cfg +++ b/src/bindings/python/setup.cfg @@ -9,7 +9,7 @@ enable-extensions = G per-file-ignores = *.pyx: E225, E226, E251, E999, E800, E265, E203, E266, E227, E211 tests/*: S101, T001 - *__init__.py: F403, F405, F405 + *__init__.py: E402, F403, F405, F405 [pydocstyle] convention = google diff --git a/src/bindings/python/src/openvino/frontend/__init__.py b/src/bindings/python/src/openvino/frontend/__init__.py index e9eeac5b7fb..51db763c42a 100644 --- a/src/bindings/python/src/openvino/frontend/__init__.py +++ b/src/bindings/python/src/openvino/frontend/__init__.py @@ -8,42 +8,23 @@ Low level wrappers for the FrontEnd c++ api. # flake8: noqa -import os -import sys - -if sys.platform == "win32": - # Installer, yum, pip installs openvino dlls to the different directories - # and those paths need to be visible to the openvino modules - # - # If you're using a custom installation of openvino, - # add the location of openvino dlls to your system PATH. - # - # looking for the libs in the pip installation path by default. - openvino_libs = [os.path.join(os.path.dirname(__file__), "..", "..", ".."), - os.path.join(os.path.dirname(__file__), "..", "..", "openvino", "libs")] - # setupvars.bat script set all libs paths to OPENVINO_LIB_PATHS environment variable. - openvino_libs_installer = os.getenv("OPENVINO_LIB_PATHS") - if openvino_libs_installer: - openvino_libs.extend(openvino_libs_installer.split(";")) - for lib in openvino_libs: - lib_path = os.path.join(os.path.dirname(__file__), lib) - if os.path.isdir(lib_path): - # On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH. - if (3, 8) <= sys.version_info: - os.add_dll_directory(os.path.abspath(lib_path)) - else: - os.environ["PATH"] = os.path.abspath(lib_path) + ";" + os.environ["PATH"] +from openvino.utils import add_openvino_libs_to_path +add_openvino_libs_to_path() # main classes from openvino.pyopenvino import FrontEndManager from openvino.pyopenvino import FrontEnd from openvino.pyopenvino import InputModel +from openvino.pyopenvino import NodeContext from openvino.pyopenvino import Place -from openvino.pyopenvino import TelemetryExtension + +# extensions from openvino.pyopenvino import DecoderTransformationExtension from openvino.pyopenvino import JsonConfigExtension +from openvino.pyopenvino import ConversionExtension from openvino.pyopenvino import ProgressReporterExtension +from openvino.pyopenvino import TelemetryExtension # exceptions from openvino.pyopenvino import NotImplementedFailure diff --git a/src/bindings/python/src/openvino/frontend/onnx/__init__.py b/src/bindings/python/src/openvino/frontend/onnx/__init__.py new file mode 100644 index 00000000000..ee3f15ed71f --- /dev/null +++ b/src/bindings/python/src/openvino/frontend/onnx/__init__.py @@ -0,0 +1,19 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +""" +Package: openvino +Low level wrappers for the FrontEnd c++ api. +""" + +# flake8: noqa + +from openvino.utils import add_openvino_libs_to_path + +add_openvino_libs_to_path() + +try: + from openvino.frontend.onnx.py_onnx_frontend import ConversionExtensionONNX as ConversionExtension +except ImportError as err: + raise ImportError("OpenVINO ONNX frontend is not available, please make sure the frontend is built. " + "{}".format(err)) diff --git a/src/bindings/python/src/openvino/frontend/paddle/__init__.py b/src/bindings/python/src/openvino/frontend/paddle/__init__.py new file mode 100644 index 00000000000..1138bc361f1 --- /dev/null +++ b/src/bindings/python/src/openvino/frontend/paddle/__init__.py @@ -0,0 +1,20 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +""" +Package: openvino +Low level wrappers for the FrontEnd c++ api. +""" + +# flake8: noqa + +from openvino.utils import add_openvino_libs_to_path + +add_openvino_libs_to_path() + + +try: + from openvino.frontend.paddle.py_paddle_frontend import ConversionExtensionPaddle as ConversionExtension +except ImportError as err: + raise ImportError("OpenVINO Paddle frontend is not available, please make sure the frontend is built." + "{}".format(err)) diff --git a/src/bindings/python/src/openvino/frontend/tensorflow/__init__.py b/src/bindings/python/src/openvino/frontend/tensorflow/__init__.py new file mode 100644 index 00000000000..68681a224ba --- /dev/null +++ b/src/bindings/python/src/openvino/frontend/tensorflow/__init__.py @@ -0,0 +1,19 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +""" +Package: openvino +Low level wrappers for the FrontEnd c++ api. +""" + +# flake8: noqa + +from openvino.utils import add_openvino_libs_to_path + +add_openvino_libs_to_path() + +try: + from openvino.frontend.tensorflow.py_tensorflow_frontend import ConversionExtensionTensorflow as ConversionExtension +except ImportError as err: + raise ImportError("OpenVINO Tensorflow frontend is not available, please make sure the frontend is built. " + "{}".format(err)) diff --git a/src/bindings/python/src/openvino/offline_transformations/__init__.py b/src/bindings/python/src/openvino/offline_transformations/__init__.py index b22f6d730fd..5b05fed8bfe 100644 --- a/src/bindings/python/src/openvino/offline_transformations/__init__.py +++ b/src/bindings/python/src/openvino/offline_transformations/__init__.py @@ -2,32 +2,11 @@ # Copyright (C) 2018-2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -import os -import sys +# flake8: noqa -if sys.platform == "win32": - # Installer, yum, pip installs openvino dlls to the different directories - # and those paths need to be visible to the openvino modules - # - # If you're using a custom installation of openvino, - # add the location of openvino dlls to your system PATH. - # - # looking for the libs in the pip installation path by default. - openvino_libs = [os.path.join(os.path.dirname(__file__), "..", "..", ".."), - os.path.join(os.path.dirname(__file__), "..", "..", "openvino", "libs")] - # setupvars.bat script set all libs paths to OPENVINO_LIB_PATHS environment variable. - openvino_libs_installer = os.getenv("OPENVINO_LIB_PATHS") - if openvino_libs_installer: - openvino_libs.extend(openvino_libs_installer.split(";")) - for lib in openvino_libs: - lib_path = os.path.join(os.path.dirname(__file__), lib) - if os.path.isdir(lib_path): - # On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH. - if (3, 8) <= sys.version_info: - os.add_dll_directory(os.path.abspath(lib_path)) - else: - os.environ["PATH"] = os.path.abspath(lib_path) + ";" + os.environ["PATH"] +from openvino.utils import add_openvino_libs_to_path +add_openvino_libs_to_path() from openvino.pyopenvino.offline_transformations import apply_moc_transformations from openvino.pyopenvino.offline_transformations import apply_moc_legacy_transformations diff --git a/src/bindings/python/src/openvino/preprocess/__init__.py b/src/bindings/python/src/openvino/preprocess/__init__.py index 96f459b5680..4625dd79054 100644 --- a/src/bindings/python/src/openvino/preprocess/__init__.py +++ b/src/bindings/python/src/openvino/preprocess/__init__.py @@ -8,32 +8,9 @@ Low level wrappers for the PrePostProcessing c++ api. # flake8: noqa -import os -import sys - -if sys.platform == "win32": - # Installer, yum, pip installs openvino dlls to the different directories - # and those paths need to be visible to the openvino modules - # - # If you're using a custom installation of openvino, - # add the location of openvino dlls to your system PATH. - # - # looking for the libs in the pip installation path by default. - openvino_libs = [os.path.join(os.path.dirname(__file__), "..", "..", ".."), - os.path.join(os.path.dirname(__file__), "..", "..", "openvino", "libs")] - # setupvars.bat script set all libs paths to OPENVINO_LIB_PATHS environment variable. - openvino_libs_installer = os.getenv("OPENVINO_LIB_PATHS") - if openvino_libs_installer: - openvino_libs.extend(openvino_libs_installer.split(";")) - for lib in openvino_libs: - lib_path = os.path.join(os.path.dirname(__file__), lib) - if os.path.isdir(lib_path): - # On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH. - if (3, 8) <= sys.version_info: - os.add_dll_directory(os.path.abspath(lib_path)) - else: - os.environ["PATH"] = os.path.abspath(lib_path) + ";" + os.environ["PATH"] +from openvino.utils import add_openvino_libs_to_path +add_openvino_libs_to_path() # main classes from openvino.pyopenvino.preprocess import InputInfo diff --git a/src/bindings/python/src/openvino/runtime/__init__.py b/src/bindings/python/src/openvino/runtime/__init__.py index aede8685ee8..b14c460d0b6 100644 --- a/src/bindings/python/src/openvino/runtime/__init__.py +++ b/src/bindings/python/src/openvino/runtime/__init__.py @@ -4,9 +4,7 @@ """openvino module namespace, exposing factory functions for all ops and other classes.""" # noqa: F401 -import os -import sys - +from openvino.utils import add_openvino_libs_to_path from pkg_resources import get_distribution, DistributionNotFound try: @@ -14,33 +12,7 @@ try: except DistributionNotFound: __version__ = "0.0.0.dev0" -if sys.platform == "win32": - # Installer, yum, pip installs openvino dlls to the different directories - # and those paths need to be visible to the openvino modules - # - # If you're using a custom installation of openvino, - # add the location of openvino dlls to your system PATH. - # - # looking for the libs in the pip installation path by default. - openvino_libs = [ - os.path.join(os.path.dirname(__file__), "..", "..", ".."), - os.path.join(os.path.dirname(__file__), "..", "..", "openvino", "libs"), - ] - # setupvars.bat script set all libs paths to OPENVINO_LIB_PATHS environment variable. - openvino_libs_installer = os.getenv("OPENVINO_LIB_PATHS") - if openvino_libs_installer: - openvino_libs.extend(openvino_libs_installer.split(";")) - for lib in openvino_libs: - lib_path = os.path.join(os.path.dirname(__file__), lib) - if os.path.isdir(lib_path): - # On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH. - if (3, 8) <= sys.version_info: - os.add_dll_directory(os.path.abspath(lib_path)) - else: - os.environ["PATH"] = ( - os.path.abspath(lib_path) + ";" + os.environ["PATH"] - ) - +add_openvino_libs_to_path() # Openvino pybind bindings and python extended classes from openvino.pyopenvino import Dimension diff --git a/src/bindings/python/src/openvino/utils.py b/src/bindings/python/src/openvino/utils.py new file mode 100644 index 00000000000..0c35d944deb --- /dev/null +++ b/src/bindings/python/src/openvino/utils.py @@ -0,0 +1,31 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import os +import sys + + +def add_openvino_libs_to_path() -> None: + """Adds OpenVINO libs to path on Win OS.""" + if sys.platform == "win32": + # Installer, yum, pip installs openvino dlls to the different directories + # and those paths need to be visible to the openvino modules + # + # If you're using a custom installation of openvino, + # add the location of openvino dlls to your system PATH. + # + # looking for the libs in the pip installation path by default. + openvino_libs = [os.path.join(os.path.dirname(__file__), "..", ".."), + os.path.join(os.path.dirname(__file__), "..", "openvino", "libs")] + # setupvars.bat script set all libs paths to OPENVINO_LIB_PATHS environment variable. + openvino_libs_installer = os.getenv("OPENVINO_LIB_PATHS") + if openvino_libs_installer: + openvino_libs.extend(openvino_libs_installer.split(";")) + for lib in openvino_libs: + lib_path = os.path.join(os.path.dirname(__file__), lib) + if os.path.isdir(lib_path): + # On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH. + if (3, 8) <= sys.version_info: + os.add_dll_directory(os.path.abspath(lib_path)) + else: + os.environ["PATH"] = os.path.abspath(lib_path) + ";" + os.environ["PATH"] diff --git a/src/bindings/python/src/pyopenvino/CMakeLists.txt b/src/bindings/python/src/pyopenvino/CMakeLists.txt index 82398550274..42c35d22234 100644 --- a/src/bindings/python/src/pyopenvino/CMakeLists.txt +++ b/src/bindings/python/src/pyopenvino/CMakeLists.txt @@ -48,9 +48,22 @@ if(ENABLE_TESTS) add_subdirectory(test_utils) endif() +if(TARGET openvino::frontend::onnx) + add_subdirectory(frontend/onnx) +endif() + +if(TARGET openvino::frontend::tensorflow) + add_subdirectory(frontend/tensorflow) +endif() + +if(TARGET openvino::frontend::paddle) + add_subdirectory(frontend/paddle) +endif() + # create target file(GLOB_RECURSE SOURCES core/*.cpp graph/*.cpp frontend/*.cpp pyopenvino.cpp) +list(FILTER SOURCES EXCLUDE REGEX frontend/onnx|tensorflow|paddle/* ) pybind11_add_module(${PROJECT_NAME} MODULE ${SOURCES}) diff --git a/src/bindings/python/src/pyopenvino/frontend/extensions.cpp b/src/bindings/python/src/pyopenvino/frontend/extension.cpp similarity index 56% rename from src/bindings/python/src/pyopenvino/frontend/extensions.cpp rename to src/bindings/python/src/pyopenvino/frontend/extension.cpp index 5e81aacc479..e6affea4b2c 100644 --- a/src/bindings/python/src/pyopenvino/frontend/extensions.cpp +++ b/src/bindings/python/src/pyopenvino/frontend/extension.cpp @@ -10,6 +10,7 @@ #include "extension/json_config.hpp" #include "manager.hpp" #include "openvino/frontend/exception.hpp" +#include "openvino/frontend/extension/conversion.hpp" #include "openvino/frontend/extension/decoder_transformation.hpp" #include "openvino/frontend/extension/progress_reporter_extension.hpp" #include "openvino/frontend/extension/telemetry.hpp" @@ -56,6 +57,45 @@ void regclass_frontend_JsonConfigExtension(py::module m) { })); } +void regclass_frontend_ConversionExtensionBase(py::module m) { + py::class_ ext(m, + "ConversionExtensionBase", + py::dynamic_attr()); +} + +void regclass_frontend_ConversionExtension(py::module m) { + py::class_ _ext(m, + "_ConversionExtension", + py::dynamic_attr(), + py::module_local()); + class PyConversionExtension : public ConversionExtension { + public: + using Ptr = std::shared_ptr; + using PyCreatorFunction = std::function; + using PyCreatorFunctionNamed = std::function(const NodeContext*)>; + PyConversionExtension(const std::string& op_type, const PyCreatorFunction& f) + : ConversionExtension(op_type, [f](const NodeContext& node) -> ov::OutputVector { + return f(static_cast(&node)); + }) {} + + PyConversionExtension(const std::string& op_type, const PyCreatorFunctionNamed& f) + : ConversionExtension(op_type, [f](const NodeContext& node) -> std::map { + return f(static_cast(&node)); + }) {} + }; + py::class_ ext(m, + "ConversionExtension", + py::dynamic_attr()); + + ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunction& f) { + return std::make_shared(op_type, f); + })); + + ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunctionNamed& f) { + return std::make_shared(op_type, f); + })); +} + void regclass_frontend_ProgressReporterExtension(py::module m) { py::class_, ov::Extension> ext{ m, diff --git a/src/bindings/python/src/pyopenvino/frontend/extensions.hpp b/src/bindings/python/src/pyopenvino/frontend/extension.hpp similarity index 77% rename from src/bindings/python/src/pyopenvino/frontend/extensions.hpp rename to src/bindings/python/src/pyopenvino/frontend/extension.hpp index ba11c4fecca..ec6c4f09bc0 100644 --- a/src/bindings/python/src/pyopenvino/frontend/extensions.hpp +++ b/src/bindings/python/src/pyopenvino/frontend/extension.hpp @@ -11,4 +11,6 @@ namespace py = pybind11; void regclass_frontend_TelemetryExtension(py::module m); void regclass_frontend_DecoderTransformationExtension(py::module m); void regclass_frontend_JsonConfigExtension(py::module m); +void regclass_frontend_ConversionExtension(py::module m); +void regclass_frontend_ConversionExtensionBase(py::module m); void regclass_frontend_ProgressReporterExtension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/frontend.cpp b/src/bindings/python/src/pyopenvino/frontend/frontend.cpp index ca23fd47684..40f3278c590 100644 --- a/src/bindings/python/src/pyopenvino/frontend/frontend.cpp +++ b/src/bindings/python/src/pyopenvino/frontend/frontend.cpp @@ -18,7 +18,7 @@ using namespace ov::frontend; void regclass_frontend_FrontEnd(py::module m) { py::class_> fem(m, "FrontEnd", py::dynamic_attr(), py::module_local()); - fem.doc() = "ngraph.impl.FrontEnd wraps ngraph::frontend::FrontEnd"; + fem.doc() = "openvino.frontend.FrontEnd wraps ov::frontend::FrontEnd"; fem.def( "load", diff --git a/src/bindings/python/src/pyopenvino/frontend/frontend_module.cmake b/src/bindings/python/src/pyopenvino/frontend/frontend_module.cmake new file mode 100644 index 00000000000..8dbf311d8f2 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/frontend_module.cmake @@ -0,0 +1,39 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +function(frontend_module TARGET FRAMEWORK INSTALL_COMPONENT) + set(TARGET_NAME ${TARGET}) + + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PYTHON_BRIDGE_OUTPUT_DIRECTORY}/frontend/${FRAMEWORK}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PYTHON_BRIDGE_OUTPUT_DIRECTORY}/frontend/${FRAMEWORK}) + set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${PYTHON_BRIDGE_OUTPUT_DIRECTORY}/frontend/${FRAMEWORK}) + set(CMAKE_PDB_OUTPUT_DIRECTORY ${PYTHON_BRIDGE_OUTPUT_DIRECTORY}/frontend/${FRAMEWORK}) + set(PYTHON_BRIDGE_CPACK_PATH "python") + + file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + + # create target + + pybind11_add_module(${TARGET_NAME} MODULE ${SOURCES}) + + add_dependencies(${TARGET_NAME} pyopenvino) + + target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") + target_link_libraries(${TARGET_NAME} PRIVATE openvino::runtime openvino::frontend::${FRAMEWORK}) + + # Compatibility with python 2.7 which has deprecated "register" specifier + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options(${TARGET_NAME} PRIVATE "-Wno-error=register") + endif() + + # perform copy + add_custom_command(TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_SOURCE_DIR}/openvino/frontend/${FRAMEWORK}/__init__.py ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/__init__.py + ) + + install(TARGETS ${TARGET_NAME} + DESTINATION python/${PYTHON_VERSION}/openvino/frontend/${FRAMEWORK} + COMPONENT ${INSTALL_COMPONENT}) +endfunction() \ No newline at end of file diff --git a/src/bindings/python/src/pyopenvino/frontend/inputmodel.cpp b/src/bindings/python/src/pyopenvino/frontend/input_model.cpp similarity index 100% rename from src/bindings/python/src/pyopenvino/frontend/inputmodel.cpp rename to src/bindings/python/src/pyopenvino/frontend/input_model.cpp diff --git a/src/bindings/python/src/pyopenvino/frontend/inputmodel.hpp b/src/bindings/python/src/pyopenvino/frontend/input_model.hpp similarity index 100% rename from src/bindings/python/src/pyopenvino/frontend/inputmodel.hpp rename to src/bindings/python/src/pyopenvino/frontend/input_model.hpp diff --git a/src/bindings/python/src/pyopenvino/frontend/node_context.cpp b/src/bindings/python/src/pyopenvino/frontend/node_context.cpp new file mode 100644 index 00000000000..7885d4365ce --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/node_context.cpp @@ -0,0 +1,127 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "node_context.hpp" + +#include +#include +#include +#include + +#include "openvino/frontend/node_context.hpp" + +namespace py = pybind11; + +using namespace ov::frontend; + +template +struct is_std_vector : std::false_type {}; + +template +struct is_std_vector> : std::true_type {}; + +#define CAST_VEC_TO_PY(any, py_type, c_type) \ + { \ + static_assert(is_std_vector(), "The type should be std::vector."); \ + if ((any).is()) { \ + auto casted = (any).as(); \ + if (!(py_type).is_none()) { \ + py::list py_list; \ + for (auto el : casted) { \ + py_list.append(py_type(el)); \ + } \ + return py_list; \ + } \ + return py::cast(casted); \ + } \ + } + +#define CAST_TO_PY(any, py_type, c_type) \ + { \ + if ((any).is()) { \ + auto casted = (any).as(); \ + if (!(py_type).is_none()) { \ + return py_type(casted); \ + } \ + return py::cast(casted); \ + } \ + } + +void regclass_frontend_NodeContext(py::module m) { + py::class_> ext(m, + "NodeContext", + py::dynamic_attr()); + + ext.def( + "get_attribute", + [=](NodeContext& self, const std::string& name, const py::object& default_value, const py::object& dtype) + -> py::object { + auto any = self.get_attribute_as_any(name); + auto module = py::module_::import("openvino.runtime"); + + auto type = m.attr("Type"); + if (dtype == type) { + if (any.is() || any.is()) { + return py::cast(self.get_attribute(name)); + } else if (any.is>() || any.is>()) { + return py::cast(self.get_attribute>(name)); + } + } + + CAST_TO_PY(any, dtype, int32_t); + CAST_TO_PY(any, dtype, int64_t); + CAST_TO_PY(any, dtype, bool); + CAST_TO_PY(any, dtype, std::string); + CAST_TO_PY(any, dtype, float); + CAST_TO_PY(any, dtype, ov::element::Type); + CAST_TO_PY(any, dtype, ov::PartialShape); + + CAST_VEC_TO_PY(any, dtype, std::vector); + CAST_VEC_TO_PY(any, dtype, std::vector); +#ifndef __APPLE__ + // TODO: investigate the issue in pybind11 on MacOS + CAST_VEC_TO_PY(any, dtype, std::vector); +#endif + CAST_VEC_TO_PY(any, dtype, std::vector); + CAST_VEC_TO_PY(any, dtype, std::vector); + CAST_VEC_TO_PY(any, dtype, std::vector); + CAST_VEC_TO_PY(any, dtype, std::vector); + + if (default_value.is_none()) + FRONT_END_GENERAL_CHECK(false, "Attribute ", name, " can't be converted to defined types."); + else + return default_value; + }, + py::arg("name"), + py::arg("default_value") = py::none(), + py::arg("dtype") = py::none()); + + ext.def("get_input", [](NodeContext& self, int idx) { + return self.get_input(idx); + }); + + ext.def("get_input", [](NodeContext& self, const std::string& name) { + return self.get_input(name); + }); + + ext.def("get_input", [](NodeContext& self, const std::string& name, int idx) { + return self.get_input(name, idx); + }); + + ext.def("get_input_size", [](NodeContext& self) { + return self.get_input_size(); + }); + + ext.def("get_input_size", [](NodeContext& self, std::string& name) { + return self.get_input_size(name); + }); + + ext.def("get_op_type", [](NodeContext& self, std::string& name) { + return self.get_op_type(); + }); + + ext.def("has_attribute", [](NodeContext& self, std::string& name) { + return self.has_attribute(name); + }); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/node_context.hpp b/src/bindings/python/src/pyopenvino/frontend/node_context.hpp new file mode 100644 index 00000000000..e16ee3bf05c --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/node_context.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace py = pybind11; + +void regclass_frontend_NodeContext(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/onnx/CMakeLists.txt b/src/bindings/python/src/pyopenvino/frontend/onnx/CMakeLists.txt new file mode 100644 index 00000000000..16c1b67ec86 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/onnx/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +include(${PYTHON_SOURCE_DIR}/pyopenvino/frontend/frontend_module.cmake) +frontend_module(py_onnx_frontend onnx pyopenvino_${PYTHON_VERSION}) diff --git a/src/bindings/python/src/pyopenvino/frontend/onnx/extension.cpp b/src/bindings/python/src/pyopenvino/frontend/onnx/extension.cpp new file mode 100644 index 00000000000..e090edb7cfe --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/onnx/extension.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "extension.hpp" + +#include +#include +#include +#include + +#include "openvino/frontend/onnx/extension/conversion.hpp" +#include "openvino/frontend/onnx/frontend.hpp" +#include "openvino/frontend/onnx/node_context.hpp" + +namespace py = pybind11; + +using namespace ov::frontend::onnx; + +void regclass_frontend_onnx_ConversionExtension(py::module m) { + py::class_ _ext( + m, + "_ConversionExtensionONNX", + py::dynamic_attr()); + class PyConversionExtension : public ConversionExtension { + public: + using Ptr = std::shared_ptr; + using PyCreatorFunction = std::function; + PyConversionExtension(const std::string& op_type, const PyCreatorFunction& f) + : ConversionExtension(op_type, [f](const ov::frontend::NodeContext& node) -> ov::OutputVector { + return f(static_cast(&node)); + }) {} + }; + py::class_ ext(m, + "ConversionExtensionONNX", + py::dynamic_attr()); + + ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunction& f) { + return std::make_shared(op_type, f); + })); + + ext.def_property_readonly_static("m_converter", &ConversionExtension::get_converter); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/onnx/extension.hpp b/src/bindings/python/src/pyopenvino/frontend/onnx/extension.hpp new file mode 100644 index 00000000000..d62e1906930 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/onnx/extension.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace py = pybind11; + +void regclass_frontend_onnx_ConversionExtension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/onnx/py_module.cpp b/src/bindings/python/src/pyopenvino/frontend/onnx/py_module.cpp new file mode 100644 index 00000000000..3e118685377 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/onnx/py_module.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "extension.hpp" + +namespace py = pybind11; + +PYBIND11_MODULE(py_onnx_frontend, m) { + regclass_frontend_onnx_ConversionExtension(m); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/paddle/CMakeLists.txt b/src/bindings/python/src/pyopenvino/frontend/paddle/CMakeLists.txt new file mode 100644 index 00000000000..dbba988710f --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/paddle/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +include(${PYTHON_SOURCE_DIR}/pyopenvino/frontend/frontend_module.cmake) +frontend_module(py_paddle_frontend paddle pyopenvino_${PYTHON_VERSION}) diff --git a/src/bindings/python/src/pyopenvino/frontend/paddle/extension.cpp b/src/bindings/python/src/pyopenvino/frontend/paddle/extension.cpp new file mode 100644 index 00000000000..75ce233c8aa --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/paddle/extension.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "extension.hpp" + +#include +#include +#include +#include + +#include "openvino/frontend/paddle/extension/conversion.hpp" + +namespace py = pybind11; + +using namespace ov::frontend::paddle; + +void regclass_frontend_paddle_ConversionExtension(py::module m) { + py::class_ _ext( + m, + "_ConversionExtensionPaddle", + py::dynamic_attr()); + class PyConversionExtension : public ConversionExtension { + public: + using Ptr = std::shared_ptr; + using PyCreatorFunctionNamed = + std::function(const ov::frontend::NodeContext*)>; + + PyConversionExtension(const std::string& op_type, const PyCreatorFunctionNamed& f) + : ConversionExtension( + op_type, + [f](const ov::frontend::NodeContext& node) -> std::map { + return f(static_cast(&node)); + }) {} + }; + py::class_ ext(m, + "ConversionExtensionPaddle", + py::dynamic_attr()); + + ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunctionNamed& f) { + return std::make_shared(op_type, f); + })); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/paddle/extension.hpp b/src/bindings/python/src/pyopenvino/frontend/paddle/extension.hpp new file mode 100644 index 00000000000..533081e0d15 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/paddle/extension.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace py = pybind11; + +void regclass_frontend_paddle_ConversionExtension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/paddle/py_module.cpp b/src/bindings/python/src/pyopenvino/frontend/paddle/py_module.cpp new file mode 100644 index 00000000000..1b779a2c4db --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/paddle/py_module.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "extension.hpp" + +namespace py = pybind11; + +PYBIND11_MODULE(py_paddle_frontend, m) { + regclass_frontend_paddle_ConversionExtension(m); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/tensorflow/CMakeLists.txt b/src/bindings/python/src/pyopenvino/frontend/tensorflow/CMakeLists.txt new file mode 100644 index 00000000000..34af1e9064e --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/tensorflow/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +include(${PYTHON_SOURCE_DIR}/pyopenvino/frontend/frontend_module.cmake) +frontend_module(py_tensorflow_frontend tensorflow tests) diff --git a/src/bindings/python/src/pyopenvino/frontend/tensorflow/extension.cpp b/src/bindings/python/src/pyopenvino/frontend/tensorflow/extension.cpp new file mode 100644 index 00000000000..33efcf3bde0 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/tensorflow/extension.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "extension.hpp" + +#include +#include +#include +#include + +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/tensorflow/extension/conversion.hpp" + +namespace py = pybind11; + +using namespace ov::frontend::tensorflow; + +void regclass_frontend_tensorflow_ConversionExtension(py::module m) { + py::class_ _ext( + m, + "_ConversionExtensionTensorflow", + py::dynamic_attr()); + class PyConversionExtension : public ConversionExtension { + public: + using Ptr = std::shared_ptr; + using PyCreatorFunction = std::function; + PyConversionExtension(const std::string& op_type, const PyCreatorFunction& f) + : ConversionExtension(op_type, [f](const ov::frontend::NodeContext& node) -> ov::OutputVector { + return f(static_cast(&node)); + }) {} + }; + py::class_ ext( + m, + "ConversionExtensionTensorflow", + py::dynamic_attr()); + + ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunction& f) { + return std::make_shared(op_type, f); + })); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/tensorflow/extension.hpp b/src/bindings/python/src/pyopenvino/frontend/tensorflow/extension.hpp new file mode 100644 index 00000000000..c8fd7a1ad13 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/tensorflow/extension.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace py = pybind11; + +void regclass_frontend_tensorflow_ConversionExtension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/tensorflow/py_module.cpp b/src/bindings/python/src/pyopenvino/frontend/tensorflow/py_module.cpp new file mode 100644 index 00000000000..b6592e2880d --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/tensorflow/py_module.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +#include "extension.hpp" + +namespace py = pybind11; + +PYBIND11_MODULE(py_tensorflow_frontend, m) { + regclass_frontend_tensorflow_ConversionExtension(m); +} diff --git a/src/bindings/python/src/pyopenvino/pyopenvino.cpp b/src/bindings/python/src/pyopenvino/pyopenvino.cpp index 7666942c5bd..00f09adbe08 100644 --- a/src/bindings/python/src/pyopenvino/pyopenvino.cpp +++ b/src/bindings/python/src/pyopenvino/pyopenvino.cpp @@ -32,10 +32,11 @@ #include "pyopenvino/core/tensor.hpp" #include "pyopenvino/core/variable_state.hpp" #include "pyopenvino/core/version.hpp" -#include "pyopenvino/frontend/extensions.hpp" +#include "pyopenvino/frontend/extension.hpp" #include "pyopenvino/frontend/frontend.hpp" -#include "pyopenvino/frontend/inputmodel.hpp" +#include "pyopenvino/frontend/input_model.hpp" #include "pyopenvino/frontend/manager.hpp" +#include "pyopenvino/frontend/node_context.hpp" #include "pyopenvino/frontend/place.hpp" #include "pyopenvino/graph/any.hpp" #include "pyopenvino/graph/descriptors/tensor.hpp" @@ -133,6 +134,7 @@ PYBIND11_MODULE(pyopenvino, m) { regclass_ProfilingInfo(m); regclass_Extension(m); + // frontend regclass_frontend_Place(m); regclass_frontend_InitializationFailureFrontEnd(m); regclass_frontend_GeneralFailureFrontEnd(m); @@ -142,10 +144,16 @@ PYBIND11_MODULE(pyopenvino, m) { regclass_frontend_FrontEndManager(m); regclass_frontend_FrontEnd(m); regclass_frontend_InputModel(m); + regclass_frontend_NodeContext(m); + + // frontend extensions regclass_frontend_TelemetryExtension(m); regclass_frontend_DecoderTransformationExtension(m); regclass_frontend_JsonConfigExtension(m); + regclass_frontend_ConversionExtensionBase(m); + regclass_frontend_ConversionExtension(m); regclass_frontend_ProgressReporterExtension(m); + // transformations regmodule_offline_transformations(m); } diff --git a/src/bindings/python/tests/mock/ov_mock_py_frontend/CMakeLists.txt b/src/bindings/python/tests/mock/ov_mock_py_frontend/CMakeLists.txt index 00269236bd3..0788de88018 100644 --- a/src/bindings/python/tests/mock/ov_mock_py_frontend/CMakeLists.txt +++ b/src/bindings/python/tests/mock/ov_mock_py_frontend/CMakeLists.txt @@ -4,18 +4,38 @@ set(TARGET_FE_NAME "ov_mock_py_frontend") -file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) -file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp) source_group("src" FILES ${LIBRARY_SRC}) source_group("include" FILES ${LIBRARY_HEADERS}) -# Create shared library -add_library(${TARGET_FE_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS}) +add_library(${TARGET_FE_NAME} ${LIBRARY_SRC} ${LIBRARY_HEADERS}) -target_include_directories(${TARGET_FE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${TARGET_FE_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) -target_link_libraries(${TARGET_FE_NAME} PRIVATE frontend_common::static) +set(DEPENDENCIES frontend_common::static) +set(DEFINITIONS) + +if (ENABLE_OV_ONNX_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::onnx) + list(APPEND DEFINITIONS ENABLE_OV_ONNX_FRONTEND) +endif() + +if (ENABLE_OV_TF_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::tensorflow) + list(APPEND DEFINITIONS ENABLE_OV_TF_FRONTEND) +endif() + +if (ENABLE_OV_PADDLE_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::paddle) + list(APPEND DEFINITIONS ENABLE_OV_PADDLE_FRONTEND) +endif() + +target_compile_definitions(${TARGET_FE_NAME} PRIVATE ${DEFINITIONS}) +target_link_libraries(${TARGET_FE_NAME} PRIVATE ${DEPENDENCIES}) add_clang_format_target(${TARGET_FE_NAME}_clang FOR_TARGETS ${TARGET_FE_NAME}) diff --git a/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/frontend_wrappers.hpp b/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/frontend_wrappers.hpp new file mode 100644 index 00000000000..256e67db9e0 --- /dev/null +++ b/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/frontend_wrappers.hpp @@ -0,0 +1,61 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#ifdef ENABLE_OV_ONNX_FRONTEND +# include "openvino/frontend/onnx/frontend.hpp" +#endif + +#ifdef ENABLE_OV_PADDLE_FRONTEND +# include "openvino/frontend/paddle/frontend.hpp" +#endif + +#ifdef ENABLE_OV_TF_FRONTEND +# include "openvino/frontend/tensorflow/frontend.hpp" +#endif +#include "visibility.hpp" + +#ifdef ENABLE_OV_ONNX_FRONTEND +// TODO: create Wrapper for ONNX. How to check that converter is actually registered? +// m_op_translators is some internal entity for ONNX FrontEnd +/*class MOCK_API FrontEndWrapperONNX : public ov::frontend::onnx::FrontEnd { +public: + void add_extension(const std::shared_ptr& extension) override { + FrontEnd::add_extension(extension); + } + + bool check_conversion_extension_registered(const std::string& name) { + return m_op_translators.find(name) != m_op_translators.end(); + } +};*/ +#endif + +#ifdef ENABLE_OV_TF_FRONTEND +class MOCK_API FrontEndWrapperTensorflow : public ov::frontend::tensorflow::FrontEnd { +public: + FrontEndWrapperTensorflow() = default; + void add_extension(const std::shared_ptr& extension) override { + FrontEnd::add_extension(extension); + } + + bool check_conversion_extension_registered(const std::string& name) { + return m_op_translators.find(name) != m_op_translators.end(); + } +}; +#endif + +#ifdef ENABLE_OV_PADDLE_FRONTEND +class MOCK_API FrontEndWrapperPaddle : public ov::frontend::paddle::FrontEnd { +public: + FrontEndWrapperPaddle() = default; + void add_extension(const std::shared_ptr& extension) override { + FrontEnd::add_extension(extension); + } + + bool check_conversion_extension_registered(const std::string& name) { + return m_op_translators.find(name) != m_op_translators.end(); + } +}; +#endif diff --git a/src/bindings/python/tests/mock/ov_mock_py_frontend/mock_py_frontend.hpp b/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/mock_py_frontend.hpp similarity index 98% rename from src/bindings/python/tests/mock/ov_mock_py_frontend/mock_py_frontend.hpp rename to src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/mock_py_frontend.hpp index 87ad9ab793f..e2579cd6c25 100644 --- a/src/bindings/python/tests/mock/ov_mock_py_frontend/mock_py_frontend.hpp +++ b/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/mock_py_frontend.hpp @@ -4,20 +4,11 @@ #pragma once -#include "ngraph/visibility.hpp" #include "openvino/frontend/extension/telemetry.hpp" #include "openvino/frontend/manager.hpp" -#include "openvino/frontend/visibility.hpp" - -// Defined if we are building the plugin DLL (instead of using it) -#ifdef ov_mock_py_frontend_EXPORTS -# define MOCK_API OPENVINO_CORE_EXPORTS -#else -# define MOCK_API OPENVINO_CORE_IMPORTS -#endif // ov_mock_py_frontend_EXPORTS +#include "visibility.hpp" // OK to have 'using' in mock header - using namespace ngraph; using namespace ov::frontend; diff --git a/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/visibility.hpp b/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/visibility.hpp new file mode 100644 index 00000000000..1abba8072ba --- /dev/null +++ b/src/bindings/python/tests/mock/ov_mock_py_frontend/include/ov_mock_py_frontend/visibility.hpp @@ -0,0 +1,17 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/visibility.hpp" + +#ifdef OPENVINO_STATIC_LIBRARY +# define MOCK_API +#else +# ifdef IMPLEMENT_OPENVINO_API +# define MOCK_API OPENVINO_CORE_EXPORTS +# else +# define MOCK_API OPENVINO_CORE_IMPORTS +# endif // IMPLEMENT_OPENVINO_API +#endif // OPENVINO_STATIC_LIBRARY diff --git a/src/bindings/python/tests/mock/ov_mock_py_frontend/mock_py_frontend.cpp b/src/bindings/python/tests/mock/ov_mock_py_frontend/src/mock_py_frontend.cpp similarity index 92% rename from src/bindings/python/tests/mock/ov_mock_py_frontend/mock_py_frontend.cpp rename to src/bindings/python/tests/mock/ov_mock_py_frontend/src/mock_py_frontend.cpp index 82f6f0942ca..1a6fe6b44d9 100644 --- a/src/bindings/python/tests/mock/ov_mock_py_frontend/mock_py_frontend.cpp +++ b/src/bindings/python/tests/mock/ov_mock_py_frontend/src/mock_py_frontend.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "mock_py_frontend.hpp" +#include "ov_mock_py_frontend/mock_py_frontend.hpp" #include "openvino/frontend/manager.hpp" #include "openvino/frontend/visibility.hpp" diff --git a/src/bindings/python/tests/mock/pyngraph_fe_mock_api/CMakeLists.txt b/src/bindings/python/tests/mock/pyngraph_fe_mock_api/CMakeLists.txt index 5e7de5c9b61..7974bb6e44b 100644 --- a/src/bindings/python/tests/mock/pyngraph_fe_mock_api/CMakeLists.txt +++ b/src/bindings/python/tests/mock/pyngraph_fe_mock_api/CMakeLists.txt @@ -2,7 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(TARGET_FE_NAME "ov_mock_py_frontend") set(PYBIND_FE_NAME "pybind_mock_frontend") set(PYBIND_FE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pyngraph_mock_frontend_api.cpp) @@ -11,7 +10,26 @@ source_group("src" FILES ${PYBIND_FE_SRC}) pybind11_add_module(${PYBIND_FE_NAME} MODULE ${PYBIND_FE_SRC}) -target_link_libraries(${PYBIND_FE_NAME} PRIVATE ${TARGET_FE_NAME} frontend_common::static) +set(DEPENDENCIES ov_mock_py_frontend openvino::runtime) +set(DEFINITIONS) + +if (ENABLE_OV_ONNX_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::onnx) + list(APPEND DEFINITIONS ENABLE_OV_ONNX_FRONTEND) +endif() + +if (ENABLE_OV_TF_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::tensorflow) + list(APPEND DEFINITIONS ENABLE_OV_TF_FRONTEND) +endif() + +if (ENABLE_OV_PADDLE_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::paddle) + list(APPEND DEFINITIONS ENABLE_OV_PADDLE_FRONTEND) +endif() + +target_compile_definitions(${PYBIND_FE_NAME} PRIVATE ${DEFINITIONS}) +target_link_libraries(${PYBIND_FE_NAME} PRIVATE ${DEPENDENCIES}) add_clang_format_target(${PYBIND_FE_NAME}_clang FOR_TARGETS ${PYBIND_FE_NAME}) diff --git a/src/bindings/python/tests/mock/pyngraph_fe_mock_api/pyngraph_mock_frontend_api.cpp b/src/bindings/python/tests/mock/pyngraph_fe_mock_api/pyngraph_mock_frontend_api.cpp index b3bca11c925..d577cebf98d 100644 --- a/src/bindings/python/tests/mock/pyngraph_fe_mock_api/pyngraph_mock_frontend_api.cpp +++ b/src/bindings/python/tests/mock/pyngraph_fe_mock_api/pyngraph_mock_frontend_api.cpp @@ -5,12 +5,17 @@ #include #include -#include "../ov_mock_py_frontend/mock_py_frontend.hpp" +#include "ov_mock_py_frontend/frontend_wrappers.hpp" +#include "ov_mock_py_frontend/mock_py_frontend.hpp" namespace py = pybind11; using namespace ngraph; using namespace ov::frontend; +FeStat FrontEndMockPy::m_stat = {}; +ModelStat InputModelMockPy::m_stat = {}; +PlaceStat PlaceMockPy::m_stat = {}; + static void register_mock_frontend_stat(py::module m) { m.def("get_fe_stat", &FrontEndMockPy::get_stat); m.def("clear_fe_stat", &FrontEndMockPy::clear_stat); @@ -92,9 +97,44 @@ static void register_mock_place_stat(py::module m) { placeStat.def_property_readonly("get_source_tensor", &PlaceStat::get_source_tensor); } +static void register_frontend_wrappers(py::module m) { +#ifdef ENABLE_OV_PADDLE_FRONTEND + py::class_> fe_paddle(m, + "FrontEndWrapperPaddle", + py::dynamic_attr()); + fe_paddle.def(py::init([]() { + return std::make_shared(); + })); + fe_paddle.def( + "add_extension", + static_cast& extension)>(&FrontEnd::add_extension)); + fe_paddle.def("check_conversion_extension_registered", [](FrontEndWrapperPaddle& self, const std::string& name) { + return self.check_conversion_extension_registered(name); + }); +#endif + +#ifdef ENABLE_OV_TF_FRONTEND + py::class_> fe_tensorflow( + m, + "FrontEndWrapperTensorflow", + py::dynamic_attr()); + fe_tensorflow.def(py::init([]() { + return std::make_shared(); + })); + fe_tensorflow.def( + "add_extension", + static_cast& extension)>(&FrontEnd::add_extension)); + fe_tensorflow.def("check_conversion_extension_registered", + [](FrontEndWrapperTensorflow& self, const std::string& name) { + return self.check_conversion_extension_registered(name); + }); +#endif +} + PYBIND11_MODULE(pybind_mock_frontend, m) { m.doc() = "Mock frontend call counters for testing Pyngraph frontend bindings"; register_mock_frontend_stat(m); register_mock_model_stat(m); register_mock_place_stat(m); + register_frontend_wrappers(m); } diff --git a/src/bindings/python/tests/test_frontend/__init__.py b/src/bindings/python/tests/test_frontend/__init__.py new file mode 100644 index 00000000000..46a1a3756d2 --- /dev/null +++ b/src/bindings/python/tests/test_frontend/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 diff --git a/src/bindings/python/tests/test_frontend/test_frontend_extension.py b/src/bindings/python/tests/test_frontend/test_frontend_extension.py new file mode 100644 index 00000000000..f675e8abf5f --- /dev/null +++ b/src/bindings/python/tests/test_frontend/test_frontend_extension.py @@ -0,0 +1,60 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from openvino.frontend import FrontEndManager + +mock_available = True +try: + from openvino.pybind_mock_frontend import FrontEndWrapperPaddle, FrontEndWrapperTensorflow +except Exception: + print("No mock frontend available") + mock_available = False + +# FrontEndManager shall be initialized and destroyed after all tests finished +# This is because destroy of FrontEndManager will unload all plugins, no objects shall exist after this +fem = FrontEndManager() +TENSORFLOW_FRONTEND_NAME = "tf" +PADDLE_FRONTEND_NAME = "paddle" + +mock_needed = pytest.mark.skipif(not mock_available, reason="mock fe is not available") + + +def skip_if_frontend_is_disabled(frontend_name): + front_ends = fem.get_available_front_ends() + if frontend_name not in front_ends: + pytest.skip() + + +@mock_needed +def test_tensorflow_conversion_extension_fe_wrapper(): + skip_if_frontend_is_disabled(TENSORFLOW_FRONTEND_NAME) + + from openvino.frontend.tensorflow import ConversionExtension + from openvino.frontend import NodeContext + + fe = FrontEndWrapperTensorflow() + + def custom_converter(node: NodeContext): + node.get_input(0) + node.get_attribute("alpha") + + fe.add_extension(ConversionExtension("CustomConverter", custom_converter)) + assert fe.check_conversion_extension_registered("CustomConverter") + + +@mock_needed +def test_paddle_conversion_extension_fe_wrapper(): + skip_if_frontend_is_disabled(PADDLE_FRONTEND_NAME) + + from openvino.frontend.paddle import ConversionExtension + from openvino.frontend import NodeContext + + fe = FrontEndWrapperPaddle() + + def custom_converter(node: NodeContext): + node.get_input(0) + node.get_attribute("alpha") + + fe.add_extension(ConversionExtension("CustomConverter", custom_converter)) + assert fe.check_conversion_extension_registered("CustomConverter") diff --git a/src/bindings/python/tests/test_frontend/test_frontend_onnx.py b/src/bindings/python/tests/test_frontend/test_frontend_onnx.py index 89bbfff97b5..16f757a0153 100644 --- a/src/bindings/python/tests/test_frontend/test_frontend_onnx.py +++ b/src/bindings/python/tests/test_frontend/test_frontend_onnx.py @@ -13,7 +13,10 @@ from tests.runtime import get_runtime def create_onnx_model(): add = onnx.helper.make_node("Add", inputs=["x", "y"], outputs=["z"]) - const_tensor = onnx.helper.make_tensor("const_tensor", onnx.TensorProto.FLOAT, (2, 2), [0.5, 1, 1.5, 2.0]) + const_tensor = onnx.helper.make_tensor("const_tensor", + onnx.TensorProto.FLOAT, + (2, 2), + [0.5, 1, 1.5, 2.0]) const_node = onnx.helper.make_node("Constant", [], outputs=["const_node"], value=const_tensor, name="const_node") mul = onnx.helper.make_node("Mul", inputs=["z", "const_node"], outputs=["out"]) @@ -52,6 +55,42 @@ def create_onnx_model_with_subgraphs(): return make_model(graph, producer_name="ngraph ONNX Importer") +def create_onnx_model_with_custom_attributes(): + add = onnx.helper.make_node("Add", inputs=["x", "y"], outputs=["z"], + attribute_i32=np.int32(10), + attribute_i64=np.int64(10), + attribute_str="string", + attribute_f32=np.float(10), + attribute_f64=np.float64(10), + attribute_bool=np.bool(True), + attribute_type=onnx.TensorProto.INT32, + + attribute_list_i32=np.array([1, 2, 3], dtype=np.int32), + attribute_list_i64=np.array([1, 2, 3], dtype=np.int64), + attribute_list_str=np.array(["a", "b", "c"], dtype=np.str), + attribute_list_f32=np.array([1, 2, 3], dtype=np.float), + attribute_list_f64=np.array([1, 2, 3], dtype=np.float64), + attribute_list_bool=[True, False, True], + attribute_list_type=np.array([onnx.TensorProto.INT32, + onnx.TensorProto.FLOAT]), + + ) + const_tensor = onnx.helper.make_tensor("const_tensor", + onnx.TensorProto.FLOAT, + (2, 2), + [0.5, 1, 1.5, 2.0]) + const_node = onnx.helper.make_node("Constant", [], outputs=["const_node"], + value=const_tensor, name="const_node") + mul = onnx.helper.make_node("Mul", inputs=["z", "const_node"], outputs=["out"]) + input_tensors = [ + make_tensor_value_info("x", onnx.TensorProto.FLOAT, (2, 2)), + make_tensor_value_info("y", onnx.TensorProto.FLOAT, (2, 2)), + ] + output_tensors = [make_tensor_value_info("out", onnx.TensorProto.FLOAT, (2, 2))] + graph = make_graph([add, const_node, mul], "graph", input_tensors, output_tensors) + return make_model(graph, producer_name="ngraph ONNX Importer") + + def run_function(function, *inputs, expected): runtime = get_runtime() computation = runtime.computation(function) @@ -61,19 +100,25 @@ def run_function(function, *inputs, expected): np.testing.assert_allclose(expected[i], actual[i], rtol=1e-3, atol=1e-6) +# FrontEndManager shall be initialized and destroyed after all tests finished +# This is because destroy of FrontEndManager will unload all plugins, no objects shall exist after this fem = FrontEndManager() onnx_model_filename = "model.onnx" +onnx_model_with_custom_attributes_filename = "model_custom_attributes.onnx" onnx_model_with_subgraphs_filename = "model_subgraphs.onnx" ONNX_FRONTEND_NAME = "onnx" def setup_module(): onnx.save_model(create_onnx_model(), onnx_model_filename) + onnx.save_model(create_onnx_model_with_custom_attributes(), + onnx_model_with_custom_attributes_filename) onnx.save_model(create_onnx_model_with_subgraphs(), onnx_model_with_subgraphs_filename) def teardown_module(): os.remove(onnx_model_filename) + os.remove(onnx_model_with_custom_attributes_filename) os.remove(onnx_model_with_subgraphs_filename) @@ -149,3 +194,232 @@ def test_load_by_model(): assert not fem.load_by_model("test.xx") assert not fem.load_by_model("onnx.yy") + + +def test_onnx_conversion_extension_check_attributes(): + skip_if_onnx_frontend_is_disabled() + + # use specific (openvino.frontend.onnx) import here + from openvino.frontend.onnx import ConversionExtension + from openvino.frontend import NodeContext + import openvino.runtime.opset8 as ops + + # use the model with attributes + fe = fem.load_by_model(onnx_model_with_custom_attributes_filename) + assert fe + assert fe.get_name() == "onnx" + + invoked = False + + def custom_converter(node: NodeContext): + nonlocal invoked + invoked = True + + def check_attribute(context, name, expected_type, expected_value): + assert context.has_attribute(name) + attribute = context.get_attribute(name) + assert type(attribute) == expected_type + assert attribute == expected_value + + check_attribute(node, "attribute_i32", int, 10) + check_attribute(node, "attribute_i64", int, 10) + check_attribute(node, "attribute_str", str, "string") + check_attribute(node, "attribute_f32", float, 10.) + check_attribute(node, "attribute_f64", float, 10.) + check_attribute(node, "attribute_bool", int, 1) + check_attribute(node, "attribute_type", int, 6) + + check_attribute(node, "attribute_list_i32", list, [1, 2, 3]) + check_attribute(node, "attribute_list_i64", list, [1, 2, 3]) + check_attribute(node, "attribute_list_str", list, ["a", "b", "c"]) + check_attribute(node, "attribute_list_f32", list, [1., 2., 3.]) + check_attribute(node, "attribute_list_f64", list, [1., 2., 3.]) + check_attribute(node, "attribute_list_bool", list, [1, 0, 1]) + check_attribute(node, "attribute_list_type", list, [6, 1]) + + a = node.get_input(0) + b = node.get_input(1) + add = ops.add(a, b) + return [add.output(0)] + + fe.add_extension(ConversionExtension("Add", custom_converter)) + input_model = fe.load(onnx_model_with_custom_attributes_filename) + assert input_model + model = fe.convert(input_model) + assert model + assert invoked + + +def test_onnx_conversion_extension_attribute_with_default_value(): + skip_if_onnx_frontend_is_disabled() + + # use specific (openvino.frontend.onnx) import here + from openvino.frontend.onnx import ConversionExtension + from openvino.frontend import NodeContext + import openvino.runtime.opset8 as ops + + # use the model without attributes + fe = fem.load_by_model(onnx_model_filename) + assert fe + assert fe.get_name() == "onnx" + + invoked = False + + def custom_converter(node: NodeContext): + nonlocal invoked + invoked = True + + def check_attribute(context, name, default_value): + assert not context.has_attribute(name) + attribute = context.get_attribute(name, default_value) + assert type(attribute) == type(default_value) + if isinstance(attribute, np.ndarray): + assert np.all(attribute == default_value) + else: + assert attribute == default_value + + check_attribute(node, "attribute_i32", np.int32(5)) + check_attribute(node, "attribute_i64", np.int64(5)) + check_attribute(node, "attribute_str", "abc") + check_attribute(node, "attribute_f32", np.float32(5)) + check_attribute(node, "attribute_f64", np.float64(5)) + check_attribute(node, "attribute_bool", np.bool(False)) + check_attribute(node, "attribute_type", onnx.TensorProto.FLOAT) + + check_attribute(node, "attribute_list_i32", np.array([4, 5, 6], dtype=np.int32)) + check_attribute(node, "attribute_list_i64", np.array([4, 5, 6], dtype=np.int64)) + check_attribute(node, "attribute_list_str", np.array(["d", "e", "f"], dtype=np.str)) + check_attribute(node, "attribute_list_f32", np.array([4, 5, 6], dtype=np.float)) + check_attribute(node, "attribute_list_f64", np.array([4, 5, 6], dtype=np.float64)) + check_attribute(node, "attribute_list_bool", np.array([True, False, True], dtype=np.bool)) + check_attribute(node, "attribute_list_type", np.array([onnx.TensorProto.INT32, + onnx.TensorProto.FLOAT])) + + a = node.get_input(0) + b = node.get_input(1) + add = ops.add(a, b) + return [add.output(0)] + + fe.add_extension(ConversionExtension("Add", custom_converter)) + input_model = fe.load(onnx_model_filename) + assert input_model + model = fe.convert(input_model) + assert model + assert invoked + + +def test_onnx_conversion_extension_cast_attributes(): + skip_if_onnx_frontend_is_disabled() + + # use specific (openvino.frontend.onnx) import here + from openvino.frontend.onnx import ConversionExtension + from openvino.frontend import NodeContext + from openvino.runtime import Type + import openvino.runtime.opset8 as ops + + # use the model without attributes + fe = fem.load_by_model(onnx_model_with_custom_attributes_filename) + assert fe + assert fe.get_name() == "onnx" + + invoked = False + + def custom_converter(node: NodeContext): + nonlocal invoked + invoked = True + + def check_attribute(context, name, expected_value, dtype): + attribute = context.get_attribute(name, dtype=dtype) + if isinstance(attribute, list): + assert type(attribute[0]) == dtype + else: + assert type(attribute) == dtype + assert attribute == expected_value + + check_attribute(node, "attribute_i32", 10, float) + check_attribute(node, "attribute_i64", 10, float) + check_attribute(node, "attribute_str", "string", np.str) + check_attribute(node, "attribute_f32", 10, int) + check_attribute(node, "attribute_f64", 10, int) + check_attribute(node, "attribute_bool", True, bool) + check_attribute(node, "attribute_type", Type.i32, Type) + + check_attribute(node, "attribute_list_i32", [1., 2., 3.], float) + check_attribute(node, "attribute_list_i64", [1., 2., 3.], float) + check_attribute(node, "attribute_list_str", ["a", "b", "c"], np.str) + check_attribute(node, "attribute_list_f32", [1, 2, 3], int) + check_attribute(node, "attribute_list_f64", [1, 2, 3], int) + check_attribute(node, "attribute_list_bool", [True, False, True], bool) + check_attribute(node, "attribute_list_type", [Type.i32, Type.f32], Type) + + a = node.get_input(0) + b = node.get_input(1) + add = ops.add(a, b) + return [add.output(0)] + + fe.add_extension(ConversionExtension("Add", custom_converter)) + input_model = fe.load(onnx_model_with_custom_attributes_filename) + assert input_model + model = fe.convert(input_model) + assert model + assert invoked + + +def test_onnx_conversion_extension_common(): + skip_if_onnx_frontend_is_disabled() + + # use common (openvino.frontend) import here + from openvino.frontend import ConversionExtension + from openvino.frontend import NodeContext + import openvino.runtime.opset8 as ops + + fe = fem.load_by_model(onnx_model_filename) + assert fe + assert fe.get_name() == "onnx" + + invoked = False + + def custom_converter(node: NodeContext): + nonlocal invoked + invoked = True + a = node.get_input(0) + b = node.get_input(1) + add = ops.add(a, b) + return [add.output(0)] + + fe.add_extension(ConversionExtension("Add", custom_converter)) + input_model = fe.load(onnx_model_filename) + assert input_model + model = fe.convert(input_model) + assert model + assert invoked + + +def test_onnx_conversion_extension(): + skip_if_onnx_frontend_is_disabled() + + # use specific (openvino.frontend.onnx) import here + from openvino.frontend.onnx import ConversionExtension + from openvino.frontend import NodeContext + import openvino.runtime.opset8 as ops + + fe = fem.load_by_model(onnx_model_filename) + assert fe + assert fe.get_name() == "onnx" + + invoked = False + + def custom_converter(node: NodeContext): + nonlocal invoked + invoked = True + a = node.get_input(0) + b = node.get_input(1) + add = ops.add(a, b) + return [add.output(0)] + + fe.add_extension(ConversionExtension("Add", custom_converter)) + input_model = fe.load(onnx_model_filename) + assert input_model + model = fe.convert(input_model) + assert model + assert invoked diff --git a/src/bindings/python/tests/test_frontend/test_frontend_onnx_editor.py b/src/bindings/python/tests/test_frontend/test_frontend_onnx_editor.py index ad8439242d5..f1e3b7ae96a 100644 --- a/src/bindings/python/tests/test_frontend/test_frontend_onnx_editor.py +++ b/src/bindings/python/tests/test_frontend/test_frontend_onnx_editor.py @@ -1367,12 +1367,14 @@ def test_set_tensor_value(): def test_not_supported_methods(): skip_if_onnx_frontend_is_disabled() + from openvino.frontend import GeneralFailure + fe = fem.load_by_framework(framework=ONNX_FRONTEND_NAME) model = fe.load("test_place_names.onnx") - with pytest.raises(Exception) as e: + with pytest.raises(GeneralFailure) as e: model.free_name_for_tensor("add_out") - assert "not applicable for ONNX model" in str(e) + assert "not applicable for ONNX model" in str(e.value) def test_set_name_for_tensor(): @@ -1389,18 +1391,18 @@ def test_set_name_for_tensor(): with pytest.raises(Exception) as e: model.set_name_for_tensor(tensor=tensor, new_name="") - assert "name must not be empty" in str(e) + assert "name must not be empty" in str(e.value) # ONNX model stores tensor info separately for inputs, outputs and between nodes tensors with pytest.raises(Exception) as e: model.set_name_for_tensor(tensor=tensor, new_name="in1") - assert "already used by another tensor" in str(e) + assert "already used by another tensor" in str(e.value) with pytest.raises(Exception) as e: model.set_name_for_tensor(tensor=tensor, new_name="out1") - assert "already used by another tensor" in str(e) + assert "already used by another tensor" in str(e.value) with pytest.raises(Exception) as e: model.set_name_for_tensor(tensor=tensor, new_name="sub_out") - assert "already used by another tensor" in str(e) + assert "already used by another tensor" in str(e.value) # actual rename model.set_name_for_tensor(tensor=tensor, new_name=new_name) @@ -1497,12 +1499,12 @@ def test_set_name_for_dimension(): with pytest.raises(Exception) as e: model.set_name_for_dimension(input1, 0, "") - assert "name must not be empty" in str(e) + assert "name must not be empty" in str(e.value) one_const = model.get_place_by_tensor_name(tensor_name="one_const") with pytest.raises(Exception) as e: model.set_name_for_dimension(one_const, 0, dim_name) - assert "ONNX initializer shape dimension cannot be dynamic." in str(e) + assert "ONNX initializer shape dimension cannot be dynamic." in str(e.value) def test_set_input_partial_shape_using_input_edge(): diff --git a/src/common/offline_transformations/include/extension/json_config.hpp b/src/common/offline_transformations/include/extension/json_config.hpp index 5dfb66abf58..e3f602e7b3d 100644 --- a/src/common/offline_transformations/include/extension/json_config.hpp +++ b/src/common/offline_transformations/include/extension/json_config.hpp @@ -22,7 +22,7 @@ public: protected: std::vector m_loaded_extensions; - std::vector, std::string>> m_target_extensions; + std::vector> m_target_extensions; }; } // namespace frontend } // namespace ov diff --git a/src/core/tests/frontend/onnx/CMakeLists.txt b/src/core/tests/frontend/onnx/CMakeLists.txt index 75967289a6e..3e7656a9462 100644 --- a/src/core/tests/frontend/onnx/CMakeLists.txt +++ b/src/core/tests/frontend/onnx/CMakeLists.txt @@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) add_executable(${TARGET_NAME} ${SRC}) -target_link_libraries(${TARGET_NAME} PRIVATE frontend_shared_test_classes) +target_link_libraries(${TARGET_NAME} PRIVATE frontend_shared_test_classes ov_onnx_frontend frontend_common) add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) diff --git a/src/core/tests/frontend/onnx/conversion.cpp b/src/core/tests/frontend/onnx/conversion.cpp new file mode 100644 index 00000000000..fae1a418720 --- /dev/null +++ b/src/core/tests/frontend/onnx/conversion.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "conversion_extension.hpp" +#include "onnx_utils.hpp" +#include "openvino/frontend/onnx/frontend.hpp" +#include "so_extension.hpp" + +using namespace ov::frontend; + +using ONNXConversionExtensionTest = FrontEndConversionExtensionTest; + +static const std::string translator_name = "Add"; + +class ONNXFrontendWrapper : public ov::frontend::onnx::FrontEnd { + void add_extension(const std::shared_ptr& extension) override { + ov::frontend::onnx::FrontEnd::add_extension(extension); + if (auto conv_ext = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_conversion_extensions.begin(), m_conversion_extensions.end(), conv_ext), + m_conversion_extensions.end()) + << "ConversionExtension is not registered."; + // TODO: check that operator is actually registered in ONNX FE + // EXPECT_NE(m_op_translators.find(conv_ext->get_op_type()), m_op_translators.end()) + // << conv_ext->get_op_type() << " translator is not registered."; + } else if (auto telemetry = std::dynamic_pointer_cast(extension)) { + EXPECT_EQ(m_extensions.telemetry, telemetry) << "TelemetryExtension is not registered."; + } else if (auto transformation = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_transformation_extensions.begin(), m_transformation_extensions.end(), transformation), + m_transformation_extensions.end()) + << "DecoderTransformationExtension is not registered."; + } else if (auto so_ext = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_other_extensions.begin(), m_other_extensions.end(), so_ext), m_other_extensions.end()) + << "SOExtension is not registered."; + } + } +}; + +static ConversionExtensionFEParam getTestData() { + ConversionExtensionFEParam res; + res.m_frontEndName = ONNX_FE; + res.m_modelsPath = std::string(TEST_ONNX_MODELS_DIRNAME); + res.m_modelName = "controlflow/loop_2d_add.onnx"; + res.m_translatorName = translator_name; + res.m_frontend = std::make_shared(); + return res; +} + +INSTANTIATE_TEST_SUITE_P(ONNXConversionExtensionTest, + FrontEndConversionExtensionTest, + ::testing::Values(getTestData()), + FrontEndConversionExtensionTest::getTestCaseName); diff --git a/src/core/tests/frontend/paddle/CMakeLists.txt b/src/core/tests/frontend/paddle/CMakeLists.txt index 0699d75fe29..7100957de64 100644 --- a/src/core/tests/frontend/paddle/CMakeLists.txt +++ b/src/core/tests/frontend/paddle/CMakeLists.txt @@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) add_executable(${TARGET_NAME} ${SRC}) -target_link_libraries(${TARGET_NAME} PRIVATE frontend_shared_test_classes) +target_link_libraries(${TARGET_NAME} PRIVATE frontend_shared_test_classes ov_paddle_frontend openvino::runtime) add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) diff --git a/src/core/tests/frontend/paddle/conversion.cpp b/src/core/tests/frontend/paddle/conversion.cpp new file mode 100644 index 00000000000..9f422b4fbbb --- /dev/null +++ b/src/core/tests/frontend/paddle/conversion.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "conversion_extension.hpp" +#include "openvino/frontend/exception.hpp" +#include "openvino/frontend/paddle/frontend.hpp" +#include "paddle_utils.hpp" +#include "so_extension.hpp" + +using namespace ov::frontend; + +using PDPDConversionExtensionTest = FrontEndConversionExtensionTest; + +static const std::string translator_name = "relu"; + +class PaddleFrontendWrapper : public ov::frontend::paddle::FrontEnd { + void add_extension(const std::shared_ptr& extension) override { + ov::frontend::paddle::FrontEnd::add_extension(extension); + + if (auto conv_ext = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_conversion_extensions.begin(), m_conversion_extensions.end(), conv_ext), + m_conversion_extensions.end()) + << "ConversionExtension is not registered."; + EXPECT_NE(m_op_translators.find(conv_ext->get_op_type()), m_op_translators.end()) + << conv_ext->get_op_type() << " translator is not registered."; + } else if (auto telemetry = std::dynamic_pointer_cast(extension)) { + EXPECT_EQ(m_telemetry, telemetry) << "TelemetryExtension is not registered."; + } else if (auto transformation = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_transformation_extensions.begin(), m_transformation_extensions.end(), transformation), + m_transformation_extensions.end()) + << "DecoderTransformationExtension is not registered."; + } else if (auto so_ext = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_extensions.begin(), m_extensions.end(), so_ext), m_extensions.end()) + << "SOExtension is not registered."; + } + } +}; + +static ConversionExtensionFEParam getTestData() { + ConversionExtensionFEParam res; + res.m_frontEndName = PADDLE_FE; + res.m_modelsPath = std::string(TEST_PADDLE_MODELS_DIRNAME); + res.m_modelName = "relu/relu.pdmodel"; + res.m_translatorName = translator_name; + res.m_frontend = std::make_shared(); + return res; +} + +INSTANTIATE_TEST_SUITE_P(PDPDConversionExtensionTest, + FrontEndConversionExtensionTest, + ::testing::Values(getTestData()), + FrontEndConversionExtensionTest::getTestCaseName); diff --git a/src/core/tests/frontend/shared/include/conversion_extension.hpp b/src/core/tests/frontend/shared/include/conversion_extension.hpp new file mode 100644 index 00000000000..722e84a6cd9 --- /dev/null +++ b/src/core/tests/frontend/shared/include/conversion_extension.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include +#include + +struct ConversionExtensionFEParam { + std::string m_frontEndName; + std::string m_modelsPath; + std::string m_modelName; + std::string m_translatorName; + std::shared_ptr m_frontend; +}; + +class FrontEndConversionExtensionTest : public ::testing::TestWithParam { +public: + ConversionExtensionFEParam m_param; + ov::frontend::FrontEndManager m_fem; + + static std::string getTestCaseName(const testing::TestParamInfo& obj); + + void SetUp() override; + +protected: + void initParamTest(); +}; diff --git a/src/core/tests/frontend/shared/include/json_config.hpp b/src/core/tests/frontend/shared/include/json_config.hpp index 209477fccfa..4380bca1e61 100644 --- a/src/core/tests/frontend/shared/include/json_config.hpp +++ b/src/core/tests/frontend/shared/include/json_config.hpp @@ -19,7 +19,7 @@ public: return m_loaded_extensions; }; - std::vector, std::string>> get_target_extensions() { + std::vector> get_target_extensions() { return m_target_extensions; } }; diff --git a/src/core/tests/frontend/shared/src/conversion.cpp b/src/core/tests/frontend/shared/src/conversion.cpp new file mode 100644 index 00000000000..82049b29c3a --- /dev/null +++ b/src/core/tests/frontend/shared/src/conversion.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include + +#include "conversion_extension.hpp" +#include "utils.hpp" + +using namespace ov::frontend; + +std::string FrontEndConversionExtensionTest::getTestCaseName( + const testing::TestParamInfo& obj) { + std::string res = obj.param.m_frontEndName + "_" + obj.param.m_modelName; + return FrontEndTestUtils::fileToTestName(res); +} + +void FrontEndConversionExtensionTest::SetUp() { + FrontEndTestUtils::setupTestEnv(); + initParamTest(); +} + +void FrontEndConversionExtensionTest::initParamTest() { + m_param = GetParam(); + m_param.m_modelName = FrontEndTestUtils::make_model_path(m_param.m_modelsPath + m_param.m_modelName); +} + +inline std::string get_lib_path(const std::string& lib_name) { + return ov::util::make_plugin_library_name(ov::util::get_ov_lib_path(), lib_name + IE_BUILD_POSTFIX); +} + +/////////////////////////////////////////////////////////////////// + +TEST_P(FrontEndConversionExtensionTest, TestConversionExtension) { + auto frontend = m_param.m_frontend; + bool invoked = false; + if (m_param.m_frontEndName == "paddle") { + frontend->add_extension(std::make_shared( + m_param.m_translatorName, + [&](const NodeContext& node) -> std::map { + auto relu = std::make_shared(node.get_input("X")); + invoked = true; + return {{"Out", {relu}}}; + })); + } else if (m_param.m_frontEndName == "tf") { + frontend->add_extension( + std::make_shared(m_param.m_translatorName, + [&](const ov::frontend::NodeContext& node) -> ov::OutputVector { + invoked = true; + auto ng_input = node.get_input(0); + auto res = std::make_shared(ng_input); + return {res}; + })); + } else if (m_param.m_frontEndName == "onnx") { + frontend->add_extension( + std::make_shared(m_param.m_translatorName, + [&](const ov::frontend::NodeContext& node) -> ov::OutputVector { + invoked = true; + auto a = node.get_input(0); + auto b = node.get_input(1); + auto res = std::make_shared(a, b); + return {res}; + })); + } + std::shared_ptr input_model; + ASSERT_NO_THROW(input_model = frontend->load(m_param.m_modelName)); + ASSERT_NE(input_model, nullptr); + std::shared_ptr model; + ASSERT_NO_THROW(model = frontend->convert(input_model)); + ASSERT_NE(model, nullptr); + EXPECT_EQ(invoked, true); +} + +TEST_P(FrontEndConversionExtensionTest, TestConversionExtensionViaSO) { + auto frontend = m_param.m_frontend; + const auto& lib_path = get_lib_path("test_builtin_extensions_1"); + frontend->add_extension(lib_path); + std::shared_ptr input_model; + ASSERT_NO_THROW(input_model = frontend->load(m_param.m_modelName)); + ASSERT_NE(input_model, nullptr); + std::shared_ptr model; + ASSERT_NO_THROW(model = frontend->convert(input_model)); + ASSERT_NE(model, nullptr); +} diff --git a/src/core/tests/frontend/shared/src/json_config.cpp b/src/core/tests/frontend/shared/src/json_config.cpp index c708cce75ce..64f5844e781 100644 --- a/src/core/tests/frontend/shared/src/json_config.cpp +++ b/src/core/tests/frontend/shared/src/json_config.cpp @@ -142,7 +142,8 @@ TEST_P(FrontEndJsonConfigTest, testAddJsonConfigExtension) { auto loaded_ext = json_config_ext->get_loaded_extensions(); auto target_ext = json_config_ext->get_target_extensions(); - EXPECT_EQ(loaded_ext.size(), 3); + // the number of Loaded extensions can be more than the number of actually used ones. + EXPECT_EQ(loaded_ext.size(), 8); EXPECT_EQ(target_ext.size(), 3); for (const auto& target : target_ext) { diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt b/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt index 988f054d621..94d5a958221 100644 --- a/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt @@ -4,14 +4,31 @@ set(TARGET_NAME "test_builtin_extensions_1") -file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) -file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +file(GLOB LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) + +set(DEPENDENCIES nlohmann_json openvino::runtime::dev offline_transformations) +set(DEFINITIONS) + +if (ENABLE_OV_ONNX_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::onnx) + list(APPEND DEFINITIONS ENABLE_OV_ONNX_FRONTEND) +endif() + +if (ENABLE_OV_TF_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::tensorflow) + list(APPEND DEFINITIONS ENABLE_OV_TF_FRONTEND) +endif() + +if (ENABLE_OV_PADDLE_FRONTEND) + list(APPEND DEPENDENCIES openvino::frontend::paddle) + list(APPEND DEFINITIONS ENABLE_OV_PADDLE_FRONTEND) +endif() # Create library add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS}) - -target_link_libraries(${TARGET_NAME} PUBLIC nlohmann_json inference_engine_transformations frontend_common - offline_transformations) +target_compile_definitions(${TARGET_NAME} PRIVATE ${DEFINITIONS}) +target_link_libraries(${TARGET_NAME} PRIVATE ${DEPENDENCIES}) add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp b/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp index 6fe88b8cf5a..905cb7d18fe 100644 --- a/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp @@ -3,7 +3,35 @@ // #include +#include + +#ifdef ENABLE_OV_ONNX_FRONTEND +# include +# define ONNX_EXT std::make_shared("NewCustomOp_3", CustomTranslatorONNX), +#else +# define ONNX_EXT +#endif + +#ifdef ENABLE_OV_PADDLE_FRONTEND +# include +# define PADDLE_EXT \ + std::make_shared("NewCustomOp_4", CustomTranslatorPaddle), +#else +# define PADDLE_EXT +#endif + +#ifdef ENABLE_OV_TF_FRONTEND +# include +# define TF_EXT \ + std::make_shared("NewCustomOp_5", CustomTranslatorTensorflow) +#else +# define TF_EXT +#endif #include "test_extension.hpp" -OPENVINO_CREATE_EXTENSIONS(std::vector({std::make_shared()})); +OPENVINO_CREATE_EXTENSIONS(std::vector( + {std::make_shared(), + std::make_shared("NewCustomOp_1", CustomTranslatorCommon_1), + std::make_shared("NewCustomOp_2", CustomTranslatorCommon_2), + ONNX_EXT PADDLE_EXT TF_EXT})); diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp index db6f182595e..363860a9245 100644 --- a/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp @@ -12,3 +12,23 @@ bool TestExtension1::transform(const std::shared_ptr& function, const } TestExtension1::TestExtension1() : ov::frontend::JsonTransformationExtension("buildin_extensions_1::TestExtension1") {} + +ov::OutputVector CustomTranslatorCommon_1(const ov::frontend::NodeContext& node) { + return ov::OutputVector(); +} + +std::map CustomTranslatorCommon_2(const ov::frontend::NodeContext& node) { + return std::map(); +} + +ov::OutputVector CustomTranslatorTensorflow(const ov::frontend::NodeContext& node) { + return ov::OutputVector(); +} + +ov::OutputVector CustomTranslatorONNX(const ov::frontend::NodeContext& node) { + return ov::OutputVector(); +} + +std::map CustomTranslatorPaddle(const ov::frontend::NodeContext& node) { + return std::map(); +} diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp index 686a4924178..3bb978a7e36 100644 --- a/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp @@ -6,6 +6,7 @@ #include #include +#include class TestExtension1 : public ov::frontend::JsonTransformationExtension { public: @@ -13,3 +14,13 @@ public: bool transform(const std::shared_ptr& function, const std::string& config) const override; }; + +ov::OutputVector CustomTranslatorCommon_1(const ov::frontend::NodeContext& node); + +std::map CustomTranslatorCommon_2(const ov::frontend::NodeContext& node); + +ov::OutputVector CustomTranslatorTensorflow(const ov::frontend::NodeContext& node); + +ov::OutputVector CustomTranslatorONNX(const ov::frontend::NodeContext& node); + +std::map CustomTranslatorPaddle(const ov::frontend::NodeContext& node); diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt b/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt index 309ced18a90..5610f48a6aa 100644 --- a/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt +++ b/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt @@ -10,7 +10,7 @@ file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) # Create library add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS}) -target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json inference_engine_transformations frontend_common +target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json openvino::runtime::dev offline_transformations) add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) diff --git a/src/core/tests/frontend/tensorflow/CMakeLists.txt b/src/core/tests/frontend/tensorflow/CMakeLists.txt index 1b8e5e7985b..0e46f242e10 100644 --- a/src/core/tests/frontend/tensorflow/CMakeLists.txt +++ b/src/core/tests/frontend/tensorflow/CMakeLists.txt @@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) add_executable(${TARGET_NAME} ${SRC}) -target_link_libraries(${TARGET_NAME} PRIVATE frontend_shared_test_classes ov_tensorflow_frontend) +target_link_libraries(${TARGET_NAME} PRIVATE frontend_shared_test_classes ov_tensorflow_frontend openvino::runtime) add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) diff --git a/src/core/tests/frontend/tensorflow/conversion.cpp b/src/core/tests/frontend/tensorflow/conversion.cpp new file mode 100644 index 00000000000..ef719eb612b --- /dev/null +++ b/src/core/tests/frontend/tensorflow/conversion.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "conversion_extension.hpp" +#include "openvino/frontend/extension/telemetry.hpp" +#include "openvino/frontend/tensorflow/frontend.hpp" +#include "so_extension.hpp" +#include "tf_utils.hpp" + +using namespace ov::frontend; + +using TFConversionExtensionTest = FrontEndConversionExtensionTest; + +static const std::string translator_name = "Relu"; + +class TensorflowFrontendWrapper : public ov::frontend::tensorflow::FrontEnd { + void add_extension(const std::shared_ptr& extension) override { + ov::frontend::tensorflow::FrontEnd::add_extension(extension); + + if (auto conv_ext = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_conversion_extensions.begin(), m_conversion_extensions.end(), conv_ext), + m_conversion_extensions.end()) + << "ConversionExtension is not registered."; + EXPECT_NE(m_op_translators.find(conv_ext->get_op_type()), m_op_translators.end()) + << conv_ext->get_op_type() << " translator is not registered."; + } else if (auto telemetry = std::dynamic_pointer_cast(extension)) { + EXPECT_EQ(m_telemetry, telemetry) << "TelemetryExtension is not registered."; + } else if (auto transformation = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_transformation_extensions.begin(), m_transformation_extensions.end(), transformation), + m_transformation_extensions.end()) + << "DecoderTransformationExtension is not registered."; + } else if (auto so_ext = std::dynamic_pointer_cast(extension)) { + EXPECT_NE(std::find(m_extensions.begin(), m_extensions.end(), so_ext), m_extensions.end()) + << "SOExtension is not registered."; + } + } +}; + +static ConversionExtensionFEParam getTestData() { + ConversionExtensionFEParam res; + res.m_frontEndName = TF_FE; + res.m_modelsPath = std::string(TEST_TENSORFLOW_MODELS_DIRNAME); + res.m_modelName = "2in_2out/2in_2out.pb"; + res.m_translatorName = translator_name; + res.m_frontend = std::make_shared(); + return res; +} + +INSTANTIATE_TEST_SUITE_P(TFConversionExtensionTest, + FrontEndConversionExtensionTest, + ::testing::Values(getTestData()), + FrontEndConversionExtensionTest::getTestCaseName); diff --git a/src/frontends/common/include/openvino/frontend/extension/conversion.hpp b/src/frontends/common/include/openvino/frontend/extension/conversion.hpp new file mode 100644 index 00000000000..e3acf304372 --- /dev/null +++ b/src/frontends/common/include/openvino/frontend/extension/conversion.hpp @@ -0,0 +1,56 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/extension.hpp" +#include "openvino/frontend/node_context.hpp" +#include "openvino/frontend/visibility.hpp" + +namespace ov { +namespace frontend { + +class FRONTEND_API ConversionExtensionBase : public ov::Extension { +public: + using Ptr = std::shared_ptr; + explicit ConversionExtensionBase(const std::string& op_type) : m_op_type(op_type) {} + + const std::string& get_op_type() const { + return m_op_type; + } + + ~ConversionExtensionBase() override = 0; + +private: + std::string m_op_type; +}; + +class FRONTEND_API ConversionExtension : public ConversionExtensionBase { +public: + using Ptr = std::shared_ptr; + ConversionExtension(const std::string& op_type, const CreatorFunction& converter) + : ConversionExtensionBase(op_type), + m_converter(converter) {} + + ConversionExtension(const std::string& op_type, const CreatorFunctionNamed& converter) + : ConversionExtensionBase(op_type), + m_converter_named(converter) {} + + const CreatorFunction& get_converter() const { + return m_converter; + }; + + const CreatorFunctionNamed& get_converter_named() const { + return m_converter_named; + }; + + ~ConversionExtension() override = default; + +private: + CreatorFunction m_converter; + CreatorFunctionNamed m_converter_named; +}; + +} // namespace frontend +} // namespace ov diff --git a/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp b/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp index aeca843b235..c72872813de 100644 --- a/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp +++ b/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp @@ -24,6 +24,7 @@ namespace frontend { /// calling corresponding ctor. class FRONTEND_API DecoderTransformationExtension : public ov::Extension { public: + using Ptr = std::shared_ptr; DecoderTransformationExtension() = default; /// \brief Create a custom functional pass where code of the pass is implemented as a function. diff --git a/src/frontends/common/include/common/extension_holder.hpp b/src/frontends/common/include/openvino/frontend/extension/extension_holder.hpp similarity index 100% rename from src/frontends/common/include/common/extension_holder.hpp rename to src/frontends/common/include/openvino/frontend/extension/extension_holder.hpp diff --git a/src/frontends/common/include/openvino/frontend/extension/telemetry.hpp b/src/frontends/common/include/openvino/frontend/extension/telemetry.hpp index 270d94b49d3..65b057b603b 100644 --- a/src/frontends/common/include/openvino/frontend/extension/telemetry.hpp +++ b/src/frontends/common/include/openvino/frontend/extension/telemetry.hpp @@ -20,6 +20,7 @@ namespace frontend { /// \brief Provides callback to report telemetry information back to Python code class FRONTEND_API TelemetryExtension : public ov::Extension { public: + using Ptr = std::shared_ptr; using error_callback = std::function; using event_callback = std::function< void(const std::string& category, const std::string& action, const std::string& label, int value)>; diff --git a/src/frontends/common/include/openvino/frontend/manager.hpp b/src/frontends/common/include/openvino/frontend/manager.hpp index 1d222cbaf7e..d5885e16595 100644 --- a/src/frontends/common/include/openvino/frontend/manager.hpp +++ b/src/frontends/common/include/openvino/frontend/manager.hpp @@ -22,7 +22,8 @@ using FrontEndFactory = std::function; /// frontends This is a main frontend entry point for client applications class FRONTEND_API FrontEndManager final { public: - /*/ \brief Default constructor. Searches and loads of available frontends*/ FrontEndManager(); + /// \brief Default constructor. Searches and loads of available frontends + FrontEndManager(); /// \brief Default move constructor FrontEndManager(FrontEndManager&&) noexcept; diff --git a/src/frontends/common/include/openvino/frontend/node_context.hpp b/src/frontends/common/include/openvino/frontend/node_context.hpp new file mode 100644 index 00000000000..7c3fa984b8a --- /dev/null +++ b/src/frontends/common/include/openvino/frontend/node_context.hpp @@ -0,0 +1,101 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/extension.hpp" +#include "openvino/frontend/exception.hpp" +#include "openvino/frontend/visibility.hpp" +#include "openvino/pass/graph_rewrite.hpp" +#include "openvino/pass/manager.hpp" +#include "openvino/pass/pass.hpp" + +namespace ov { +namespace frontend { + +class FRONTEND_API NodeContext { +public: + explicit NodeContext(const std::string& op_type) : m_op_type(op_type) {} + virtual ~NodeContext() = default; + + /// \brief Returns a number of inputs + virtual size_t get_input_size() const { + FRONT_END_NOT_IMPLEMENTED(get_input_size); + }; + + /// \brief Returns a number of inputs + virtual size_t get_input_size(const std::string& port_name) const { + FRONT_END_NOT_IMPLEMENTED(get_input_size); + } + + /// \brief Returns exactly one input with a given idx; throws if there is no inputs or + /// there are more than one input + virtual Output get_input(int idx) const { + FRONT_END_NOT_IMPLEMENTED(get_input); + } + + /// \brief Returns exactly one input with a given name and idx; throws if there is no inputs or + /// there are more than one input + virtual Output get_input(const std::string& name, int idx) const { + FRONT_END_NOT_IMPLEMENTED(get_input); + } + + /// \brief Returns exactly one input with a given name; throws if there is no inputs or + /// there are more than one input + virtual Output get_input(const std::string& name) const { + FRONT_END_NOT_IMPLEMENTED(get_input); + } + + virtual const std::string& get_op_type() const { + return m_op_type; + } + + /// \brief Returns node attribute by name. + template + T get_attribute(const std::string& name) const { + auto any = get_attribute_as_any(name); + FRONT_END_GENERAL_CHECK(!any.empty(), "Attribute with name '", name, "' does not exist"); + + // sometimes we can't unambiguously recognize types in protobuf, e.g. + // int we can interpret as int or as enum inherited from int, so + // we have to apply additional rules based on the type (T) passed from the user. + auto res = apply_additional_conversion_rules(any, typeid(T)); + return res.as(); + } + + /// \brief Returns node attribute by name. Returns 'def' value if attribute does not exist + template + T get_attribute(const std::string& name, const T& def) const { + auto any = get_attribute_as_any(name); + + // sometimes we can't unambiguously recognize types in protobuf, e.g. + // int we can interpret as int or as enum inherited from int, so + // we have to apply additional rules based on the type (T) passed from the user. + auto res = apply_additional_conversion_rules(any, typeid(T)); + if (!res.empty()) { + return res.as(); + } + return def; + } + + /// \brief Check if an attribute of a given name exist + bool has_attribute(const std::string& name) const { + return !get_attribute_as_any(name).empty(); + } + + /// \brief Returns node attribute by name as ov::Any. + virtual ov::Any get_attribute_as_any(const std::string& name) const = 0; + +private: + virtual ov::Any apply_additional_conversion_rules(const ov::Any& data, const std::type_info& type_info) const { + return data; + } + std::string m_op_type; +}; + +using CreatorFunction = std::function; +using CreatorFunctionNamed = std::function(const NodeContext&)>; + +} // namespace frontend +} // namespace ov diff --git a/src/frontends/common/src/extension/conversion.cpp b/src/frontends/common/src/extension/conversion.cpp new file mode 100644 index 00000000000..1e58d7e3d4d --- /dev/null +++ b/src/frontends/common/src/extension/conversion.cpp @@ -0,0 +1,8 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "openvino/frontend/extension/conversion.hpp" + +using namespace ov::frontend; +ConversionExtensionBase::~ConversionExtensionBase() = default; diff --git a/src/frontends/common/src/extension/decoder_transformation.cpp b/src/frontends/common/src/extension/decoder_transformation.cpp index 971ba44fa6e..f174fb76fbe 100644 --- a/src/frontends/common/src/extension/decoder_transformation.cpp +++ b/src/frontends/common/src/extension/decoder_transformation.cpp @@ -43,5 +43,7 @@ DecoderTransformationExtension::DecoderTransformationExtension( }) {} void DecoderTransformationExtension::register_pass(ov::pass::Manager& manager) const { - m_registration(manager); + if (m_registration) { + m_registration(manager); + } } diff --git a/src/frontends/onnx/frontend/include/onnx_import/core/node.hpp b/src/frontends/onnx/frontend/include/onnx_import/core/node.hpp index dcbfb943638..3d193e928e2 100644 --- a/src/frontends/onnx/frontend/include/onnx_import/core/node.hpp +++ b/src/frontends/onnx/frontend/include/onnx_import/core/node.hpp @@ -191,4 +191,4 @@ inline std::ostream& operator<<(std::ostream& outs, const Node& node) { } // namespace onnx_import -} // namespace ngraph +} // namespace ngraph \ No newline at end of file diff --git a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/extension/conversion.hpp b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/extension/conversion.hpp new file mode 100644 index 00000000000..86ee7f67b3a --- /dev/null +++ b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/extension/conversion.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/node_context.hpp" +#include "openvino/frontend/onnx/node_context.hpp" +#include "openvino/frontend/onnx/visibility.hpp" + +namespace ov { +namespace frontend { +namespace onnx { +class ONNX_FRONTEND_API ConversionExtension : public ConversionExtensionBase { +public: + using Ptr = std::shared_ptr; + ConversionExtension() = delete; + + ConversionExtension(const std::string& op_type, const ov::frontend::CreatorFunction& converter) + : ConversionExtensionBase(op_type), + m_converter(converter) {} + + const ov::frontend::CreatorFunction& get_converter() const { + return m_converter; + } + +private: + ov::frontend::CreatorFunction m_converter; +}; +} // namespace onnx +} // namespace frontend +} // namespace ov diff --git a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp index 006d3d878fc..af20f12f2a1 100644 --- a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp +++ b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp @@ -4,21 +4,12 @@ #pragma once -#include -#include - -#ifdef OPENVINO_STATIC_LIBRARY -# define ONNX_FRONTEND_API -# define ONNX_FRONTEND_C_API -#else -# ifdef ov_onnx_frontend_EXPORTS -# define ONNX_FRONTEND_API OPENVINO_CORE_EXPORTS -# define ONNX_FRONTEND_C_API OPENVINO_EXTERN_C OPENVINO_CORE_EXPORTS -# else -# define ONNX_FRONTEND_API OPENVINO_CORE_IMPORTS -# define ONNX_FRONTEND_C_API OPENVINO_EXTERN_C OPENVINO_CORE_IMPORTS -# endif // ov_onnx_frontend_EXPORTS -#endif // OPENVINO_STATIC_LIBRARY +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "openvino/frontend/extension/extension_holder.hpp" +#include "openvino/frontend/extension/telemetry.hpp" +#include "openvino/frontend/frontend.hpp" +#include "openvino/frontend/onnx/visibility.hpp" namespace ov { namespace frontend { @@ -26,6 +17,8 @@ namespace onnx { class ONNX_FRONTEND_API FrontEnd : public ov::frontend::FrontEnd { public: + ~FrontEnd() override; + using Ptr = std::shared_ptr; std::shared_ptr convert(const InputModel::Ptr& model) const override; void convert(const std::shared_ptr& partially_converted) const override; std::shared_ptr decode(const InputModel::Ptr& model) const override; @@ -36,7 +29,12 @@ public: protected: InputModel::Ptr load_impl(const std::vector& params) const override; -private: + // m_extensions should be the first member here, + // m_extensions can contain SO Extension (holder for other Extensions), + // so it should be released last. + std::vector m_other_extensions; + std::vector m_transformation_extensions; + std::vector m_conversion_extensions; ExtensionHolder m_extensions; }; diff --git a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/node_context.hpp b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/node_context.hpp new file mode 100644 index 00000000000..d1dbc426ff7 --- /dev/null +++ b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/node_context.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/node_context.hpp" +#include "openvino/frontend/onnx/visibility.hpp" + +namespace ngraph { +namespace onnx_import { +class Node; +} +} // namespace ngraph + +namespace ov { +namespace frontend { +namespace onnx { + +class ONNX_FRONTEND_API NodeContext : public ov::frontend::NodeContext { +public: + using Ptr = std::shared_ptr; + explicit NodeContext(const ngraph::onnx_import::Node& context); + size_t get_input_size() const override; + + Output get_input(int port_idx) const override; + + ov::Any get_attribute_as_any(const std::string& name) const override; + +protected: + const ngraph::onnx_import::Node& m_context; + OutputVector m_inputs; + +private: + ov::Any apply_additional_conversion_rules(const ov::Any& data, const std::type_info& type_info) const override; +}; +using CreatorFunction = std::function; +} // namespace onnx +} // namespace frontend +} // namespace ov \ No newline at end of file diff --git a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/visibility.hpp b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/visibility.hpp new file mode 100644 index 00000000000..8224cff3359 --- /dev/null +++ b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/visibility.hpp @@ -0,0 +1,20 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/frontend/exception.hpp" + +#ifdef OPENVINO_STATIC_LIBRARY +# define ONNX_FRONTEND_API +# define ONNX_FRONTEND_C_API +#else +# ifdef ov_onnx_frontend_EXPORTS +# define ONNX_FRONTEND_API OPENVINO_CORE_EXPORTS +# define ONNX_FRONTEND_C_API OPENVINO_EXTERN_C OPENVINO_CORE_EXPORTS +# else +# define ONNX_FRONTEND_API OPENVINO_CORE_IMPORTS +# define ONNX_FRONTEND_C_API OPENVINO_EXTERN_C OPENVINO_CORE_IMPORTS +# endif // ov_onnx_frontend_EXPORTS +#endif // OPENVINO_STATIC_LIBRARY diff --git a/src/frontends/onnx/frontend/src/core/attribute.cpp b/src/frontends/onnx/frontend/src/core/attribute.cpp index 6366c6c136b..b4734e9b998 100644 --- a/src/frontends/onnx/frontend/src/core/attribute.cpp +++ b/src/frontends/onnx/frontend/src/core/attribute.cpp @@ -25,6 +25,33 @@ Subgraph Attribute::get_subgraph(const Graph* parent_graph) const { return Subgraph{model_proto, parent_graph}; } +ov::Any Attribute::get_any() const { + switch (get_type()) { + case Type::float_point: + return get_float(); + case Type::integer: + return get_integer(); + case Type::string: + return get_string(); + case Type::float_point_array: + return get_float_array(); + case Type::integer_array: + return get_integer_array(); + case Type::string_array: + return get_string_array(); + // TODO: support attributes. + case Type::sparse_tensor_array: + case Type::graph_array: + case Type::tensor_array: + case Type::tensor: + case Type::graph: + case Type::sparse_tensor: + throw ov::Exception(get_name() + " attribute is not supported."); + default: + throw ov::Exception("Unknown type of attribute " + get_name()); + } +} + } // namespace onnx_import } // namespace ngraph diff --git a/src/frontends/onnx/frontend/src/core/attribute.hpp b/src/frontends/onnx/frontend/src/core/attribute.hpp index 3236c5b9d90..792bf0328e1 100644 --- a/src/frontends/onnx/frontend/src/core/attribute.hpp +++ b/src/frontends/onnx/frontend/src/core/attribute.hpp @@ -327,6 +327,8 @@ public: return detail::attribute::get_value(*m_attribute_proto); } + ov::Any get_any() const; + private: const ONNX_NAMESPACE::AttributeProto* m_attribute_proto; }; diff --git a/src/frontends/onnx/frontend/src/core/graph.hpp b/src/frontends/onnx/frontend/src/core/graph.hpp index 41d3fc1cb3c..8734f873122 100644 --- a/src/frontends/onnx/frontend/src/core/graph.hpp +++ b/src/frontends/onnx/frontend/src/core/graph.hpp @@ -10,12 +10,12 @@ #include #include -#include "common/extension_holder.hpp" #include "core/graph_cache.hpp" #include "core/model.hpp" #include "ngraph/function.hpp" #include "ngraph/op/parameter.hpp" #include "onnx_import/core/operator_set.hpp" +#include "openvino/frontend/extension/extension_holder.hpp" namespace ngraph { namespace onnx_import { diff --git a/src/frontends/onnx/frontend/src/core/node.cpp b/src/frontends/onnx/frontend/src/core/node.cpp index fce426010ed..024c8f0c922 100644 --- a/src/frontends/onnx/frontend/src/core/node.cpp +++ b/src/frontends/onnx/frontend/src/core/node.cpp @@ -162,6 +162,11 @@ Subgraph Node::Impl::get_attribute_value(const std::string& name) const { return get_subgraph_from_attribute(name); } +template <> +ov::Any Node::get_attribute_value(const std::string& name) const { + return get_attribute(name).get_any(); +} + OutputVector Node::Impl::get_ng_inputs() const { OutputVector result; for (const auto& name : m_node_proto->input()) { diff --git a/src/frontends/onnx/frontend/src/editor.hpp b/src/frontends/onnx/frontend/src/editor.hpp index e2acc65629f..6c9426b3732 100644 --- a/src/frontends/onnx/frontend/src/editor.hpp +++ b/src/frontends/onnx/frontend/src/editor.hpp @@ -8,13 +8,13 @@ #include #include -#include "common/extension_holder.hpp" #include "editor_types.hpp" #include "ngraph/function.hpp" #include "ngraph/op/constant.hpp" #include "ngraph/partial_shape.hpp" #include "ngraph/type/element_type.hpp" #include "onnx_import/onnx_importer_visibility.hpp" +#include "openvino/frontend/extension/extension_holder.hpp" #include "openvino/frontend/extension/progress_reporter_extension.hpp" #include "openvino/frontend/extension/telemetry.hpp" diff --git a/src/frontends/onnx/frontend/src/frontend.cpp b/src/frontends/onnx/frontend/src/frontend.cpp index 358f4b8add2..feb2c13fd29 100644 --- a/src/frontends/onnx/frontend/src/frontend.cpp +++ b/src/frontends/onnx/frontend/src/frontend.cpp @@ -5,13 +5,19 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include "onnx_common/onnx_model_validator.hpp" +#include "openvino/frontend/extension/telemetry.hpp" +#include "ops_bridge.hpp" +#include "so_extension.hpp" using namespace ov; using namespace ov::frontend::onnx; @@ -63,6 +69,19 @@ InputModel::Ptr FrontEnd::load_impl(const std::vector& variants) const std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const { auto model_onnx = std::dynamic_pointer_cast(model); NGRAPH_CHECK(model_onnx != nullptr, "Invalid input model"); + + if (!m_transformation_extensions.empty()) { + auto function = decode(model); + + ov::pass::Manager manager; + for (const auto& transformation : m_transformation_extensions) { + transformation->register_pass(manager); + } + manager.run_passes(function); + convert(function); + return function; + } + return model_onnx->convert(); } @@ -135,7 +154,42 @@ bool FrontEnd::supported_impl(const std::vector& variants) const { void FrontEnd::add_extension(const std::shared_ptr& extension) { if (auto telemetry = std::dynamic_pointer_cast(extension)) { m_extensions.telemetry = telemetry; + } else if (auto transformation = std::dynamic_pointer_cast(extension)) { + m_transformation_extensions.push_back(transformation); + } else if (const auto& so_ext = std::dynamic_pointer_cast(extension)) { + add_extension(so_ext->extension()); + m_other_extensions.push_back(so_ext); + } else if (auto common_conv_ext = std::dynamic_pointer_cast(extension)) { + m_conversion_extensions.push_back(common_conv_ext); + for (int i = 1; i < ngraph::onnx_import::OperatorsBridge::LATEST_SUPPORTED_ONNX_OPSET_VERSION; ++i) + ngraph::onnx_import::register_operator(common_conv_ext->get_op_type(), + i, + "", + [=](const ngraph::onnx_import::Node& context) -> OutputVector { + return common_conv_ext->get_converter()(NodeContext(context)); + }); + } else if (const auto onnx_conv_ext = std::dynamic_pointer_cast(extension)) { + m_conversion_extensions.push_back(onnx_conv_ext); + for (int i = 1; i < ngraph::onnx_import::OperatorsBridge::LATEST_SUPPORTED_ONNX_OPSET_VERSION; ++i) + ngraph::onnx_import::register_operator(onnx_conv_ext->get_op_type(), + i, + "", + [=](const ngraph::onnx_import::Node& context) -> OutputVector { + return onnx_conv_ext->get_converter()(NodeContext(context)); + }); } else if (auto progress_reporter = std::dynamic_pointer_cast(extension)) { m_extensions.progress_reporter = progress_reporter; } } + +FrontEnd::~FrontEnd() { + // We should remove new added operations manually due to deadlock in python GIL (pybind11/gil.h) + // It looks like the issue occurs when we use static c++ objects to store wrapped objects, + // in our case OperatorsBridge is static (singleton), and it stores ConvertionExtension. + for (const auto& conv_ext : m_conversion_extensions) { + for (int i = 1; i < ngraph::onnx_import::OperatorsBridge::LATEST_SUPPORTED_ONNX_OPSET_VERSION; ++i) { + ngraph::onnx_import::unregister_operator(conv_ext->get_op_type(), i, ""); + } + } + ngraph::onnx_import::OperatorsBridge::load_initial_state(); +} diff --git a/src/frontends/onnx/frontend/src/input_model.hpp b/src/frontends/onnx/frontend/src/input_model.hpp index 75dc8fec8cf..57e8963b7dd 100644 --- a/src/frontends/onnx/frontend/src/input_model.hpp +++ b/src/frontends/onnx/frontend/src/input_model.hpp @@ -8,7 +8,7 @@ #include #include -#include "common/extension_holder.hpp" +#include "openvino/frontend/extension/extension_holder.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/onnx/frontend/src/node_context.cpp b/src/frontends/onnx/frontend/src/node_context.cpp new file mode 100644 index 00000000000..cdd975c2807 --- /dev/null +++ b/src/frontends/onnx/frontend/src/node_context.cpp @@ -0,0 +1,44 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + +ov::frontend::onnx::NodeContext::NodeContext(const ngraph::onnx_import::Node& context) + : ov::frontend::NodeContext(context.op_type()), + m_context(context), + m_inputs(context.get_ng_inputs()) {} + +ov::Output ov::frontend::onnx::NodeContext::get_input(int port_idx) const { + return m_inputs.at(port_idx); +} + +ov::Any ov::frontend::onnx::NodeContext::get_attribute_as_any(const std::string& name) const { + try { + return m_context.get_attribute_value(name); + } catch (ngraph::onnx_import::error::node::UnknownAttribute& e) { + return ov::Any(); + } +} + +size_t ov::frontend::onnx::NodeContext::get_input_size() const { + return m_inputs.size(); +} + +ov::Any ov::frontend::onnx::NodeContext::apply_additional_conversion_rules(const ov::Any& data, + const std::type_info& type_info) const { + if (data.is() && type_info == typeid(ov::element::Type)) { + return ngraph::onnx_import::common::get_ngraph_element_type(data.as()); + } else if (data.is>() && type_info == typeid(std::vector)) { + const auto& casted = data.as>(); + std::vector types(casted.size()); + for (size_t i = 0; i < casted.size(); ++i) { + types[i] = ngraph::onnx_import::common::get_ngraph_element_type(casted[i]); + } + return types; + } + // no conversion rules found + return data; +} diff --git a/src/frontends/onnx/frontend/src/ops_bridge.cpp b/src/frontends/onnx/frontend/src/ops_bridge.cpp index cbdd74b2000..81cf5493900 100644 --- a/src/frontends/onnx/frontend/src/ops_bridge.cpp +++ b/src/frontends/onnx/frontend/src/ops_bridge.cpp @@ -281,6 +281,10 @@ static const char* const MICROSOFT_DOMAIN = "com.microsoft"; m_map[domain_][name_].emplace(ver_, std::bind(op::set_##ver_::fn_, std::placeholders::_1)) OperatorsBridge::OperatorsBridge() { + _load_initial_state(); +} + +void OperatorsBridge::_load_initial_state() { REGISTER_OPERATOR("Abs", 1, abs); REGISTER_OPERATOR("Acos", 1, acos); REGISTER_OPERATOR("Acosh", 1, acosh); diff --git a/src/frontends/onnx/frontend/src/ops_bridge.hpp b/src/frontends/onnx/frontend/src/ops_bridge.hpp index 62eab794147..6ac1f4a99fe 100644 --- a/src/frontends/onnx/frontend/src/ops_bridge.hpp +++ b/src/frontends/onnx/frontend/src/ops_bridge.hpp @@ -61,6 +61,10 @@ public: return instance()._is_operator_registered(name, version, domain); } + static void load_initial_state() { + return instance()._load_initial_state(); + } + private: // Registered operators structure // { @@ -91,6 +95,7 @@ private: bool _is_operator_registered(const std::string& name, std::int64_t version, const std::string& domain); + void _load_initial_state(); std::mutex lock; }; diff --git a/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp b/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp index 2efefa42cc1..9134d4ca1cf 100644 --- a/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp +++ b/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp @@ -7,8 +7,8 @@ #include #include -#include "common/extension_holder.hpp" #include "ngraph/function.hpp" +#include "openvino/frontend/extension/extension_holder.hpp" namespace ONNX_NAMESPACE { class ModelProto; diff --git a/src/frontends/paddle/CMakeLists.txt b/src/frontends/paddle/CMakeLists.txt index 1b8ff91a7c7..cc529d2f502 100644 --- a/src/frontends/paddle/CMakeLists.txt +++ b/src/frontends/paddle/CMakeLists.txt @@ -7,4 +7,4 @@ ov_add_frontend(NAME paddle SHUTDOWN_PROTOBUF PROTOBUF_LITE FILEDESCRIPTION "FrontEnd to load and convert PaddlePaddle file format" - LINK_LIBRARIES openvino::runtime::dev) + LINK_LIBRARIES openvino::util openvino::runtime::dev) diff --git a/src/frontends/paddle/include/openvino/frontend/paddle/decoder.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/decoder.hpp new file mode 100644 index 00000000000..952eb944986 --- /dev/null +++ b/src/frontends/paddle/include/openvino/frontend/paddle/decoder.hpp @@ -0,0 +1,56 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once +#include "openvino/core/any.hpp" +#include "openvino/frontend/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" + +namespace ov { +namespace frontend { +namespace paddle { +using InPortName = std::string; +using OutPortName = std::string; +using TensorName = std::string; +using NamedOutputs = std::map; +using NamedInputs = std::map; + +class DecoderBase { +public: + /// \brief Get attribute value by name and requested type + /// + /// \param name Attribute name + /// \return Shared pointer to appropriate value if it exists, 'nullptr' otherwise + virtual ov::Any get_attribute(const std::string& name) const = 0; + + /// \brief Applies additional conversion rules to the data based on type_info + /// + /// \param data Data + /// \param type_info Attribute type information + /// \return Shared pointer to appropriate value if it exists, 'nullptr' otherwise + virtual ov::Any convert_attribute(const ov::Any& data, const std::type_info& type_info) const = 0; + + /// \brief Get the output names + virtual std::vector get_output_names() const = 0; + + /// \brief Get the output size + virtual size_t get_output_size() const = 0; + + /// \brief Get output port type + /// + /// Current API assumes that output port has only one output type. + /// If decoder supports multiple types for specified port, it shall throw general + /// exception + /// + /// \param port_name Port name for the node + /// + /// \return Type of specified output port + virtual ov::element::Type get_out_port_type(const std::string& port_name) const = 0; + + /// \brief Get the type of the operation + virtual std::string get_op_type() const = 0; +}; +} // namespace paddle +} // namespace frontend +} // namespace ov \ No newline at end of file diff --git a/src/frontends/paddle/src/exceptions.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp similarity index 77% rename from src/frontends/paddle/src/exceptions.hpp rename to src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp index d2b56f69917..ced4289d4dc 100644 --- a/src/frontends/paddle/src/exceptions.hpp +++ b/src/frontends/paddle/include/openvino/frontend/paddle/exception.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include "openvino/frontend/exception.hpp" namespace ov { namespace frontend { @@ -14,13 +14,11 @@ class NodeContext; class OpValidationFailure : public ov::frontend::OpValidationFailure { public: - OpValidationFailure(const CheckLocInfo& check_loc_info, - const paddle::NodeContext& node, - const std::string& explanation) + OpValidationFailure(const CheckLocInfo& check_loc_info, const NodeContext& node, const std::string& explanation) : ov::frontend::OpValidationFailure(check_loc_info, get_error_msg_prefix_paddle(node), explanation) {} private: - static std::string get_error_msg_prefix_paddle(const paddle::NodeContext& node); + static std::string get_error_msg_prefix_paddle(const NodeContext& node); }; } // namespace paddle } // namespace frontend diff --git a/src/frontends/paddle/include/openvino/frontend/paddle/extension/conversion.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/extension/conversion.hpp new file mode 100644 index 00000000000..92014538779 --- /dev/null +++ b/src/frontends/paddle/include/openvino/frontend/paddle/extension/conversion.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/frontend.hpp" +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" + +namespace ov { +namespace frontend { +namespace paddle { + +class PADDLE_API ConversionExtension : public ConversionExtensionBase { +public: + using Ptr = std::shared_ptr; + + ConversionExtension() = delete; + + ConversionExtension(const std::string& op_type, const ov::frontend::CreatorFunctionNamed& converter) + : ConversionExtensionBase(op_type), + m_converter(converter) {} + + const ov::frontend::CreatorFunctionNamed& get_converter() const { + return m_converter; + } + +private: + ov::frontend::CreatorFunctionNamed m_converter; +}; + +} // namespace paddle +} // namespace frontend +} // namespace ov \ No newline at end of file diff --git a/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp index ddffe5bf2d3..b0d73094229 100644 --- a/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp +++ b/src/frontends/paddle/include/openvino/frontend/paddle/frontend.hpp @@ -4,12 +4,14 @@ #pragma once -#include -#include -#include -#include - -#include "exceptions.hpp" +#include "openvino/core/extension.hpp" +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "openvino/frontend/extension/telemetry.hpp" +#include "openvino/frontend/frontend.hpp" +#include "openvino/frontend/input_model.hpp" +#include "openvino/frontend/paddle/exception.hpp" +#include "openvino/frontend/paddle/extension/conversion.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/frontend/paddle/visibility.hpp" namespace ov { @@ -20,7 +22,8 @@ class OpPlace; class PADDLE_API FrontEnd : public ov::frontend::FrontEnd { public: - FrontEnd() = default; + using Ptr = std::shared_ptr; + FrontEnd(); /// \brief Completely convert the remaining, not converted part of a function. /// \param partiallyConverted partially converted OV Model @@ -68,13 +71,21 @@ protected: /// \return InputModel::Ptr InputModel::Ptr load_impl(const std::vector& params) const override; -private: +protected: static std::shared_ptr convert_each_node( const std::shared_ptr& frontend_model, std::function(const std::map>&, const std::shared_ptr&)> func); - std::shared_ptr m_telemetry; - std::vector> m_transformation_extensions; + + // m_extensions should be the first member here, + // m_extensions can contain SO Extension (holder for other Extensions), + // so it should be released last. + std::vector m_extensions; + TelemetryExtension::Ptr m_telemetry; + std::vector m_transformation_extensions; + std::vector m_conversion_extensions; + + TranslatorDictionaryType m_op_translators; }; } // namespace paddle diff --git a/src/frontends/paddle/include/openvino/frontend/paddle/node_context.hpp b/src/frontends/paddle/include/openvino/frontend/paddle/node_context.hpp new file mode 100644 index 00000000000..f7f6784c58b --- /dev/null +++ b/src/frontends/paddle/include/openvino/frontend/paddle/node_context.hpp @@ -0,0 +1,104 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once +#include "ngraph/compatibility.hpp" +#include "openvino/core/any.hpp" +#include "openvino/frontend/paddle/decoder.hpp" +#include "openvino/frontend/paddle/exception.hpp" +#include "openvino/frontend/paddle/visibility.hpp" + +namespace ov { +namespace frontend { +namespace paddle { +using InPortName = std::string; +using OutPortName = std::string; +using TensorName = std::string; +using NamedOutputs = std::map; +using NamedInputs = std::map; + +/// Keep necessary data for a single node in the original FW graph to facilitate +/// conversion process in the rules code. +class NodeContext : public ov::frontend::NodeContext { +public: + using Ptr = std::shared_ptr; + NodeContext(const DecoderBase& _decoder, const NamedInputs& _name_map) + : ov::frontend::NodeContext(_decoder.get_op_type()), + decoder(_decoder), + name_map(_name_map) {} + + /// Detects if there is at least one input attached with a given name + bool has_input(const std::string& name) const { + auto found = name_map.find(name); + if (found != name_map.end()) + return !found->second.empty(); + return false; + } + + /// Returns exactly one input with a given name; throws if there is no inputs or + /// there are more than one input + Output get_input(const std::string& name) const override { + FRONT_END_GENERAL_CHECK(name_map.at(name).size() == 1); + return name_map.at(name).at(0); + } + + /// Returns all inputs with a given name + OutputVector get_ng_inputs(const std::string& name) const { + return name_map.at(name); + } + + Output get_input(const std::string& name, int idx) const override { + return name_map.at(name).at(idx); + } + + size_t get_input_size(const std::string& name) const override { + return name_map.at(name).size(); + } + + std::vector get_output_names() const { + return decoder.get_output_names(); + } + + ov::element::Type get_out_port_type(const std::string& port_name) const { + return decoder.get_out_port_type(port_name); + } + + NamedOutputs default_single_output_mapping(const std::shared_ptr& node, + const std::vector& required_pdpd_out_names) const; + + ov::Any get_attribute_as_any(const std::string& name) const override { + auto res = decoder.get_attribute(name); + return res; + } + +private: + ov::Any apply_additional_conversion_rules(const ov::Any& any, const std::type_info& type_info) const override { + auto res = decoder.convert_attribute(any, type_info); + return res; + } + + const DecoderBase& decoder; + const NamedInputs& name_map; +}; + +inline NamedOutputs NodeContext::default_single_output_mapping( + const std::shared_ptr& node, + const std::vector& required_pdpd_out_names) const { + NamedOutputs named_outputs; + const auto& outputs = node->outputs(); + const auto& pdpd_op_output_names = this->get_output_names(); + FRONT_END_GENERAL_CHECK(outputs.size() == 1, "OV node must have exactly one output"); + for (const auto& pdpd_name : pdpd_op_output_names) { + if (std::find(required_pdpd_out_names.begin(), required_pdpd_out_names.end(), pdpd_name) != + required_pdpd_out_names.end()) + named_outputs[pdpd_name] = {outputs[0]}; + } + return named_outputs; +} + +using CreatorFunction = std::function; +using TranslatorDictionaryType = std::map; +} // namespace paddle +} // namespace frontend +} // namespace ov diff --git a/src/frontends/paddle/src/decoder.cpp b/src/frontends/paddle/src/decoder_proto.cpp similarity index 73% rename from src/frontends/paddle/src/decoder.cpp rename to src/frontends/paddle/src/decoder_proto.cpp index fd2c3116c2e..6239ac8ca72 100644 --- a/src/frontends/paddle/src/decoder.cpp +++ b/src/frontends/paddle/src/decoder_proto.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "decoder.hpp" +#include "decoder_proto.hpp" #include #include @@ -21,7 +21,7 @@ namespace paddle { using namespace ::paddle::framework; -std::map<::paddle::framework::proto::VarType_Type, ov::element::Type> TYPE_MAP{ +std::map TYPE_MAP{ {proto::VarType_Type::VarType_Type_BOOL, ov::element::boolean}, {proto::VarType_Type::VarType_Type_INT16, ov::element::i16}, {proto::VarType_Type::VarType_Type_INT32, ov::element::i32}, @@ -33,34 +33,55 @@ std::map<::paddle::framework::proto::VarType_Type, ov::element::Type> TYPE_MAP{ {proto::VarType_Type::VarType_Type_INT8, ov::element::i8}, {proto::VarType_Type::VarType_Type_BF16, ov::element::bf16}}; -ov::Any DecoderProto::get_attribute(const std::string& name, const std::type_info& type_info) const { +ov::Any DecoderProto::get_attribute(const std::string& name) const { auto attrs = decode_attribute_helper(name); if (attrs.empty()) { return {}; } - if (type_info == typeid(std::string)) { - return attrs[0].s(); - } else if (type_info == typeid(int64_t)) { - return attrs[0].l(); - } else if (type_info == typeid(std::vector)) { - return std::vector(attrs[0].longs().begin(), attrs[0].longs().end()); - } else if (type_info == typeid(int32_t)) { + switch (attrs[0].type()) { + case proto::AttrType::INT: return attrs[0].i(); - } else if (type_info == typeid(std::vector)) { + case proto::AttrType::INTS: return std::vector(attrs[0].ints().begin(), attrs[0].ints().end()); - } else if (type_info == typeid(float)) { + case proto::AttrType::FLOAT: return attrs[0].f(); - } else if (type_info == typeid(std::vector)) { + case proto::AttrType::FLOATS: return std::vector(attrs[0].floats().begin(), attrs[0].floats().end()); - } else if (type_info == typeid(ov::element::Type)) { - return TYPE_MAP[static_cast<::paddle::framework::proto::VarType_Type>(attrs[0].i())]; - } else if (type_info == typeid(bool)) { + case proto::AttrType::STRING: + return attrs[0].s(); + case proto::AttrType::STRINGS: + return std::vector(attrs[0].strings().begin(), attrs[0].strings().end()); + case proto::AttrType::LONG: + return attrs[0].l(); + case proto::AttrType::LONGS: + return std::vector(attrs[0].longs().begin(), attrs[0].longs().end()); + case proto::AttrType::BOOLEAN: return attrs[0].b(); + case proto::AttrType::BOOLEANS: + return std::vector(attrs[0].bools().begin(), attrs[0].bools().end()); + case proto::AttrType::BLOCK: + return attrs[0].block_idx(); + case proto::AttrType::BLOCKS: + return std::vector(attrs[0].blocks_idx().begin(), attrs[0].blocks_idx().end()); + default: + FRONT_END_GENERAL_CHECK(false, "Conversion from PaddlePaddle to OpenVINO data type is not supported."); } +} - // Type is not supported by decoder - return {}; +ov::Any DecoderProto::convert_attribute(const Any& data, const std::type_info& type_info) const { + if (data.is() && type_info == typeid(ov::element::Type)) { + return TYPE_MAP.at(static_cast(data.as())); + } else if (data.is>() && type_info == typeid(std::vector)) { + const auto& casted = data.as>(); + std::vector types(casted.size()); + for (size_t i = 0; i < casted.size(); ++i) { + types[i] = TYPE_MAP.at(static_cast(casted[i])); + } + return types; + } + // no conversion rules found. + return data; } std::vector DecoderProto::get_output_names() const { @@ -94,7 +115,7 @@ ov::element::Type DecoderProto::get_out_port_type(const std::string& port_name) for (const auto& out_port : op_place->get_output_ports().at(port_name)) { output_types.push_back(out_port->get_target_tensor_paddle()->get_element_type()); } - FRONT_END_GENERAL_CHECK(output_types.size() > 0, "Port has no tensors connected."); + FRONT_END_GENERAL_CHECK(!output_types.empty(), "Port has no tensors connected."); FRONT_END_GENERAL_CHECK(std::equal(output_types.begin() + 1, output_types.end(), output_types.begin()), "Port has tensors with different types connected."); return output_types[0]; diff --git a/src/frontends/paddle/src/decoder.hpp b/src/frontends/paddle/src/decoder_proto.hpp similarity index 87% rename from src/frontends/paddle/src/decoder.hpp rename to src/frontends/paddle/src/decoder_proto.hpp index 9e011d868bb..524c01e0744 100644 --- a/src/frontends/paddle/src/decoder.hpp +++ b/src/frontends/paddle/src/decoder_proto.hpp @@ -9,14 +9,14 @@ #include #include #include -#include #include #include #include #include "framework.pb.h" -#include "node_context.hpp" +#include "openvino/core/any.hpp" #include "openvino/frontend/paddle/frontend.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "place.hpp" namespace ov { @@ -28,7 +28,9 @@ class DecoderProto : public paddle::DecoderBase { public: explicit DecoderProto(const std::shared_ptr& op) : op_place(op) {} - ov::Any get_attribute(const std::string& name, const std::type_info& type_info) const override; + ov::Any get_attribute(const std::string& name) const override; + + ov::Any convert_attribute(const ov::Any& data, const std::type_info& type_info) const override; std::vector get_output_names() const override; diff --git a/src/frontends/paddle/src/exceptions.cpp b/src/frontends/paddle/src/exception.cpp similarity index 80% rename from src/frontends/paddle/src/exceptions.cpp rename to src/frontends/paddle/src/exception.cpp index df0a304c6e3..0c6b5735254 100644 --- a/src/frontends/paddle/src/exceptions.cpp +++ b/src/frontends/paddle/src/exception.cpp @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "exceptions.hpp" +#include "openvino/frontend/paddle/exception.hpp" -#include "node_context.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/paddle/src/frontend.cpp b/src/frontends/paddle/src/frontend.cpp index d14ea1e5425..6ed877c5f1d 100644 --- a/src/frontends/paddle/src/frontend.cpp +++ b/src/frontends/paddle/src/frontend.cpp @@ -9,15 +9,17 @@ #include #include -#include "decoder.hpp" +#include "decoder_proto.hpp" #include "framework.pb.h" #include "input_model.hpp" -#include "node_context.hpp" #include "op_table.hpp" +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset7.hpp" #include "paddle_fw_node.hpp" #include "paddle_utils.hpp" #include "place.hpp" +#include "so_extension.hpp" using namespace ov::opset7; using namespace ov; @@ -132,6 +134,8 @@ std::istream* variant_to_stream_ptr(const ov::Any& variant, std::ifstream& ext_s } } // namespace +FrontEnd::FrontEnd() : m_op_translators(paddle::get_supported_ops()) {} + std::shared_ptr FrontEnd::convert_each_node( const std::shared_ptr& frontend_model, std::function(const std::map>&, @@ -292,11 +296,10 @@ std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const return function; } - std::map CREATORS_MAP = paddle::get_supported_ops(); auto f = convert_each_node( paddle_model, [&](const std::map>& nodes_dict, const std::shared_ptr& op_place) { - return paddle::make_ng_node(nodes_dict, op_place, CREATORS_MAP); + return paddle::make_ng_node(nodes_dict, op_place, m_op_translators); }); return f; } @@ -304,8 +307,7 @@ std::shared_ptr FrontEnd::convert(const InputModel::Ptr& model) const void FrontEnd::convert(const std::shared_ptr& partiallyConverted) const { for (const auto& node : partiallyConverted->get_ordered_ops()) { if (ov::is_type(node)) { - paddle::normalize_framework_node(std::dynamic_pointer_cast(node), - paddle::get_supported_ops()); + paddle::normalize_framework_node(std::dynamic_pointer_cast(node), m_op_translators); } } for (const auto& result : partiallyConverted->get_results()) { @@ -329,13 +331,12 @@ std::shared_ptr FrontEnd::convert_partially(const InputModel::Ptr& mo return function; } - std::map CREATORS_MAP = paddle::get_supported_ops(); auto f = convert_each_node( paddle_model, [&](const std::map>& nodes_dict, const std::shared_ptr& op_place) { paddle::NamedOutputs named_outputs; try { - named_outputs = paddle::make_ng_node(nodes_dict, op_place, CREATORS_MAP); + named_outputs = paddle::make_ng_node(nodes_dict, op_place, m_op_translators); } catch (const OpConversionFailure&) { named_outputs = paddle::make_framework_node(nodes_dict, op_place); } @@ -348,7 +349,6 @@ std::shared_ptr FrontEnd::decode(const InputModel::Ptr& model) const auto paddle_model = std::dynamic_pointer_cast(model); FRONT_END_GENERAL_CHECK(paddle_model != nullptr, "Invalid input model"); - std::map CREATORS_MAP = paddle::get_supported_ops(); auto f = convert_each_node(paddle_model, paddle::make_framework_node); return f; } @@ -362,6 +362,19 @@ void FrontEnd::add_extension(const std::shared_ptr& extension) { m_telemetry = telemetry; } else if (auto transformation = std::dynamic_pointer_cast(extension)) { m_transformation_extensions.push_back(transformation); + } else if (const auto& so_ext = std::dynamic_pointer_cast(extension)) { + add_extension(so_ext->extension()); + m_extensions.push_back(so_ext); + } else if (auto common_conv_ext = std::dynamic_pointer_cast(extension)) { + m_conversion_extensions.push_back(common_conv_ext); + m_op_translators[common_conv_ext->get_op_type()] = [=](const NodeContext& context) { + return common_conv_ext->get_converter_named()(context); + }; + } else if (const auto& paddle_conv_ext = std::dynamic_pointer_cast(extension)) { + m_conversion_extensions.push_back(paddle_conv_ext); + m_op_translators[paddle_conv_ext->get_op_type()] = [=](const NodeContext& context) { + return paddle_conv_ext->get_converter()(context); + }; } } diff --git a/src/frontends/paddle/src/input_model.cpp b/src/frontends/paddle/src/input_model.cpp index e32fe36fafc..7b47b07ae8c 100644 --- a/src/frontends/paddle/src/input_model.cpp +++ b/src/frontends/paddle/src/input_model.cpp @@ -7,10 +7,10 @@ #include #include -#include "decoder.hpp" +#include "decoder_proto.hpp" #include "framework.pb.h" #include "input_model.hpp" -#include "node_context.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset7.hpp" #include "paddle_utils.hpp" #include "place.hpp" diff --git a/src/frontends/paddle/src/input_model.hpp b/src/frontends/paddle/src/input_model.hpp index 86a1767340d..3691b14a0bc 100644 --- a/src/frontends/paddle/src/input_model.hpp +++ b/src/frontends/paddle/src/input_model.hpp @@ -4,8 +4,8 @@ #pragma once -#include -#include +#include "openvino/frontend/extension/telemetry.hpp" +#include "openvino/frontend/paddle/frontend.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/paddle/src/op/argmax.cpp b/src/frontends/paddle/src/op/argmax.cpp index 93ec3693e87..be3742f9875 100644 --- a/src/frontends/paddle/src/op/argmax.cpp +++ b/src/frontends/paddle/src/op/argmax.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs argmax(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); bool flatten = node.get_attribute("flatten"); const element::Type& index_element_type = element::i64; const Output k = ov::opset6::Constant::create(ov::element::i64, {}, {1}); diff --git a/src/frontends/paddle/src/op/assign_value.cpp b/src/frontends/paddle/src/op/assign_value.cpp index 56a3f5bd142..f630556847b 100644 --- a/src/frontends/paddle/src/op/assign_value.cpp +++ b/src/frontends/paddle/src/op/assign_value.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/paddle/src/op/batch_norm.cpp b/src/frontends/paddle/src/op/batch_norm.cpp index 67f1df96fc0..f55485f4b2d 100644 --- a/src/frontends/paddle/src/op/batch_norm.cpp +++ b/src/frontends/paddle/src/op/batch_norm.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,11 +10,11 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs batch_norm(const NodeContext& node) { - auto data = node.get_ng_input("X"); - auto gamma = node.get_ng_input("Scale"); - auto beta = node.get_ng_input("Bias"); - auto mean = node.get_ng_input("Mean"); - auto variance = node.get_ng_input("Variance"); + auto data = node.get_input("X"); + auto gamma = node.get_input("Scale"); + auto beta = node.get_input("Bias"); + auto mean = node.get_input("Mean"); + auto variance = node.get_input("Variance"); auto data_layout = node.get_attribute("data_layout"); PADDLE_OP_CHECK(node, (data_layout == "NCHW" || data_layout == "NHWC"), "Not supported input data layout!"); diff --git a/src/frontends/paddle/src/op/cast.cpp b/src/frontends/paddle/src/op/cast.cpp index fd90238575c..4f17dc5b752 100644 --- a/src/frontends/paddle/src/op/cast.cpp +++ b/src/frontends/paddle/src/op/cast.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs cast(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto out_dtype = node.get_attribute("out_dtype"); return node.default_single_output_mapping({std::make_shared(data, out_dtype)}, {"Out"}); diff --git a/src/frontends/paddle/src/op/clip.cpp b/src/frontends/paddle/src/op/clip.cpp index 96b308d7f2d..8661411feca 100644 --- a/src/frontends/paddle/src/op/clip.cpp +++ b/src/frontends/paddle/src/op/clip.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs clip(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto min = node.get_attribute("min"); auto max = node.get_attribute("max"); PADDLE_OP_CHECK(node, max >= min, "clip: max value must greater than min value!"); diff --git a/src/frontends/paddle/src/op/concat.cpp b/src/frontends/paddle/src/op/concat.cpp index ec6cb86126c..f12e5a246b4 100644 --- a/src/frontends/paddle/src/op/concat.cpp +++ b/src/frontends/paddle/src/op/concat.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { diff --git a/src/frontends/paddle/src/op/conv2d_transpose.cpp b/src/frontends/paddle/src/op/conv2d_transpose.cpp index 9e3a9982d7d..d1aae974926 100644 --- a/src/frontends/paddle/src/op/conv2d_transpose.cpp +++ b/src/frontends/paddle/src/op/conv2d_transpose.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "conv2d_utils.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { diff --git a/src/frontends/paddle/src/op/conv2d_utils.cpp b/src/frontends/paddle/src/op/conv2d_utils.cpp index 03431ac9851..d3ba72ef5bd 100644 --- a/src/frontends/paddle/src/op/conv2d_utils.cpp +++ b/src/frontends/paddle/src/op/conv2d_utils.cpp @@ -4,7 +4,7 @@ #include "conv2d_utils.hpp" -#include "node_context.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" #include "transformations/utils/utils.hpp" @@ -58,7 +58,7 @@ std::pair get_pads(const NodeContext& node, cons } std::pair get_pads(const NodeContext& node) { - const auto data_rank = node.get_ng_input("Input").get_partial_shape().rank(); + const auto data_rank = node.get_input("Input").get_partial_shape().rank(); PADDLE_OP_CHECK(node, data_rank.get_length() > 2, "the rank of conv input must > 2"); const auto data_spatial_dims = data_rank.get_length() - 2; diff --git a/src/frontends/paddle/src/op/conv2d_utils.hpp b/src/frontends/paddle/src/op/conv2d_utils.hpp index ba2ec88bcc7..52986172e1a 100644 --- a/src/frontends/paddle/src/op/conv2d_utils.hpp +++ b/src/frontends/paddle/src/op/conv2d_utils.hpp @@ -3,8 +3,8 @@ // #pragma once -#include "node_context.hpp" #include "openvino/core/coordinate_diff.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { @@ -16,8 +16,8 @@ std::shared_ptr get_reshaped_filter(const Output& filters, int32_t g template NamedOutputs conv2d_base(const NodeContext& node) { - auto data = node.get_ng_input("Input"); - auto filters = node.get_ng_input("Filter"); + auto data = node.get_input("Input"); + auto filters = node.get_input("Filter"); const auto strides = node.get_attribute>("strides"); const auto dilations = node.get_attribute>("dilations"); diff --git a/src/frontends/paddle/src/op/cumsum.cpp b/src/frontends/paddle/src/op/cumsum.cpp index f33756f739e..b34633cff23 100644 --- a/src/frontends/paddle/src/op/cumsum.cpp +++ b/src/frontends/paddle/src/op/cumsum.cpp @@ -2,16 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs cumsum(const NodeContext& node) { - const auto x = node.get_ng_input("X"); + const auto x = node.get_input("X"); const auto axis = node.get_attribute("axis", -1); const auto flatten = node.get_attribute("flatten", false); const auto reverse = node.get_attribute("reverse", false); diff --git a/src/frontends/paddle/src/op/deformable_conv.cpp b/src/frontends/paddle/src/op/deformable_conv.cpp index 9f83f786f07..8fb51de5f02 100644 --- a/src/frontends/paddle/src/op/deformable_conv.cpp +++ b/src/frontends/paddle/src/op/deformable_conv.cpp @@ -1,9 +1,8 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - #include "conv2d_utils.hpp" +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset8.hpp" namespace ov { @@ -11,9 +10,9 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs deformable_conv(const NodeContext& node) { - auto input = node.get_ng_input("Input"); - auto filter = node.get_ng_input("Filter"); - auto offset = node.get_ng_input("Offset"); + auto input = node.get_input("Input"); + auto filter = node.get_input("Filter"); + auto offset = node.get_input("Offset"); auto strides = node.get_attribute>("strides"); auto dilations = node.get_attribute>("dilations"); @@ -28,8 +27,8 @@ NamedOutputs deformable_conv(const NodeContext& node) { const ov::op::PadType auto_pad{ov::op::PadType::EXPLICIT}; std::shared_ptr output_node; - if (node.has_ng_input("Mask")) { - auto mask = node.get_ng_input("Mask"); + if (node.has_input("Mask")) { + auto mask = node.get_input("Mask"); output_node = std::make_shared(input, offset, diff --git a/src/frontends/paddle/src/op/dropout.cpp b/src/frontends/paddle/src/op/dropout.cpp index b76adebb7ed..d2abc93c62a 100644 --- a/src/frontends/paddle/src/op/dropout.cpp +++ b/src/frontends/paddle/src/op/dropout.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs dropout(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto dropout_implementation = node.get_attribute("dropout_implementation"); PADDLE_OP_CHECK(node, (dropout_implementation == "downgrade_in_infer" || dropout_implementation == "upscale_in_train"), diff --git a/src/frontends/paddle/src/op/elementwise_ops.cpp b/src/frontends/paddle/src/op/elementwise_ops.cpp index 3e1da07d6a6..23e163696e4 100644 --- a/src/frontends/paddle/src/op/elementwise_ops.cpp +++ b/src/frontends/paddle/src/op/elementwise_ops.cpp @@ -3,9 +3,9 @@ // #include -#include #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { @@ -13,8 +13,8 @@ namespace paddle { namespace op { template NamedOutputs elementwise_ops(const NodeContext& node) { - auto x = node.get_ng_input("X"); - auto y = node.get_ng_input("Y"); + auto x = node.get_input("X"); + auto y = node.get_input("Y"); auto axis = node.get_attribute("axis"); diff --git a/src/frontends/paddle/src/op/embedding.cpp b/src/frontends/paddle/src/op/embedding.cpp index 7c5e502c636..05c7705d44b 100644 --- a/src/frontends/paddle/src/op/embedding.cpp +++ b/src/frontends/paddle/src/op/embedding.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset8.hpp" namespace ov { @@ -14,8 +13,8 @@ using namespace opset8; using namespace element; NamedOutputs embedding(const NodeContext& node) { - auto data_ids = node.get_ng_input("Ids"); - auto data_w = node.get_ng_input("W"); + auto data_ids = node.get_input("Ids"); + auto data_w = node.get_input("W"); auto padding_idx = node.get_attribute("padding_idx"); diff --git a/src/frontends/paddle/src/op/exp.cpp b/src/frontends/paddle/src/op/exp.cpp index dd107d48f2e..5afa4fdd910 100644 --- a/src/frontends/paddle/src/op/exp.cpp +++ b/src/frontends/paddle/src/op/exp.cpp @@ -2,16 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs exp(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); return node.default_single_output_mapping({std::make_shared(data)}, {"Out"}); } } // namespace op diff --git a/src/frontends/paddle/src/op/expand_v2.cpp b/src/frontends/paddle/src/op/expand_v2.cpp index fca2ca27d7d..98df519978d 100644 --- a/src/frontends/paddle/src/op/expand_v2.cpp +++ b/src/frontends/paddle/src/op/expand_v2.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,11 +11,11 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs expand_v2(const NodeContext& node) { - auto x = node.get_ng_input("X"); + auto x = node.get_input("X"); Output shape_expected_node; - if (node.has_ng_input("Shape")) { - shape_expected_node = node.get_ng_input("Shape"); - } else if (node.has_ng_input("expand_shapes_tensor")) { + if (node.has_input("Shape")) { + shape_expected_node = node.get_input("Shape"); + } else if (node.has_input("expand_shapes_tensor")) { auto inputs = node.get_ng_inputs("expand_shapes_tensor"); ov::NodeVector node_vec; for (auto& input : inputs) { @@ -25,7 +25,7 @@ NamedOutputs expand_v2(const NodeContext& node) { shape_expected_node = std::make_shared(node_vec, 0); } else { std::vector shape_expected; - if (node.has_attribute>("shape")) { + if (node.has_attribute("shape")) { shape_expected = node.get_attribute>("shape"); } else { throw std::runtime_error("expand: has no shape attribute"); diff --git a/src/frontends/paddle/src/op/fill_any_like.cpp b/src/frontends/paddle/src/op/fill_any_like.cpp index c15b2fe9608..19b1814af3a 100644 --- a/src/frontends/paddle/src/op/fill_any_like.cpp +++ b/src/frontends/paddle/src/op/fill_any_like.cpp @@ -2,16 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs fill_any_like(const NodeContext& node) { - const auto x = node.get_ng_input("X"); + const auto x = node.get_input("X"); auto dtype = node.get_attribute("dtype", element::undefined); const auto value = node.get_attribute("value"); if (dtype == element::undefined) { diff --git a/src/frontends/paddle/src/op/fill_constant.cpp b/src/frontends/paddle/src/op/fill_constant.cpp index 4141cf77755..61acfdcb87d 100644 --- a/src/frontends/paddle/src/op/fill_constant.cpp +++ b/src/frontends/paddle/src/op/fill_constant.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -15,8 +14,8 @@ NamedOutputs fill_constant(const NodeContext& node) { auto dtype = node.get_attribute("dtype"); Output value_node; Output shape_node; - if (node.has_ng_input("ValueTensor")) { - value_node = node.get_ng_input("ValueTensor"); + if (node.has_input("ValueTensor")) { + value_node = node.get_input("ValueTensor"); } else if (dtype == element::i32) { int32_t value = static_cast(node.get_attribute("value")); value_node = opset6::Constant::create(dtype, {1}, {value}); @@ -31,12 +30,12 @@ NamedOutputs fill_constant(const NodeContext& node) { } PADDLE_OP_CHECK(node, - shape.size() > 0 || node.has_ng_input("ShapeTensor") || node.has_ng_input("ShapeTensorList"), + shape.size() > 0 || node.has_input("ShapeTensor") || node.has_input("ShapeTensorList"), "fill_constant shape not set"); - if (node.has_ng_input("ShapeTensor")) { - shape_node = node.get_ng_input("ShapeTensor"); - } else if (node.has_ng_input("ShapeTensorList")) { + if (node.has_input("ShapeTensor")) { + shape_node = node.get_input("ShapeTensor"); + } else if (node.has_input("ShapeTensorList")) { auto shape_tensor_list = node.get_ng_inputs("ShapeTensorList"); shape_node = Output{std::make_shared(shape_tensor_list, 0)}; } else { diff --git a/src/frontends/paddle/src/op/fill_constant_batch_size_like.cpp b/src/frontends/paddle/src/op/fill_constant_batch_size_like.cpp index 32b9deb6a5c..9ba31c8387c 100644 --- a/src/frontends/paddle/src/op/fill_constant_batch_size_like.cpp +++ b/src/frontends/paddle/src/op/fill_constant_batch_size_like.cpp @@ -4,8 +4,8 @@ #include -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -104,7 +104,7 @@ NamedOutputs fill_constant_batch_size_like(const NodeContext& node) { auto input_dim_idx = node.get_attribute("input_dim_idx"); auto output_dim_idx = node.get_attribute("output_dim_idx"); auto shapes = node.get_attribute>("shape"); - auto input = node.get_ng_input("Input"); + auto input = node.get_input("Input"); auto input_shape = std::make_shared(input, element::i32); // 1, cat the array: // shape[0, shape[output_dim_idx]) + input_shape[input_dim_idx] + diff --git a/src/frontends/paddle/src/op/flatten_contiguous_range.cpp b/src/frontends/paddle/src/op/flatten_contiguous_range.cpp index 0276a5f772a..d2f8f9bf2bc 100644 --- a/src/frontends/paddle/src/op/flatten_contiguous_range.cpp +++ b/src/frontends/paddle/src/op/flatten_contiguous_range.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs flatten_contiguous_range(const NodeContext& node) { - auto x_node = node.get_ng_input("X"); + auto x_node = node.get_input("X"); auto shape_of_x = std::make_shared(x_node); int dims = x_node.get_partial_shape().rank().get_length(); auto start_axis = node.get_attribute("start_axis"); diff --git a/src/frontends/paddle/src/op/gelu.cpp b/src/frontends/paddle/src/op/gelu.cpp index e11b436d952..4b87a9993fc 100644 --- a/src/frontends/paddle/src/op/gelu.cpp +++ b/src/frontends/paddle/src/op/gelu.cpp @@ -2,16 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs gelu(const NodeContext& node) { - const auto data = node.get_ng_input("X"); + const auto data = node.get_input("X"); const auto approximate = node.get_attribute("approximate", false); const auto mode = approximate ? ov::op::GeluApproximationMode::TANH : ov::op::GeluApproximationMode::ERF; diff --git a/src/frontends/paddle/src/op/hard_sigmoid.cpp b/src/frontends/paddle/src/op/hard_sigmoid.cpp index dfeb477ba84..ea9cd08e726 100644 --- a/src/frontends/paddle/src/op/hard_sigmoid.cpp +++ b/src/frontends/paddle/src/op/hard_sigmoid.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +11,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs hard_sigmoid(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto dtype = data.get_element_type(); float slope = node.get_attribute("slope", 0.2f); float offset = node.get_attribute("offset", 0.5f); diff --git a/src/frontends/paddle/src/op/hard_swish.cpp b/src/frontends/paddle/src/op/hard_swish.cpp index ccedf1d45d4..55004e8035f 100644 --- a/src/frontends/paddle/src/op/hard_swish.cpp +++ b/src/frontends/paddle/src/op/hard_swish.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,18 +11,18 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs hard_swish(const NodeContext& node) { - auto data = node.get_ng_input("X"); - if (node.has_attribute("threshold")) { + auto data = node.get_input("X"); + if (node.has_attribute("threshold")) { auto threshold = node.get_attribute("threshold"); PADDLE_OP_CHECK(node, std::abs(threshold - 6.0) < 0.001, "hard_swish: Only threshold = 6.0 is currently supported"); } - if (node.has_attribute("scale")) { + if (node.has_attribute("scale")) { auto scale = node.get_attribute("scale"); PADDLE_OP_CHECK(node, std::abs(scale - 6.0) < 0.001, "hard_swish: Only scale = 6.0 is currently supported"); } - if (node.has_attribute("offset")) { + if (node.has_attribute("offset")) { auto offset = node.get_attribute("offset"); PADDLE_OP_CHECK(node, std::abs(offset - 3.0) < 0.001, "hard_swish: Only offset = 3.0 is currently supported"); } diff --git a/src/frontends/paddle/src/op/interp.cpp b/src/frontends/paddle/src/op/interp.cpp index e4acf4c93ea..7e03a929a41 100644 --- a/src/frontends/paddle/src/op/interp.cpp +++ b/src/frontends/paddle/src/op/interp.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { @@ -62,7 +61,7 @@ static std::shared_ptr extract_out_sizes(const Output& data, static NamedOutputs interpolate(const NodeContext& node, const Interpolate::InterpolateMode& mode, const int space_dim) { - const auto x = node.get_ng_input("X"); + const auto x = node.get_input("X"); using InterpolateMode = Interpolate::InterpolateMode; using CoordinateTransformMode = Interpolate::CoordinateTransformMode; using Nearest_mode = Interpolate::NearestMode; @@ -86,9 +85,9 @@ static NamedOutputs interpolate(const NodeContext& node, out_flag |= out_h <= 0 || out_d <= 0; } - if (node.has_ng_input("OutSize")) { + if (node.has_input("OutSize")) { attrs.shape_calculation_mode = ShapeCalcMode::SIZES; - const auto hw_shape = node.get_ng_input("OutSize"); + const auto hw_shape = node.get_input("OutSize"); const auto shape_of_x = std::make_shared(x); const auto shape_begin = Constant::create(element::i64, {1}, {0}); const auto shape_end = Constant::create(element::i64, Shape{1}, {-space_dim}); diff --git a/src/frontends/paddle/src/op/layer_norm.cpp b/src/frontends/paddle/src/op/layer_norm.cpp index 533c0f5e1b1..be8c83325d1 100644 --- a/src/frontends/paddle/src/op/layer_norm.cpp +++ b/src/frontends/paddle/src/op/layer_norm.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { @@ -12,7 +11,7 @@ namespace paddle { namespace op { NamedOutputs layer_norm(const NodeContext& node) { using namespace default_opset; - const auto data = node.get_ng_input("X"); + const auto data = node.get_input("X"); const auto epsilon = node.get_attribute("epsilon", 1e-05); const auto begin_norm_axis = node.get_attribute("begin_norm_axis", 1); // The limitation from: @@ -39,14 +38,14 @@ NamedOutputs layer_norm(const NodeContext& node) { const auto mvn = std::make_shared(data, axis, true, epsilon, ov::op::MVNEpsMode::INSIDE_SQRT); std::shared_ptr result = mvn; - if (node.has_ng_input("Scale")) { - const auto s = node.get_ng_input("Scale"); + if (node.has_input("Scale")) { + const auto s = node.get_input("Scale"); const auto reshaped_s = std::make_shared(s, scale_bias_shape, false); result = std::make_shared(mvn, reshaped_s); } - if (node.has_ng_input("Bias")) { - const auto b = node.get_ng_input("Bias"); + if (node.has_input("Bias")) { + const auto b = node.get_input("Bias"); const auto reshaped_b = std::make_shared(b, scale_bias_shape, false); result = std::make_shared(result, reshaped_b); } diff --git a/src/frontends/paddle/src/op/leakyrelu.cpp b/src/frontends/paddle/src/op/leakyrelu.cpp index 0576c724460..97a8d037a25 100644 --- a/src/frontends/paddle/src/op/leakyrelu.cpp +++ b/src/frontends/paddle/src/op/leakyrelu.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs leaky_relu(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto alpha = ov::opset6::Constant::create(ov::element::f32, {1}, {node.get_attribute("alpha")}); return node.default_single_output_mapping({std::make_shared(data, alpha)}, {"Out"}); } diff --git a/src/frontends/paddle/src/op/log.cpp b/src/frontends/paddle/src/op/log.cpp index ee0fd5109b4..858dfab3d1d 100644 --- a/src/frontends/paddle/src/op/log.cpp +++ b/src/frontends/paddle/src/op/log.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +11,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs log(const NodeContext& node) { - auto x = node.get_ng_input("X"); + auto x = node.get_input("X"); return node.default_single_output_mapping({std::make_shared(x)}, {"Out"}); } } // namespace op diff --git a/src/frontends/paddle/src/op/logical_not.cpp b/src/frontends/paddle/src/op/logical_not.cpp index 2ed9ccc39e2..1e073bbef68 100644 --- a/src/frontends/paddle/src/op/logical_not.cpp +++ b/src/frontends/paddle/src/op/logical_not.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs logical_not(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); return node.default_single_output_mapping({std::make_shared(data)}, {"Out"}); } } // namespace op diff --git a/src/frontends/paddle/src/op/lstm.cpp b/src/frontends/paddle/src/op/lstm.cpp index 2e3102fdcbf..179406f83e4 100644 --- a/src/frontends/paddle/src/op/lstm.cpp +++ b/src/frontends/paddle/src/op/lstm.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" #include "paddle_utils.hpp" @@ -93,8 +93,8 @@ struct LSTMNgInputMap { auto batch_size_node = std::make_shared(shape_of_x, opset6::Constant::create(element::i64, Shape{1}, {0}), axes); - if (node.has_ng_input("SequenceLength")) { - m_input_map[LSTMInput::LSTM_INPUT_SEQ_LENGTHS] = node.get_ng_input("SequenceLength"); + if (node.has_input("SequenceLength")) { + m_input_map[LSTMInput::LSTM_INPUT_SEQ_LENGTHS] = node.get_input("SequenceLength"); } else { auto seq_length_node = std::make_shared(shape_of_x, diff --git a/src/frontends/paddle/src/op/matmul.cpp b/src/frontends/paddle/src/op/matmul.cpp index d9815e6e28a..f5d27f73ab6 100644 --- a/src/frontends/paddle/src/op/matmul.cpp +++ b/src/frontends/paddle/src/op/matmul.cpp @@ -1,8 +1,7 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -10,8 +9,8 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs matmul(const NodeContext& node) { - auto x = node.get_ng_input("X"); - auto y = node.get_ng_input("Y"); + auto x = node.get_input("X"); + auto y = node.get_input("Y"); auto alpha = node.get_attribute("alpha", 1); auto transpose_a = node.get_attribute("transpose_X", false); auto transpose_b = node.get_attribute("transpose_Y", false); diff --git a/src/frontends/paddle/src/op/matmul_v2.cpp b/src/frontends/paddle/src/op/matmul_v2.cpp index 861c54209b2..f2f77d8a060 100644 --- a/src/frontends/paddle/src/op/matmul_v2.cpp +++ b/src/frontends/paddle/src/op/matmul_v2.cpp @@ -1,17 +1,16 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs matmul_v2(const NodeContext& node) { - const auto x = node.get_ng_input("X"); - const auto y = node.get_ng_input("Y"); + const auto x = node.get_input("X"); + const auto y = node.get_input("Y"); const auto transpose_a = node.get_attribute("trans_x", false); const auto transpose_b = node.get_attribute("trans_y", false); const auto mm = std::make_shared(x, y, transpose_a, transpose_b); diff --git a/src/frontends/paddle/src/op/matrix_nms.cpp b/src/frontends/paddle/src/op/matrix_nms.cpp index 563016ea5e6..b9228d0f88a 100644 --- a/src/frontends/paddle/src/op/matrix_nms.cpp +++ b/src/frontends/paddle/src/op/matrix_nms.cpp @@ -1,8 +1,8 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset8.hpp" namespace ov { @@ -13,8 +13,8 @@ NamedOutputs matrix_nms(const NodeContext& node) { using namespace opset8; using namespace element; - auto bboxes = node.get_ng_input("BBoxes"); - auto scores = node.get_ng_input("Scores"); + auto bboxes = node.get_input("BBoxes"); + auto scores = node.get_input("Scores"); auto score_threshold = node.get_attribute("score_threshold"); auto post_threshold = node.get_attribute("post_threshold"); diff --git a/src/frontends/paddle/src/op/multiclass_nms.cpp b/src/frontends/paddle/src/op/multiclass_nms.cpp index 5f3e7e3f53f..6d2defde75f 100644 --- a/src/frontends/paddle/src/op/multiclass_nms.cpp +++ b/src/frontends/paddle/src/op/multiclass_nms.cpp @@ -1,8 +1,8 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset8.hpp" namespace ov { @@ -13,8 +13,8 @@ NamedOutputs multiclass_nms(const NodeContext& node) { using namespace opset8; using namespace element; - auto bboxes = node.get_ng_input("BBoxes"); - auto scores = node.get_ng_input("Scores"); + auto bboxes = node.get_input("BBoxes"); + auto scores = node.get_input("Scores"); auto score_threshold = node.get_attribute("score_threshold"); auto iou_threshold = node.get_attribute("nms_threshold"); diff --git a/src/frontends/paddle/src/op/pad3d.cpp b/src/frontends/paddle/src/op/pad3d.cpp index f5103246708..9504d172d84 100644 --- a/src/frontends/paddle/src/op/pad3d.cpp +++ b/src/frontends/paddle/src/op/pad3d.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs pad3d(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto mode = node.get_attribute("mode"); auto value = node.get_attribute("value", 0.0); auto data_format = node.get_attribute("data_format"); @@ -20,11 +19,11 @@ NamedOutputs pad3d(const NodeContext& node) { // padding of type int feature only supported by paddle 'develop' // version(>=2.1.0) - if (node.has_attribute>("paddings")) { + if (node.has_attribute("paddings")) { auto paddings_vector = node.get_attribute>("paddings"); PADDLE_OP_CHECK(node, paddings_vector.size() == 6, "paddings Params size should be 6 in pad3d!"); paddings = paddings_vector; - } else if (node.has_attribute("paddings")) { + } else if (node.has_attribute("paddings")) { auto padding_int = node.get_attribute("paddings"); for (int i = 0; i < 6; i++) paddings[i] = padding_int; diff --git a/src/frontends/paddle/src/op/pool2d.cpp b/src/frontends/paddle/src/op/pool2d.cpp index 224b0ffda18..b60de814941 100644 --- a/src/frontends/paddle/src/op/pool2d.cpp +++ b/src/frontends/paddle/src/op/pool2d.cpp @@ -4,8 +4,7 @@ // //***************************************************************************** -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" #include "openvino/opsets/opset8.hpp" @@ -15,7 +14,7 @@ namespace paddle { namespace op { // helper func - get pad_begin and pad_end static void get_paddings(const NodeContext& node, ov::Shape& pad_begin, ov::Shape& pad_end, ov::op::PadType& auto_pad) { - if (node.has_attribute("padding_algorithm")) { + if (node.has_attribute("padding_algorithm")) { auto pad_algo = node.get_attribute("padding_algorithm"); if (pad_algo == "SAME") { auto_pad = ov::op::PadType::SAME_UPPER; @@ -59,7 +58,7 @@ static void get_paddings(const NodeContext& node, ov::Shape& pad_begin, ov::Shap } NamedOutputs pool2d(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto pooling_type = node.get_attribute("pooling_type", {}); auto global_pooling = node.get_attribute("global_pooling"); diff --git a/src/frontends/paddle/src/op/pow.cpp b/src/frontends/paddle/src/op/pow.cpp index 4890209c097..3235d6a0ea7 100644 --- a/src/frontends/paddle/src/op/pow.cpp +++ b/src/frontends/paddle/src/op/pow.cpp @@ -1,8 +1,8 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -10,11 +10,11 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs pow(const NodeContext& node) { - auto x = node.get_ng_input("X"); + auto x = node.get_input("X"); auto dtype = x.get_element_type(); Output factor_node; - if (node.has_ng_input("FactorTensor")) { - factor_node = node.get_ng_input("FactorTensor"); + if (node.has_input("FactorTensor")) { + factor_node = node.get_input("FactorTensor"); if (factor_node.get_element_type() != dtype) factor_node = std::make_shared(factor_node, dtype); } else { diff --git a/src/frontends/paddle/src/op/prior_box.cpp b/src/frontends/paddle/src/op/prior_box.cpp index a178f154065..3cfdc9f145a 100644 --- a/src/frontends/paddle/src/op/prior_box.cpp +++ b/src/frontends/paddle/src/op/prior_box.cpp @@ -4,9 +4,8 @@ #include "openvino/op/prior_box.hpp" -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { @@ -26,8 +25,8 @@ std::shared_ptr make_slice(const std::shared_ptr& node, } // namespace } // namespace detail NamedOutputs prior_box(const NodeContext& node) { - auto input = node.get_ng_input("Input"); - auto Image = node.get_ng_input("Image"); + auto input = node.get_input("Input"); + auto Image = node.get_input("Image"); const auto input_shape = std::make_shared(input); const auto Image_shape = std::make_shared(Image); const auto output_shape_slice = detail::make_slice(input_shape, 2, 4); diff --git a/src/frontends/paddle/src/op/range.cpp b/src/frontends/paddle/src/op/range.cpp index 7c3d947637b..52c7f89555d 100644 --- a/src/frontends/paddle/src/op/range.cpp +++ b/src/frontends/paddle/src/op/range.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,9 +10,9 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs range(const NodeContext& node) { - auto start = node.get_ng_input("Start"); - auto stop = node.get_ng_input("End"); - auto step = node.get_ng_input("Step"); + auto start = node.get_input("Start"); + auto stop = node.get_input("End"); + auto step = node.get_input("Step"); auto type = node.get_out_port_type("Out"); const auto axis = ov::opset6::Constant::create(element::i64, Shape{}, {0}); diff --git a/src/frontends/paddle/src/op/relu.cpp b/src/frontends/paddle/src/op/relu.cpp index db1ceab5652..2067eaf0e87 100644 --- a/src/frontends/paddle/src/op/relu.cpp +++ b/src/frontends/paddle/src/op/relu.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs relu(const NodeContext& node) { - return node.default_single_output_mapping({std::make_shared(node.get_ng_input("X"))}, {"Out"}); + return node.default_single_output_mapping({std::make_shared(node.get_input("X"))}, {"Out"}); } } // namespace op diff --git a/src/frontends/paddle/src/op/relu6.cpp b/src/frontends/paddle/src/op/relu6.cpp index bc0d3c1eebc..cb95d3002af 100644 --- a/src/frontends/paddle/src/op/relu6.cpp +++ b/src/frontends/paddle/src/op/relu6.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +11,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs relu6(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto threshold = node.get_attribute("threshold", 6.0f); return node.default_single_output_mapping({std::make_shared(data, 0.0, threshold)}, {"Out"}); } diff --git a/src/frontends/paddle/src/op/reshape2.cpp b/src/frontends/paddle/src/op/reshape2.cpp index 0f51a8bdc5f..295d8414b4d 100644 --- a/src/frontends/paddle/src/op/reshape2.cpp +++ b/src/frontends/paddle/src/op/reshape2.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,15 +11,15 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs reshape2(const NodeContext& node) { - auto data = node.get_ng_input("X"); - if (!node.has_ng_input("Shape") && !node.has_ng_input("ShapeTensor")) { + auto data = node.get_input("X"); + if (!node.has_input("Shape") && !node.has_input("ShapeTensor")) { auto shape_attr = node.get_attribute>("shape"); auto shape_node = ov::opset6::Constant::create(ov::element::i32, {shape_attr.size()}, shape_attr); return node.default_single_output_mapping({std::make_shared(data, shape_node, true)}, {"Out"}); } else { std::string name = "Shape"; - if (node.has_ng_input("ShapeTensor")) { + if (node.has_input("ShapeTensor")) { name = "ShapeTensor"; } diff --git a/src/frontends/paddle/src/op/rnn.cpp b/src/frontends/paddle/src/op/rnn.cpp index 1e6ba2d6948..b9eb1b65557 100644 --- a/src/frontends/paddle/src/op/rnn.cpp +++ b/src/frontends/paddle/src/op/rnn.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { diff --git a/src/frontends/paddle/src/op/scale.cpp b/src/frontends/paddle/src/op/scale.cpp index 182ee6e5256..27f3cbffe3d 100644 --- a/src/frontends/paddle/src/op/scale.cpp +++ b/src/frontends/paddle/src/op/scale.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,14 +10,14 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs scale(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto dtype = data.get_element_type(); // Note: paddle Scale output data_type is the same with input Output scale; Output bias; - if (node.has_ng_input("ScaleTensor")) { - auto scale_tensor_node = node.get_ng_input("ScaleTensor"); + if (node.has_input("ScaleTensor")) { + auto scale_tensor_node = node.get_input("ScaleTensor"); if (scale_tensor_node.get_element_type() == dtype) scale = scale_tensor_node; else diff --git a/src/frontends/paddle/src/op/shape.cpp b/src/frontends/paddle/src/op/shape.cpp index 14ebf36616c..58a54e665f8 100644 --- a/src/frontends/paddle/src/op/shape.cpp +++ b/src/frontends/paddle/src/op/shape.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs shape(const NodeContext& node) { - auto data = node.get_ng_input("Input"); + auto data = node.get_input("Input"); auto shape_node = std::make_shared(data, element::i32); return node.default_single_output_mapping({shape_node}, {"Out"}); } diff --git a/src/frontends/paddle/src/op/sigmoid.cpp b/src/frontends/paddle/src/op/sigmoid.cpp index a1223e64493..7a71529ca93 100644 --- a/src/frontends/paddle/src/op/sigmoid.cpp +++ b/src/frontends/paddle/src/op/sigmoid.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs sigmoid(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); return node.default_single_output_mapping({std::make_shared(data)}, {"Out"}); } diff --git a/src/frontends/paddle/src/op/slice.cpp b/src/frontends/paddle/src/op/slice.cpp index ef4059890df..382cea40317 100644 --- a/src/frontends/paddle/src/op/slice.cpp +++ b/src/frontends/paddle/src/op/slice.cpp @@ -4,9 +4,8 @@ #include -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { @@ -14,12 +13,12 @@ namespace paddle { namespace op { using namespace default_opset; NamedOutputs slice(const NodeContext& node) { - auto data = node.get_ng_input("Input"); + auto data = node.get_input("Input"); auto axes = node.get_attribute>("axes"); Output start_idx_node, end_idx_node; - if (node.has_ng_input("StartsTensor")) { - start_idx_node = node.get_ng_input("StartsTensor"); - } else if (node.has_ng_input("StartsTensorList")) { + if (node.has_input("StartsTensor")) { + start_idx_node = node.get_input("StartsTensor"); + } else if (node.has_input("StartsTensorList")) { auto inputs = node.get_ng_inputs("StartsTensorList"); start_idx_node = std::make_shared(inputs, 0); } else { @@ -27,9 +26,9 @@ NamedOutputs slice(const NodeContext& node) { start_idx_node = Constant::create(element::i32, {starts.size()}, starts); } - if (node.has_ng_input("EndsTensor")) { - end_idx_node = node.get_ng_input("EndsTensor"); - } else if (node.has_ng_input("EndsTensorList")) { + if (node.has_input("EndsTensor")) { + end_idx_node = node.get_input("EndsTensor"); + } else if (node.has_input("EndsTensorList")) { auto inputs = node.get_ng_inputs("EndsTensorList"); end_idx_node = std::make_shared(inputs, 0); } else { diff --git a/src/frontends/paddle/src/op/softmax.cpp b/src/frontends/paddle/src/op/softmax.cpp index 3b5f5c3dfa1..20b927db0eb 100644 --- a/src/frontends/paddle/src/op/softmax.cpp +++ b/src/frontends/paddle/src/op/softmax.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs softmax(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto axis = node.get_attribute("axis"); if (axis < 0) { PADDLE_OP_CHECK(node, data.get_partial_shape().rank().is_static(), "Softmax rank must be static"); diff --git a/src/frontends/paddle/src/op/softplus.cpp b/src/frontends/paddle/src/op/softplus.cpp index f7642d752ac..02c29d072f6 100644 --- a/src/frontends/paddle/src/op/softplus.cpp +++ b/src/frontends/paddle/src/op/softplus.cpp @@ -1,23 +1,22 @@ // Copyright (C) 2018-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs softplus(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto beta = node.get_attribute("beta"); auto threshold = node.get_attribute("threshold"); float supported_beta = 1.0; float supported_threshold = 20.0; const float EPSINON = 1e-6; - if (!(abs(beta - supported_beta) <= EPSINON) || !(abs(threshold - supported_threshold) <= EPSINON)) { + if (!(std::fabs(beta - supported_beta) <= EPSINON) || !(std::fabs(threshold - supported_threshold) <= EPSINON)) { PADDLE_OP_CHECK(node, false, "only support beta==1.0 && threshold==20.0"); } return node.default_single_output_mapping({std::make_shared(data)}, {"Out"}); diff --git a/src/frontends/paddle/src/op/split.cpp b/src/frontends/paddle/src/op/split.cpp index 9f5486bf014..09f5de84af6 100644 --- a/src/frontends/paddle/src/op/split.cpp +++ b/src/frontends/paddle/src/op/split.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" +#include "openvino/frontend/paddle/visibility.hpp" #include "openvino/opsets/opset7.hpp" namespace ov { @@ -12,15 +12,15 @@ namespace paddle { namespace op { NamedOutputs split(const NodeContext& node) { using namespace opset7; - const auto& data = node.get_ng_input("X"); + const auto& data = node.get_input("X"); Output axis; - if (node.has_ng_input("AxisTensor")) { - auto input = node.get_ng_input("AxisTensor"); + if (node.has_input("AxisTensor")) { + auto input = node.get_input("AxisTensor"); auto zero_node = Constant::create(element::i32, {1}, {0}); axis = std::make_shared(input, zero_node, false); } else { auto dim = -1; - if (node.has_attribute("axis")) { + if (node.has_attribute("axis")) { dim = node.get_attribute("axis"); } axis = std::make_shared(ov::element::i32, Shape{}, dim); @@ -30,13 +30,11 @@ NamedOutputs split(const NodeContext& node) { std::vector> split_outputs; if (num_or_sections == 0) { Output sections_node; - if (node.has_ng_input("SectionsTensorList")) { + if (node.has_input("SectionsTensorList")) { auto inputs = node.get_ng_inputs("SectionsTensorList"); sections_node = std::make_shared(inputs, 0); } else { - PADDLE_OP_CHECK(node, - node.has_attribute>("sections"), - "split: num==0 && no sections is invalid."); + PADDLE_OP_CHECK(node, node.has_attribute("sections"), "split: num==0 && no sections is invalid."); auto sections = node.get_attribute>("sections"); sections_node = Constant::create(element::i32, {sections.size()}, sections); } diff --git a/src/frontends/paddle/src/op/squeeze.cpp b/src/frontends/paddle/src/op/squeeze.cpp index 6bf87059dee..7ce817cf6c5 100644 --- a/src/frontends/paddle/src/op/squeeze.cpp +++ b/src/frontends/paddle/src/op/squeeze.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,9 +10,9 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs squeeze(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); std::vector axes; - if (node.has_attribute>("axes")) { + if (node.has_attribute("axes")) { axes = node.get_attribute>("axes"); } diff --git a/src/frontends/paddle/src/op/stack.cpp b/src/frontends/paddle/src/op/stack.cpp index 4d1de117003..8c1ebb964db 100644 --- a/src/frontends/paddle/src/op/stack.cpp +++ b/src/frontends/paddle/src/op/stack.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/paddle/src/op/tanh.cpp b/src/frontends/paddle/src/op/tanh.cpp index 8dfe3b5d138..803bfc8f465 100644 --- a/src/frontends/paddle/src/op/tanh.cpp +++ b/src/frontends/paddle/src/op/tanh.cpp @@ -2,16 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "default_opset.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { namespace paddle { namespace op { NamedOutputs tanh(const NodeContext& node) { - const auto x = node.get_ng_input("X"); + const auto x = node.get_input("X"); return node.default_single_output_mapping({std::make_shared(x)}, {"Out"}); } diff --git a/src/frontends/paddle/src/op/transpose2.cpp b/src/frontends/paddle/src/op/transpose2.cpp index 2f0e64b1c0e..ab6f5ea8d4c 100644 --- a/src/frontends/paddle/src/op/transpose2.cpp +++ b/src/frontends/paddle/src/op/transpose2.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,7 +10,7 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs transpose2(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); auto perm = node.get_attribute>("axis"); auto input_order = ov::opset6::Constant::create(ov::element::i64, {perm.size()}, perm); return node.default_single_output_mapping({std::make_shared(data, input_order)}, {"Out"}); diff --git a/src/frontends/paddle/src/op/unsqueeze.cpp b/src/frontends/paddle/src/op/unsqueeze.cpp index 3e3c2d9bc33..90893b723a5 100644 --- a/src/frontends/paddle/src/op/unsqueeze.cpp +++ b/src/frontends/paddle/src/op/unsqueeze.cpp @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -11,11 +10,11 @@ namespace frontend { namespace paddle { namespace op { NamedOutputs unsqueeze(const NodeContext& node) { - auto data = node.get_ng_input("X"); + auto data = node.get_input("X"); Output axesNode; - if (node.has_ng_input("AxesTensor")) { - axesNode = node.get_ng_input("AxesTensor"); - } else if (node.has_ng_input("AxesTensorList")) { + if (node.has_input("AxesTensor")) { + axesNode = node.get_input("AxesTensor"); + } else if (node.has_input("AxesTensorList")) { auto inputs = node.get_ng_inputs("AxesTensorList"); axesNode = std::make_shared(inputs, 0); } else { diff --git a/src/frontends/paddle/src/op/yolo_box.cpp b/src/frontends/paddle/src/op/yolo_box.cpp index 4d2d0fc3794..873549fa08e 100644 --- a/src/frontends/paddle/src/op/yolo_box.cpp +++ b/src/frontends/paddle/src/op/yolo_box.cpp @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // #include // std::numeric_limits -#include #include +#include "openvino/frontend/paddle/node_context.hpp" #include "openvino/opsets/opset6.hpp" namespace ov { @@ -20,8 +20,8 @@ using namespace element; // Paddle2ONNX/paddle2onnx/op_mapper/detection/yolo_box.py - clip_bbox is not used // by Paddle2ONNX. NamedOutputs yolo_box(const NodeContext& node_context) { - auto data = node_context.get_ng_input("X"); - auto image_size = node_context.get_ng_input("ImgSize"); + auto data = node_context.get_input("X"); + auto image_size = node_context.get_input("ImgSize"); // get shape of X auto input_shape = std::make_shared(data, i64); diff --git a/src/frontends/paddle/src/op_table.hpp b/src/frontends/paddle/src/op_table.hpp index 2fbd262c754..fad457b938c 100644 --- a/src/frontends/paddle/src/op_table.hpp +++ b/src/frontends/paddle/src/op_table.hpp @@ -8,7 +8,7 @@ #include #include -#include "node_context.hpp" +#include "openvino/frontend/paddle/node_context.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/paddle/src/paddle_fw_node.hpp b/src/frontends/paddle/src/paddle_fw_node.hpp index 17f3083a282..f18c29d11c3 100644 --- a/src/frontends/paddle/src/paddle_fw_node.hpp +++ b/src/frontends/paddle/src/paddle_fw_node.hpp @@ -4,9 +4,8 @@ #pragma once -#include - -#include "decoder.hpp" +#include "decoder_proto.hpp" +#include "openvino/op/util/framework_node.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/paddle/src/place.cpp b/src/frontends/paddle/src/place.cpp index 5d1b36a3a92..6f393bca0e9 100644 --- a/src/frontends/paddle/src/place.cpp +++ b/src/frontends/paddle/src/place.cpp @@ -4,7 +4,7 @@ #include "place.hpp" -#include "decoder.hpp" +#include "decoder_proto.hpp" #include "framework.pb.h" namespace ov { diff --git a/src/frontends/paddle/src/place.hpp b/src/frontends/paddle/src/place.hpp index a32c18715c8..3abb40462bc 100644 --- a/src/frontends/paddle/src/place.hpp +++ b/src/frontends/paddle/src/place.hpp @@ -4,9 +4,8 @@ #pragma once -#include - #include "input_model.hpp" +#include "openvino/frontend/manager.hpp" namespace paddle { namespace framework { diff --git a/src/frontends/tensorflow/CMakeLists.txt b/src/frontends/tensorflow/CMakeLists.txt index 8fe44a10546..68e9d0b05e7 100644 --- a/src/frontends/tensorflow/CMakeLists.txt +++ b/src/frontends/tensorflow/CMakeLists.txt @@ -2,12 +2,12 @@ # SPDX-License-Identifier: Apache-2.0 # -# TODO: Add LINKABLE_FRONTEND option when tensorflow frontend directory is moved to openvino folder ov_add_frontend(NAME tensorflow + LINKABLE_FRONTEND SHUTDOWN_PROTOBUF SKIP_INSTALL FILEDESCRIPTION "FrontEnd to load and convert TensorFlow file format" - LINK_LIBRARIES openvino::util) + LINK_LIBRARIES openvino::util openvino::runtime::dev) # TODO: once TensorFlow FE become releasable component, need to remove these lines and SKIP_INSTALL above install(TARGETS ${TARGET_NAME} diff --git a/src/frontends/tensorflow/include/openvino/frontend/tensorflow/decoder.hpp b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/decoder.hpp index d1f08c4df42..7b814e9c219 100644 --- a/src/frontends/tensorflow/include/openvino/frontend/tensorflow/decoder.hpp +++ b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/decoder.hpp @@ -13,12 +13,18 @@ namespace tensorflow { class TENSORFLOW_API DecoderBase { public: - /// \brief Get attribute value by name and requested type + /// \brief Get attribute value by name /// /// \param name Attribute name - /// \param type_info Attribute type information - /// \return Shared pointer to appropriate value if it exists, 'nullptr' otherwise - virtual ov::Any get_attribute(const std::string& name, const std::type_info& type_info) const = 0; + /// \return Shared pointer to appropriate value converted to openvino data type if it exists, 'nullptr' otherwise + virtual ov::Any get_attribute(const std::string& name) const = 0; + + /// \brief Get attribute value by name + /// + /// \param name Attribute name + /// \return Shared pointer to appropriate value in native tensorflow data type if it exists, + /// 'nullptr' otherwise + virtual ov::Any get_native_attribute(const std::string& name) const = 0; /// \brief Get a number of inputs virtual size_t get_input_size() const = 0; diff --git a/src/frontends/tensorflow/src/exceptions.hpp b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/exception.hpp similarity index 100% rename from src/frontends/tensorflow/src/exceptions.hpp rename to src/frontends/tensorflow/include/openvino/frontend/tensorflow/exception.hpp diff --git a/src/frontends/tensorflow/include/openvino/frontend/tensorflow/extension/conversion.hpp b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/extension/conversion.hpp new file mode 100644 index 00000000000..5c5b6b4d0eb --- /dev/null +++ b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/extension/conversion.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/frontend/extension/conversion.hpp" +#include "openvino/frontend/frontend.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" +#include "openvino/frontend/tensorflow/visibility.hpp" + +namespace ov { +namespace frontend { +namespace tensorflow { + +class TENSORFLOW_API ConversionExtension : public ConversionExtensionBase { +public: + using Ptr = std::shared_ptr; + + ConversionExtension() = delete; + + ConversionExtension(const std::string& op_type, const ov::frontend::CreatorFunction& converter) + : ConversionExtensionBase(op_type), + m_converter(converter) {} + + const ov::frontend::CreatorFunction& get_converter() const { + return m_converter; + } + +private: + ov::frontend::CreatorFunction m_converter; +}; + +} // namespace tensorflow +} // namespace frontend +} // namespace ov \ No newline at end of file diff --git a/src/frontends/tensorflow/include/openvino/frontend/tensorflow/frontend.hpp b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/frontend.hpp index 5bb36bb83ea..296fd88daf7 100644 --- a/src/frontends/tensorflow/include/openvino/frontend/tensorflow/frontend.hpp +++ b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/frontend.hpp @@ -9,27 +9,22 @@ #include "openvino/core/any.hpp" #include "openvino/core/node_vector.hpp" +#include "openvino/frontend/extension/conversion.hpp" #include "openvino/frontend/extension/decoder_transformation.hpp" #include "openvino/frontend/extension/telemetry.hpp" #include "openvino/frontend/frontend.hpp" #include "openvino/frontend/input_model.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" #include "openvino/frontend/tensorflow/visibility.hpp" +#include "openvino/frontend/visibility.hpp" namespace ov { namespace frontend { namespace tensorflow { -class NodeContext; - class TENSORFLOW_API FrontEnd : public ov::frontend::FrontEnd { public: - using CreatorFunction = std::function<::ov::OutputVector(const ::ov::frontend::tensorflow::NodeContext&)>; - using TranslatorDictionaryType = std::map; - -private: - TranslatorDictionaryType m_op_translators; - -public: + using Ptr = std::shared_ptr; FrontEnd(); /// \brief Completely convert the model @@ -72,15 +67,21 @@ protected: ov::frontend::InputModel::Ptr load_impl(const std::vector& variants) const override; -private: void translate_graph(const ov::frontend::InputModel::Ptr& model, const std::string& model_name, bool fail_fast, bool no_conversion, std::shared_ptr& ng_function) const; - std::shared_ptr m_telemetry; - std::vector> m_transformation_extensions; + // m_extensions should be the first member here, + // m_extensions can contain SO Extension (holder for other Extensions), + // so it should be released last. + std::vector m_extensions; + TelemetryExtension::Ptr m_telemetry; + std::vector m_transformation_extensions; + std::vector m_conversion_extensions; + + TranslatorDictionaryType m_op_translators; }; } // namespace tensorflow diff --git a/src/frontends/tensorflow/include/openvino/frontend/tensorflow/node_context.hpp b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/node_context.hpp new file mode 100644 index 00000000000..531c435ba4a --- /dev/null +++ b/src/frontends/tensorflow/include/openvino/frontend/tensorflow/node_context.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "decoder.hpp" +#include "exception.hpp" +#include "openvino/core/any.hpp" +#include "openvino/frontend/node_context.hpp" + +namespace ov { +namespace frontend { +namespace tensorflow { + +/// Keep necessary data for a single node in the original FW graph to facilitate +/// conversion process in the rules code. +class NodeContext : public ov::frontend::NodeContext { +public: + using Ptr = std::shared_ptr; + NodeContext(const DecoderBase& decoder, const OutputVector& inputs) + : ov::frontend::NodeContext(decoder.get_op_type()), + m_decoder(decoder), + m_inputs(inputs) {} + + /// Detects if there is at least one input attached with a given name + bool has_input(const size_t& port_index) const { + return port_index < m_inputs.size(); + } + + Output get_input(int port_index) const override { + return m_inputs.at(port_index); + } + + size_t get_input_size() const override { + return m_inputs.size(); + } + + /// \brief Get a node name + std::string get_name() const { + return m_decoder.get_op_name(); + } + + /// \brief Get a decoder + const DecoderBase* get_decoder() const { + return &m_decoder; + } + + ov::Any get_attribute_as_any(const std::string& name) const override { + auto res = m_decoder.get_attribute(name); + FRONT_END_GENERAL_CHECK(!res.empty(), "Attribute with name '", name, "' does not exist"); + return res; + } + +private: + const DecoderBase& m_decoder; + const OutputVector& m_inputs; +}; + +using CreatorFunction = std::function; +using TranslatorDictionaryType = std::map; + +} // namespace tensorflow +} // namespace frontend +} // namespace ov diff --git a/src/frontends/tensorflow/src/decoder_proto.cpp b/src/frontends/tensorflow/src/decoder_proto.cpp index ca65dd39e94..99e724d706a 100644 --- a/src/frontends/tensorflow/src/decoder_proto.cpp +++ b/src/frontends/tensorflow/src/decoder_proto.cpp @@ -4,7 +4,7 @@ #include "decoder_proto.hpp" -#include "node_context.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" namespace ov { namespace frontend { @@ -27,62 +27,92 @@ const std::map<::tensorflow::DataType, ov::element::Type>& TYPE_MAP() { } } // namespace -ov::Any DecoderProto::get_attribute(const std::string& name, const std::type_info& type_info) const { +ov::Any DecoderProto::get_native_attribute(const std::string& name) const { auto attrs = decode_attribute_helper(name); if (attrs.empty()) { return {}; } - if (type_info == typeid(std::string)) { - return attrs[0].s(); - } else if (type_info == typeid(int64_t)) { - return attrs[0].i(); - } else if (type_info == typeid(std::vector)) { - std::vector longs; - longs.reserve(attrs[0].list().i_size()); - for (size_t idx = 0; idx < attrs[0].list().i_size(); ++idx) { - longs.push_back(attrs[0].list().i(idx)); - } - return longs; - } else if (type_info == typeid(int32_t)) { - return static_cast(attrs[0].i()); - } else if (type_info == typeid(std::vector)) { - std::vector ints; - ints.reserve(attrs[0].list().i_size()); - for (size_t idx = 0; idx < attrs[0].list().i_size(); ++idx) { - ints.push_back(static_cast(attrs[0].list().i(idx))); - } - return ints; - } else if (type_info == typeid(float)) { - return attrs[0].f(); - } else if (type_info == typeid(std::vector)) { - std::vector floats; - floats.reserve(attrs[0].list().i_size()); - for (size_t idx = 0; idx < attrs[0].list().i_size(); ++idx) { - floats.push_back(attrs[0].list().f(idx)); - } - return floats; - } else if (type_info == typeid(ov::element::Type)) { - auto data_type = attrs[0].type(); - return TYPE_MAP().at(data_type); - } else if (type_info == typeid(bool)) { - return attrs[0].b(); - } else if (type_info == typeid(::tensorflow::DataType)) { - return attrs[0].type(); - } else if (type_info == typeid(::tensorflow::TensorProto)) { + switch (attrs[0].value_case()) { + case ::tensorflow::AttrValue::ValueCase::kTensor: return attrs[0].tensor(); - } else if (type_info == typeid(::ov::PartialShape)) { - std::vector dims; - auto tf_shape = attrs[0].shape(); - for (int i = 0; i < tf_shape.dim_size(); i++) { - dims.push_back(tf_shape.dim(i).size()); - } - auto pshape = ov::PartialShape(dims); - return pshape; + case ::tensorflow::AttrValue::ValueCase::kType: + return attrs[0].type(); + default: + FRONT_END_GENERAL_CHECK(false, "DataType is not covered."); + } +} + +ov::Any DecoderProto::get_attribute(const std::string& name) const { + auto attrs = decode_attribute_helper(name); + if (attrs.empty()) { + return {}; } - // type is not supported by decoder - return {}; + switch (attrs[0].value_case()) { + case ::tensorflow::AttrValue::ValueCase::kB: + return attrs[0].b(); + case ::tensorflow::AttrValue::ValueCase::kF: + return attrs[0].f(); + case ::tensorflow::AttrValue::ValueCase::kS: + return attrs[0].s(); + case ::tensorflow::AttrValue::ValueCase::kI: + return attrs[0].i(); + case ::tensorflow::AttrValue::ValueCase::kShape: { + std::vector dims; + const auto& tf_shape = attrs[0].shape(); + for (int i = 0; i < tf_shape.dim_size(); i++) { + dims.emplace_back(tf_shape.dim(i).size()); + } + return ov::PartialShape(dims); + } + + case ::tensorflow::AttrValue::ValueCase::kType: + return TYPE_MAP().at(attrs[0].type()); + + case ::tensorflow::AttrValue::ValueCase::kList: { + const auto& list = attrs[0].list(); + if (list.i_size()) + return std::vector(list.i().begin(), list.i().end()); + + if (list.f_size()) + return std::vector(list.f().begin(), list.f().end()); + + if (list.s_size()) + return std::vector(list.s().begin(), list.s().end()); + + if (list.b_size()) + return std::vector(list.b().begin(), list.b().end()); + + if (list.shape_size()) { + std::vector res; + for (const auto& it : list.shape()) { + std::vector dims; + for (int i = 0; i < it.dim_size(); i++) { + dims.emplace_back(it.dim(i).size()); + } + res.emplace_back(dims); + } + } + + if (list.type_size()) { + std::vector res; + for (int idx = 0; idx < list.type_size(); ++idx) { + res.emplace_back(TYPE_MAP().at(list.type(idx))); + } + return res; + } + + if (list.tensor_size() || list.func_size()) + FRONT_END_GENERAL_CHECK(false, "Conversion from Tensorflow to OpenVINO data type is not supported."); + } + + case ::tensorflow::AttrValue::ValueCase::kTensor: + case ::tensorflow::AttrValue::ValueCase::kPlaceholder: + case ::tensorflow::AttrValue::ValueCase::kFunc: + default: + FRONT_END_GENERAL_CHECK(false, "Conversion from Tensorflow to OpenVINO data type is not supported."); + } } size_t DecoderProto::get_input_size() const { diff --git a/src/frontends/tensorflow/src/decoder_proto.hpp b/src/frontends/tensorflow/src/decoder_proto.hpp index b7ffc579f9a..c155e42f7e8 100644 --- a/src/frontends/tensorflow/src/decoder_proto.hpp +++ b/src/frontends/tensorflow/src/decoder_proto.hpp @@ -20,7 +20,9 @@ class DecoderProto : public ov::frontend::tensorflow::DecoderBase { public: explicit DecoderProto(const ::tensorflow::NodeDef* node_def) : m_node_def(node_def) {} - ov::Any get_attribute(const std::string& name, const std::type_info& type_info) const override; + ov::Any get_attribute(const std::string& name) const override; + + ov::Any get_native_attribute(const std::string& name) const override; size_t get_input_size() const override; diff --git a/src/frontends/tensorflow/src/exceptions.cpp b/src/frontends/tensorflow/src/exception.cpp similarity index 63% rename from src/frontends/tensorflow/src/exceptions.cpp rename to src/frontends/tensorflow/src/exception.cpp index 3ec9f6a8547..817a8b903ed 100644 --- a/src/frontends/tensorflow/src/exceptions.cpp +++ b/src/frontends/tensorflow/src/exception.cpp @@ -2,14 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "exceptions.hpp" +#include "openvino/frontend/tensorflow/exception.hpp" -#include "node_context.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" namespace ov { namespace frontend { namespace tensorflow { -std::string OpValidationFailure::get_error_msg_prefix_tf(const tensorflow::NodeContext& node) { +std::string OpValidationFailure::get_error_msg_prefix_tf(const NodeContext& node) { std::stringstream ss; ss << "While validating node '" << node.get_op_type() << '\''; return ss.str(); diff --git a/src/frontends/tensorflow/src/frontend.cpp b/src/frontends/tensorflow/src/frontend.cpp index 9c5f37acd13..df415401217 100644 --- a/src/frontends/tensorflow/src/frontend.cpp +++ b/src/frontends/tensorflow/src/frontend.cpp @@ -6,10 +6,12 @@ #include "input_model.hpp" #include "op_table.hpp" +#include "openvino/frontend/tensorflow/extension/conversion.hpp" #include "openvino/frontend/tensorflow/graph_iterator.hpp" #include "openvino/pass/manager.hpp" #include "openvino/util/common_util.hpp" #include "pass/transpose_sinking.hpp" +#include "so_extension.hpp" #include "tf_framework_node.hpp" #include "utils.hpp" @@ -17,22 +19,15 @@ using namespace ov::frontend::tensorflow; namespace { void translate_framework_node(const std::shared_ptr& node, - const FrontEnd::TranslatorDictionaryType& op_translators) { + const TranslatorDictionaryType& op_translators) { auto type = node->get_op_type(); const auto& TRANSLATE_OP_MAP = op_translators; auto translator_it = TRANSLATE_OP_MAP.find(type); FRONT_END_OP_CONVERSION_CHECK(translator_it != TRANSLATE_OP_MAP.end(), "No translator found for ", type, " node."); - ov::OutputVector ng_inputs; - NamedInputs named_inputs; - size_t input_port_idx = 0; - for (const auto& input : node->input_values()) { - ng_inputs.push_back(input); - named_inputs[input_port_idx++] = {input}; - } - - NodeContext node_ctx(*node->get_decoder(), named_inputs); + ov::OutputVector ng_inputs = node->input_values(); + NodeContext node_ctx(*node->get_decoder(), ng_inputs); auto new_node_outputs = translator_it->second(node_ctx); auto new_output = new_node_outputs.begin(); @@ -112,7 +107,6 @@ void FrontEnd::translate_graph(const ov::frontend::InputModel::Ptr& model, // prepare a list of OV node inputs for each node ov::OutputVector ng_inputs; - ::ov::frontend::tensorflow::NamedInputs named_inputs; for (size_t input_port_idx = 0; input_port_idx < operation_decoder->get_input_size(); ++input_port_idx) { std::string producer_name; size_t producer_port_idx; @@ -136,20 +130,17 @@ void FrontEnd::translate_graph(const ov::frontend::InputModel::Ptr& model, FRONT_END_GENERAL_CHECK(input_outputs_vector.size() == 1, "Input created with pruning must have one output"); ng_inputs.push_back(input_outputs_vector.at(0)); - named_inputs[input_port_idx] = {input_outputs_vector.at(0)}; } else if (ng_op_map.count(producer_name + ":" + std::to_string(producer_port_idx))) { const auto& input_outputs_vector = ng_op_map.at(producer_name + ":" + std::to_string(producer_port_idx)); FRONT_END_GENERAL_CHECK(input_outputs_vector.size() == 1, "Input created with pruning must have one output"); ng_inputs.push_back(input_outputs_vector.at(0)); - named_inputs[input_port_idx] = {input_outputs_vector.at(0)}; } else if (ng_op_map.count(producer_name)) { const auto& input_outputs_vector = ng_op_map.at(producer_name); FRONT_END_GENERAL_CHECK(input_outputs_vector.size() > producer_port_idx, "Input created with pruning must have one output"); ng_inputs.push_back(input_outputs_vector.at(producer_port_idx)); - named_inputs[input_port_idx] = {input_outputs_vector.at(producer_port_idx)}; } else { FRONT_END_GENERAL_CHECK(false, "No input is found for node \"" + operation_name + "\" by port" + @@ -165,7 +156,7 @@ void FrontEnd::translate_graph(const ov::frontend::InputModel::Ptr& model, auto op_fun = &(translate_map[operation_decoder->get_op_type()]); // NodeContext node_context(ng_inputs, operation_decoder, model_inputs); // TODO: Check why NodeContextNew doesn't have ngOutputVector ng_inputs input in constructor - ::ov::frontend::tensorflow::NodeContext node_context(*operation_decoder, named_inputs); + NodeContext node_context(*operation_decoder, ng_inputs); // generate OV node output vector using translator for given operation type ng_outputs = (*op_fun)(node_context); } catch (...) { @@ -385,5 +376,18 @@ void FrontEnd::add_extension(const std::shared_ptr& extension) { m_telemetry = telemetry; } else if (auto transformation = std::dynamic_pointer_cast(extension)) { m_transformation_extensions.push_back(transformation); + } else if (const auto& so_ext = std::dynamic_pointer_cast(extension)) { + add_extension(so_ext->extension()); + m_extensions.push_back(so_ext); + } else if (auto common_conv_ext = std::dynamic_pointer_cast(extension)) { + m_conversion_extensions.push_back(common_conv_ext); + m_op_translators[common_conv_ext->get_op_type()] = [=](const NodeContext& context) { + return common_conv_ext->get_converter()(context); + }; + } else if (const auto& tensorflow_conv_ext = std::dynamic_pointer_cast(extension)) { + m_conversion_extensions.push_back(tensorflow_conv_ext); + m_op_translators[tensorflow_conv_ext->get_op_type()] = [=](const NodeContext& context) { + return tensorflow_conv_ext->get_converter()(context); + }; } } diff --git a/src/frontends/tensorflow/src/input_model.cpp b/src/frontends/tensorflow/src/input_model.cpp index e9082b11cf0..f2a80d077fe 100644 --- a/src/frontends/tensorflow/src/input_model.cpp +++ b/src/frontends/tensorflow/src/input_model.cpp @@ -7,9 +7,9 @@ #include #include -#include "node_context.hpp" #include "openvino/frontend/exception.hpp" #include "openvino/frontend/tensorflow/graph_iterator.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" #include "openvino/opsets/opset7.hpp" #include "place.hpp" #include "utils.hpp" @@ -116,8 +116,8 @@ void InputModel::InputModelTFImpl::loadPlaces() { m_op_places.push_back(op_place); m_op_places_map[op_name] = op_place; if (op_type == "Placeholder") { - auto pshape = node_decoder->get_attribute("shape", typeid(ov::PartialShape)).as(); - auto type = node_decoder->get_attribute("dtype", typeid(ov::element::Type)).as(); + auto pshape = node_decoder->get_attribute("shape").as(); + auto type = node_decoder->get_attribute("dtype").as(); std::vector names = {op_name}; auto tensor_place = std::make_shared(m_input_model, pshape, type, names); m_tensor_places[op_name] = tensor_place; diff --git a/src/frontends/tensorflow/src/input_model.hpp b/src/frontends/tensorflow/src/input_model.hpp index 0514ad620d1..e8f96365c30 100644 --- a/src/frontends/tensorflow/src/input_model.hpp +++ b/src/frontends/tensorflow/src/input_model.hpp @@ -4,10 +4,10 @@ #pragma once +#include "input_model.hpp" #include "openvino/frontend/extension/telemetry.hpp" -#include "openvino/frontend/input_model.hpp" -#include "openvino/frontend/place.hpp" #include "openvino/frontend/tensorflow/graph_iterator.hpp" +#include "place.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/tensorflow/src/op/addN.cpp b/src/frontends/tensorflow/src/op/addN.cpp index 2fdb06bf296..4ce1afa02c2 100644 --- a/src/frontends/tensorflow/src/op/addN.cpp +++ b/src/frontends/tensorflow/src/op/addN.cpp @@ -16,7 +16,10 @@ namespace tensorflow { namespace op { OutputVector translate_add_n_op(const NodeContext& node) { - OutputVector ng_arg_vec = node.get_all_inputs(); + OutputVector ng_arg_vec; + for (size_t i = 0; i < node.get_input_size(); i++) { + ng_arg_vec.push_back(node.get_input(i)); + } auto res = std::accumulate(std::next(ng_arg_vec.begin()), ng_arg_vec.end(), ng_arg_vec.at(0), diff --git a/src/frontends/tensorflow/src/op/avg_pool.cpp b/src/frontends/tensorflow/src/op/avg_pool.cpp index 261b9ee67d4..f44b5748b50 100644 --- a/src/frontends/tensorflow/src/op/avg_pool.cpp +++ b/src/frontends/tensorflow/src/op/avg_pool.cpp @@ -16,8 +16,8 @@ namespace op { OutputVector translate_avg_pool_op(const NodeContext& node) { Output ng_input = node.get_input(0); - auto tf_strides = node.get_attribute>("strides"); - auto tf_ksize = node.get_attribute>("ksize"); + auto tf_strides = node.get_attribute>("strides"); + auto tf_ksize = node.get_attribute>("ksize"); auto tf_padding_type = node.get_attribute("padding"); auto tf_data_format = node.get_attribute("data_format"); diff --git a/src/frontends/tensorflow/src/op/conv_2d.cpp b/src/frontends/tensorflow/src/op/conv_2d.cpp index b50c4e1fbce..5ee7e74a56a 100644 --- a/src/frontends/tensorflow/src/op/conv_2d.cpp +++ b/src/frontends/tensorflow/src/op/conv_2d.cpp @@ -16,8 +16,8 @@ namespace op { OutputVector translate_conv_2d_op(const NodeContext& node) { auto ng_input = node.get_input(0), ng_filter = node.get_input(1); - auto tf_strides = node.get_attribute>("strides"); - auto tf_dilations = node.get_attribute>("dilations"); + auto tf_strides = node.get_attribute>("strides"); + auto tf_dilations = node.get_attribute>("dilations"); auto tf_padding_type = node.get_attribute("padding"); auto tf_data_format = node.get_attribute("data_format"); diff --git a/src/frontends/tensorflow/src/op/conv_2d_backprop.cpp b/src/frontends/tensorflow/src/op/conv_2d_backprop.cpp index 8eb1f900885..9ebf056eb70 100644 --- a/src/frontends/tensorflow/src/op/conv_2d_backprop.cpp +++ b/src/frontends/tensorflow/src/op/conv_2d_backprop.cpp @@ -17,8 +17,8 @@ OutputVector translate_conv_2d_backprop_input_op(const NodeContext& node) { auto ng_filter = node.get_input(1), ng_out_backprop = node.get_input(2); // TODO: refactor me to be less redundant with other convolution ops - auto tf_strides = node.get_attribute>("strides"); - auto tf_dilations = node.get_attribute>("dilations"); + auto tf_strides = node.get_attribute>("strides"); + auto tf_dilations = node.get_attribute>("dilations"); auto tf_padding_type = node.get_attribute("padding"); auto tf_data_format = node.get_attribute("data_format"); diff --git a/src/frontends/tensorflow/src/op/conv_3d.cpp b/src/frontends/tensorflow/src/op/conv_3d.cpp index ab9cc7fcc7e..a6710b42973 100644 --- a/src/frontends/tensorflow/src/op/conv_3d.cpp +++ b/src/frontends/tensorflow/src/op/conv_3d.cpp @@ -17,8 +17,8 @@ namespace op { OutputVector translate_conv_3d_op(const NodeContext& node) { auto ng_input = node.get_input(0), ng_filter = node.get_input(1); - auto tf_strides = node.get_attribute>("strides"); - auto tf_dilations = node.get_attribute>("dilations"); + auto tf_strides = node.get_attribute>("strides"); + auto tf_dilations = node.get_attribute>("dilations"); auto tf_padding_type = node.get_attribute("padding"); auto tf_data_format = node.get_attribute("data_format"); diff --git a/src/frontends/tensorflow/src/op/depthwise_conv_2d.cpp b/src/frontends/tensorflow/src/op/depthwise_conv_2d.cpp index 81b13ed0930..34f2389965b 100644 --- a/src/frontends/tensorflow/src/op/depthwise_conv_2d.cpp +++ b/src/frontends/tensorflow/src/op/depthwise_conv_2d.cpp @@ -17,8 +17,8 @@ OutputVector translate_depthwise_conv_2d_native_op(const NodeContext& node) { auto ng_input = node.get_input(0); auto ng_filter = node.get_input(1); - auto tf_strides = node.get_attribute>("strides"); - auto tf_dilations = node.get_attribute>("dilations"); + auto tf_strides = node.get_attribute>("strides"); + auto tf_dilations = node.get_attribute>("dilations"); auto tf_padding_type = node.get_attribute("padding"); auto tf_data_format = node.get_attribute("data_format"); diff --git a/src/frontends/tensorflow/src/op/elu.cpp b/src/frontends/tensorflow/src/op/elu.cpp index ef8a11d0e51..c828c50f243 100644 --- a/src/frontends/tensorflow/src/op/elu.cpp +++ b/src/frontends/tensorflow/src/op/elu.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "node_context.hpp" #include "op_table.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" #include "openvino/opsets/opset8.hpp" using namespace std; diff --git a/src/frontends/tensorflow/src/op/max_pool.cpp b/src/frontends/tensorflow/src/op/max_pool.cpp index 3c28aded3fb..53873b29444 100644 --- a/src/frontends/tensorflow/src/op/max_pool.cpp +++ b/src/frontends/tensorflow/src/op/max_pool.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "op_table.hpp" +#include "openvino/opsets/opset7.hpp" using namespace std; using namespace ov; @@ -18,8 +17,8 @@ namespace op { OutputVector translate_max_pool_op(const NodeContext& node) { auto ng_input = node.get_input(0); - auto tf_strides = node.get_attribute>("strides"); - auto tf_ksize = node.get_attribute>("ksize"); + auto tf_strides = node.get_attribute>("strides"); + auto tf_ksize = node.get_attribute>("ksize"); auto tf_padding_type = node.get_attribute("padding"); auto tf_data_format = node.get_attribute("data_format"); diff --git a/src/frontends/tensorflow/src/op/select.cpp b/src/frontends/tensorflow/src/op/select.cpp index 7114e390793..de81d16e05b 100644 --- a/src/frontends/tensorflow/src/op/select.cpp +++ b/src/frontends/tensorflow/src/op/select.cpp @@ -13,7 +13,7 @@ namespace frontend { namespace tensorflow { namespace op { OutputVector translate_select_op(const NodeContext& node) { - TENSORFLOW_OP_VALIDATION(node, node.get_all_inputs().size() == 3, "Select op cannot be converted"); + TENSORFLOW_OP_VALIDATION(node, node.get_input_size() == 3, "Select op cannot be converted"); auto in_1 = node.get_input(0); auto in_2 = node.get_input(1); auto in_3 = node.get_input(2); diff --git a/src/frontends/tensorflow/src/op/softmax.cpp b/src/frontends/tensorflow/src/op/softmax.cpp index 46d2fdb800d..e0040c14ae6 100644 --- a/src/frontends/tensorflow/src/op/softmax.cpp +++ b/src/frontends/tensorflow/src/op/softmax.cpp @@ -2,9 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 // -#include - #include "op_table.hpp" +#include "openvino/opsets/opset7.hpp" using namespace std; using namespace ov::opset8; diff --git a/src/frontends/tensorflow/src/op/squeeze.cpp b/src/frontends/tensorflow/src/op/squeeze.cpp index 81f406053f5..730cb4b2dc0 100644 --- a/src/frontends/tensorflow/src/op/squeeze.cpp +++ b/src/frontends/tensorflow/src/op/squeeze.cpp @@ -15,7 +15,7 @@ namespace op { OutputVector translate_squeeze_op(const NodeContext& node) { auto input = node.get_input(0); - auto axes = node.get_attribute>("squeeze_dims"); + auto axes = node.get_attribute>("squeeze_dims"); auto axes_const = make_shared(element::i32, Shape{axes.size()}, axes); auto res = make_shared(input, axes_const); set_node_name(node.get_name(), res); diff --git a/src/frontends/tensorflow/src/op_table.cpp b/src/frontends/tensorflow/src/op_table.cpp index 045bdff39bd..9ab49e012f9 100644 --- a/src/frontends/tensorflow/src/op_table.cpp +++ b/src/frontends/tensorflow/src/op_table.cpp @@ -93,7 +93,7 @@ OP_CONVERTER(translate_where_op); OP_CONVERTER(translate_x_div_y_op); OP_CONVERTER(translate_zeros_like_op); -const std::map get_supported_ops() { +const std::map get_supported_ops() { return { // note: UnaryOp translator declaration for each op must to be added in unary_op.cpp file {"Abs", translate_unary_op}, diff --git a/src/frontends/tensorflow/src/op_table.hpp b/src/frontends/tensorflow/src/op_table.hpp index de94b4f816c..2fe31104171 100644 --- a/src/frontends/tensorflow/src/op_table.hpp +++ b/src/frontends/tensorflow/src/op_table.hpp @@ -8,8 +8,8 @@ #include #include -#include "node_context.hpp" #include "openvino/core/node_vector.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" #include "openvino_conversions.hpp" #include "utils.hpp" @@ -17,9 +17,8 @@ namespace ov { namespace frontend { namespace tensorflow { namespace op { -using CreatorFunction = std::function<::ov::OutputVector(const ::ov::frontend::tensorflow::NodeContext&)>; -const std::map get_supported_ops(); +const std::map get_supported_ops(); } // namespace op } // namespace tensorflow } // namespace frontend diff --git a/src/frontends/tensorflow/src/place.cpp b/src/frontends/tensorflow/src/place.cpp index b63f04ab280..7899d3ba46f 100644 --- a/src/frontends/tensorflow/src/place.cpp +++ b/src/frontends/tensorflow/src/place.cpp @@ -4,9 +4,9 @@ #include "place.hpp" -#include "node_context.hpp" #include "op_def.pb.h" #include "openvino/frontend/exception.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" #include "tensor.pb.h" #include "types.pb.h" diff --git a/src/frontends/tensorflow/src/utils.hpp b/src/frontends/tensorflow/src/utils.hpp index 1b65b080668..a224e81dfa8 100644 --- a/src/frontends/tensorflow/src/utils.hpp +++ b/src/frontends/tensorflow/src/utils.hpp @@ -21,8 +21,8 @@ #pragma once #include "graph_iterator_proto.hpp" -#include "node_context.hpp" #include "openvino/core/validation_util.hpp" +#include "openvino/frontend/tensorflow/node_context.hpp" #include "openvino/opsets/opset8.hpp" #include "openvino/util/log.hpp" #include "openvino_conversions.hpp" @@ -91,8 +91,9 @@ void get_const_input(const NodeContext& node, int64_t input_index, std::vector void values_from_const_node(const NodeContext& node, ov::Shape* const_tensor_shape, std::vector* values) { TENSORFLOW_OP_VALIDATION(node, node.get_op_type() == "Const", "Node is expected to be Constant."); - auto dt = node.get_attribute<::tensorflow::DataType>("dtype"); - auto tensor_proto = node.get_attribute<::tensorflow::TensorProto>("value"); + const auto* decoder = node.get_decoder(); + auto dt = decoder->get_native_attribute("dtype").as<::tensorflow::DataType>(); + auto tensor_proto = decoder->get_native_attribute("value").as<::tensorflow::TensorProto>(); const ::tensorflow::TensorShapeProto& shape = tensor_proto.tensor_shape(); ov::PartialShape pshape; tf_shape_to_ov_shape(shape, &pshape);