FrontEnd ConversionExtensions (#9070)
* Squash commit: implement Conversion extensions * Refactor PaddlePaddle FrontEnd * Codestyle * FrontEnd,InputModel,Place base classes -> abstract, renamed model file * Fix unit tests * fix unit tests * ngraph:: to ov:: * Rename frontends dir to frontend * fix merge conflicts * Fix ConversionExtension * get rid of NamedInputs/Outputs in TF FE * Rename paddlepaddle to paddle; pdpd to paddle * add missing file * codestyle * Remove local change * paddlepaddle -> paddle for azure configs and .md files * fix package name, fix config files * Fix win build * Revert Broadcast/AutoBroadcast changes * codestyle * fix FronEnd class * fix ngraph_cpp_api.config * fix incorrect merge, codestyle * fix conversion extension * conversion extension * codestyle * merge master * fix build * refactoring; revert broadcast/autobroadcast changes * codestyle * fix MacOS config * resolve merge conflicts * refactor includes * register ConversionExtension in FrontEnds * move get_op_type to base NodeContex class * set op_translator map in ctor of Paddle FE; fix unit tests * update unit tests; codestyle * codestyle * preliminary version of conversion extension in pybind * conversion extension * get_attribute_as_any method for NodeContext * move get_attribute methods to NodeContext base class, rename get_ng_input to get_input * add missed file * Implement ov::Any getter in ONNX NodeContext * fix py bindings * Add update ConversionExtension unit tests, add SO unit tests, fix TF FE * fix segfault on destructor * fix NodeContext interface, fix unit tests * set different names for ConversionExtensions in unit tests * fix PaddleFuzzy tests * fix Paddle Fuzzy tests * revert changes in generate_slice.py * fix codestyle * fix pybindings * revert local changes in generate_slice.py * delete duplicate exceptions.hpp * Refactoring: fix names according to convention * pybinding for NodeContext, FrontEnd, ConversionExtension; fix unit tests; implement new unit tests * Refactoring * fix the case when a new converter rewrites existed one; delete unnecessary NodeContext from pybindings; use CreatorFunctons from the base class in ConversionExtension; update unit tests * Revert local change * PythonAPI: fix get_attribute method; fix get_input method; implement support of dtype and default attributes * Fix py unit tests: add support for vector<ov::element::Type> as attribute * resolve review comments * fix unit tests * move extension_holder to openvino/frontend/extension folder * fix build on mac os * temporary disable cast from vector<bool> to investigate issue on mac os * Resolve review comments * Resolve review comments * Use dev API for .so extension * Link frontends to pyopenvino as separate targets * Temporary enable tf fe installation * ignore PEP8 E402 for init files, set correct directory for py modules * revert local changes * Fix deadlock in pybind GIL; fix Win build; fix PEP8 * fix PEP8 * Add a return type annotation * fix builds; fix ON/OFF switcher for ENABLE_OV_xxx_FRONTEND cmake options * Fix the issue with ifdefs on WinOS; fix the issue related to pybindings and static c++ object * fix python unit tests * fix static build on WinOS * Retrigger CI builds * Fix static build on Windows * fix static build on Windows again * Retrigger CI * delete unused includes; add a comment about issue on MacOS * fix missprint * resolve review comments * fix missprint * resolve review remarks * Resolve review comments * win win wheels build * resolve review comments
This commit is contained in:
parent
ff6a9a1179
commit
29d73ce3c8
@ -9,7 +9,7 @@ enable-extensions = G
|
|||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
*.pyx: E225, E226, E251, E999, E800, E265, E203, E266, E227, E211
|
*.pyx: E225, E226, E251, E999, E800, E265, E203, E266, E227, E211
|
||||||
tests/*: S101, T001
|
tests/*: S101, T001
|
||||||
*__init__.py: F403, F405, F405
|
*__init__.py: E402, F403, F405, F405
|
||||||
|
|
||||||
[pydocstyle]
|
[pydocstyle]
|
||||||
convention = google
|
convention = google
|
||||||
|
@ -8,42 +8,23 @@ Low level wrappers for the FrontEnd c++ api.
|
|||||||
|
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
|
|
||||||
import os
|
from openvino.utils import add_openvino_libs_to_path
|
||||||
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"]
|
|
||||||
|
|
||||||
|
add_openvino_libs_to_path()
|
||||||
|
|
||||||
# main classes
|
# main classes
|
||||||
from openvino.pyopenvino import FrontEndManager
|
from openvino.pyopenvino import FrontEndManager
|
||||||
from openvino.pyopenvino import FrontEnd
|
from openvino.pyopenvino import FrontEnd
|
||||||
from openvino.pyopenvino import InputModel
|
from openvino.pyopenvino import InputModel
|
||||||
|
from openvino.pyopenvino import NodeContext
|
||||||
from openvino.pyopenvino import Place
|
from openvino.pyopenvino import Place
|
||||||
from openvino.pyopenvino import TelemetryExtension
|
|
||||||
|
# extensions
|
||||||
from openvino.pyopenvino import DecoderTransformationExtension
|
from openvino.pyopenvino import DecoderTransformationExtension
|
||||||
from openvino.pyopenvino import JsonConfigExtension
|
from openvino.pyopenvino import JsonConfigExtension
|
||||||
|
from openvino.pyopenvino import ConversionExtension
|
||||||
from openvino.pyopenvino import ProgressReporterExtension
|
from openvino.pyopenvino import ProgressReporterExtension
|
||||||
|
from openvino.pyopenvino import TelemetryExtension
|
||||||
|
|
||||||
# exceptions
|
# exceptions
|
||||||
from openvino.pyopenvino import NotImplementedFailure
|
from openvino.pyopenvino import NotImplementedFailure
|
||||||
|
19
src/bindings/python/src/openvino/frontend/onnx/__init__.py
Normal file
19
src/bindings/python/src/openvino/frontend/onnx/__init__.py
Normal file
@ -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))
|
20
src/bindings/python/src/openvino/frontend/paddle/__init__.py
Normal file
20
src/bindings/python/src/openvino/frontend/paddle/__init__.py
Normal file
@ -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))
|
@ -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))
|
@ -2,32 +2,11 @@
|
|||||||
# Copyright (C) 2018-2022 Intel Corporation
|
# Copyright (C) 2018-2022 Intel Corporation
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import os
|
# flake8: noqa
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.platform == "win32":
|
from openvino.utils import add_openvino_libs_to_path
|
||||||
# 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()
|
||||||
|
|
||||||
from openvino.pyopenvino.offline_transformations import apply_moc_transformations
|
from openvino.pyopenvino.offline_transformations import apply_moc_transformations
|
||||||
from openvino.pyopenvino.offline_transformations import apply_moc_legacy_transformations
|
from openvino.pyopenvino.offline_transformations import apply_moc_legacy_transformations
|
||||||
|
@ -8,32 +8,9 @@ Low level wrappers for the PrePostProcessing c++ api.
|
|||||||
|
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
|
|
||||||
import os
|
from openvino.utils import add_openvino_libs_to_path
|
||||||
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"]
|
|
||||||
|
|
||||||
|
add_openvino_libs_to_path()
|
||||||
|
|
||||||
# main classes
|
# main classes
|
||||||
from openvino.pyopenvino.preprocess import InputInfo
|
from openvino.pyopenvino.preprocess import InputInfo
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
"""openvino module namespace, exposing factory functions for all ops and other classes."""
|
"""openvino module namespace, exposing factory functions for all ops and other classes."""
|
||||||
# noqa: F401
|
# noqa: F401
|
||||||
|
|
||||||
import os
|
from openvino.utils import add_openvino_libs_to_path
|
||||||
import sys
|
|
||||||
|
|
||||||
from pkg_resources import get_distribution, DistributionNotFound
|
from pkg_resources import get_distribution, DistributionNotFound
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -14,33 +12,7 @@ try:
|
|||||||
except DistributionNotFound:
|
except DistributionNotFound:
|
||||||
__version__ = "0.0.0.dev0"
|
__version__ = "0.0.0.dev0"
|
||||||
|
|
||||||
if sys.platform == "win32":
|
add_openvino_libs_to_path()
|
||||||
# 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"]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Openvino pybind bindings and python extended classes
|
# Openvino pybind bindings and python extended classes
|
||||||
from openvino.pyopenvino import Dimension
|
from openvino.pyopenvino import Dimension
|
||||||
|
31
src/bindings/python/src/openvino/utils.py
Normal file
31
src/bindings/python/src/openvino/utils.py
Normal file
@ -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"]
|
@ -48,9 +48,22 @@ if(ENABLE_TESTS)
|
|||||||
add_subdirectory(test_utils)
|
add_subdirectory(test_utils)
|
||||||
endif()
|
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
|
# create target
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES core/*.cpp graph/*.cpp frontend/*.cpp pyopenvino.cpp)
|
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})
|
pybind11_add_module(${PROJECT_NAME} MODULE ${SOURCES})
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "extension/json_config.hpp"
|
#include "extension/json_config.hpp"
|
||||||
#include "manager.hpp"
|
#include "manager.hpp"
|
||||||
#include "openvino/frontend/exception.hpp"
|
#include "openvino/frontend/exception.hpp"
|
||||||
|
#include "openvino/frontend/extension/conversion.hpp"
|
||||||
#include "openvino/frontend/extension/decoder_transformation.hpp"
|
#include "openvino/frontend/extension/decoder_transformation.hpp"
|
||||||
#include "openvino/frontend/extension/progress_reporter_extension.hpp"
|
#include "openvino/frontend/extension/progress_reporter_extension.hpp"
|
||||||
#include "openvino/frontend/extension/telemetry.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_<ConversionExtensionBase, ConversionExtensionBase::Ptr, ov::Extension> ext(m,
|
||||||
|
"ConversionExtensionBase",
|
||||||
|
py::dynamic_attr());
|
||||||
|
}
|
||||||
|
|
||||||
|
void regclass_frontend_ConversionExtension(py::module m) {
|
||||||
|
py::class_<ConversionExtension, ConversionExtension::Ptr, ConversionExtensionBase> _ext(m,
|
||||||
|
"_ConversionExtension",
|
||||||
|
py::dynamic_attr(),
|
||||||
|
py::module_local());
|
||||||
|
class PyConversionExtension : public ConversionExtension {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<PyConversionExtension>;
|
||||||
|
using PyCreatorFunction = std::function<ov::OutputVector(const NodeContext*)>;
|
||||||
|
using PyCreatorFunctionNamed = std::function<std::map<std::string, ov::OutputVector>(const NodeContext*)>;
|
||||||
|
PyConversionExtension(const std::string& op_type, const PyCreatorFunction& f)
|
||||||
|
: ConversionExtension(op_type, [f](const NodeContext& node) -> ov::OutputVector {
|
||||||
|
return f(static_cast<const NodeContext*>(&node));
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
PyConversionExtension(const std::string& op_type, const PyCreatorFunctionNamed& f)
|
||||||
|
: ConversionExtension(op_type, [f](const NodeContext& node) -> std::map<std::string, ov::OutputVector> {
|
||||||
|
return f(static_cast<const NodeContext*>(&node));
|
||||||
|
}) {}
|
||||||
|
};
|
||||||
|
py::class_<PyConversionExtension, PyConversionExtension::Ptr, ConversionExtension> ext(m,
|
||||||
|
"ConversionExtension",
|
||||||
|
py::dynamic_attr());
|
||||||
|
|
||||||
|
ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunction& f) {
|
||||||
|
return std::make_shared<PyConversionExtension>(op_type, f);
|
||||||
|
}));
|
||||||
|
|
||||||
|
ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunctionNamed& f) {
|
||||||
|
return std::make_shared<PyConversionExtension>(op_type, f);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
void regclass_frontend_ProgressReporterExtension(py::module m) {
|
void regclass_frontend_ProgressReporterExtension(py::module m) {
|
||||||
py::class_<ProgressReporterExtension, std::shared_ptr<ProgressReporterExtension>, ov::Extension> ext{
|
py::class_<ProgressReporterExtension, std::shared_ptr<ProgressReporterExtension>, ov::Extension> ext{
|
||||||
m,
|
m,
|
@ -11,4 +11,6 @@ namespace py = pybind11;
|
|||||||
void regclass_frontend_TelemetryExtension(py::module m);
|
void regclass_frontend_TelemetryExtension(py::module m);
|
||||||
void regclass_frontend_DecoderTransformationExtension(py::module m);
|
void regclass_frontend_DecoderTransformationExtension(py::module m);
|
||||||
void regclass_frontend_JsonConfigExtension(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);
|
void regclass_frontend_ProgressReporterExtension(py::module m);
|
@ -18,7 +18,7 @@ using namespace ov::frontend;
|
|||||||
|
|
||||||
void regclass_frontend_FrontEnd(py::module m) {
|
void regclass_frontend_FrontEnd(py::module m) {
|
||||||
py::class_<FrontEnd, std::shared_ptr<FrontEnd>> fem(m, "FrontEnd", py::dynamic_attr(), py::module_local());
|
py::class_<FrontEnd, std::shared_ptr<FrontEnd>> 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(
|
fem.def(
|
||||||
"load",
|
"load",
|
||||||
|
@ -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()
|
127
src/bindings/python/src/pyopenvino/frontend/node_context.cpp
Normal file
127
src/bindings/python/src/pyopenvino/frontend/node_context.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "node_context.hpp"
|
||||||
|
|
||||||
|
#include <pybind11/functional.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
#include <pybind11/stl_bind.h>
|
||||||
|
|
||||||
|
#include "openvino/frontend/node_context.hpp"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
using namespace ov::frontend;
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
struct is_std_vector : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T, typename A>
|
||||||
|
struct is_std_vector<std::vector<T, A>> : std::true_type {};
|
||||||
|
|
||||||
|
#define CAST_VEC_TO_PY(any, py_type, c_type) \
|
||||||
|
{ \
|
||||||
|
static_assert(is_std_vector<c_type>(), "The type should be std::vector."); \
|
||||||
|
if ((any).is<c_type>()) { \
|
||||||
|
auto casted = (any).as<c_type>(); \
|
||||||
|
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<c_type>()) { \
|
||||||
|
auto casted = (any).as<c_type>(); \
|
||||||
|
if (!(py_type).is_none()) { \
|
||||||
|
return py_type(casted); \
|
||||||
|
} \
|
||||||
|
return py::cast(casted); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
void regclass_frontend_NodeContext(py::module m) {
|
||||||
|
py::class_<ov::frontend::NodeContext, std::shared_ptr<ov::frontend::NodeContext>> 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<int32_t>() || any.is<int64_t>()) {
|
||||||
|
return py::cast(self.get_attribute<ov::element::Type>(name));
|
||||||
|
} else if (any.is<std::vector<int32_t>>() || any.is<std::vector<int64_t>>()) {
|
||||||
|
return py::cast(self.get_attribute<std::vector<ov::element::Type>>(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<int32_t>);
|
||||||
|
CAST_VEC_TO_PY(any, dtype, std::vector<int64_t>);
|
||||||
|
#ifndef __APPLE__
|
||||||
|
// TODO: investigate the issue in pybind11 on MacOS
|
||||||
|
CAST_VEC_TO_PY(any, dtype, std::vector<bool>);
|
||||||
|
#endif
|
||||||
|
CAST_VEC_TO_PY(any, dtype, std::vector<std::string>);
|
||||||
|
CAST_VEC_TO_PY(any, dtype, std::vector<float>);
|
||||||
|
CAST_VEC_TO_PY(any, dtype, std::vector<ov::element::Type>);
|
||||||
|
CAST_VEC_TO_PY(any, dtype, std::vector<ov::PartialShape>);
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
11
src/bindings/python/src/pyopenvino/frontend/node_context.hpp
Normal file
11
src/bindings/python/src/pyopenvino/frontend/node_context.hpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
void regclass_frontend_NodeContext(py::module m);
|
@ -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})
|
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
#include <pybind11/functional.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
#include <pybind11/stl_bind.h>
|
||||||
|
|
||||||
|
#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_<ConversionExtension, ConversionExtension::Ptr, ov::frontend::ConversionExtensionBase> _ext(
|
||||||
|
m,
|
||||||
|
"_ConversionExtensionONNX",
|
||||||
|
py::dynamic_attr());
|
||||||
|
class PyConversionExtension : public ConversionExtension {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<PyConversionExtension>;
|
||||||
|
using PyCreatorFunction = std::function<ov::OutputVector(const ov::frontend::NodeContext*)>;
|
||||||
|
PyConversionExtension(const std::string& op_type, const PyCreatorFunction& f)
|
||||||
|
: ConversionExtension(op_type, [f](const ov::frontend::NodeContext& node) -> ov::OutputVector {
|
||||||
|
return f(static_cast<const ov::frontend::NodeContext*>(&node));
|
||||||
|
}) {}
|
||||||
|
};
|
||||||
|
py::class_<PyConversionExtension, PyConversionExtension::Ptr, ConversionExtension> ext(m,
|
||||||
|
"ConversionExtensionONNX",
|
||||||
|
py::dynamic_attr());
|
||||||
|
|
||||||
|
ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunction& f) {
|
||||||
|
return std::make_shared<PyConversionExtension>(op_type, f);
|
||||||
|
}));
|
||||||
|
|
||||||
|
ext.def_property_readonly_static("m_converter", &ConversionExtension::get_converter);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
void regclass_frontend_onnx_ConversionExtension(py::module m);
|
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
PYBIND11_MODULE(py_onnx_frontend, m) {
|
||||||
|
regclass_frontend_onnx_ConversionExtension(m);
|
||||||
|
}
|
@ -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})
|
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
#include <pybind11/functional.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
#include <pybind11/stl_bind.h>
|
||||||
|
|
||||||
|
#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_<ConversionExtension, ConversionExtension::Ptr, ov::frontend::ConversionExtensionBase> _ext(
|
||||||
|
m,
|
||||||
|
"_ConversionExtensionPaddle",
|
||||||
|
py::dynamic_attr());
|
||||||
|
class PyConversionExtension : public ConversionExtension {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<PyConversionExtension>;
|
||||||
|
using PyCreatorFunctionNamed =
|
||||||
|
std::function<std::map<std::string, ov::OutputVector>(const ov::frontend::NodeContext*)>;
|
||||||
|
|
||||||
|
PyConversionExtension(const std::string& op_type, const PyCreatorFunctionNamed& f)
|
||||||
|
: ConversionExtension(
|
||||||
|
op_type,
|
||||||
|
[f](const ov::frontend::NodeContext& node) -> std::map<std::string, ov::OutputVector> {
|
||||||
|
return f(static_cast<const ov::frontend::NodeContext*>(&node));
|
||||||
|
}) {}
|
||||||
|
};
|
||||||
|
py::class_<PyConversionExtension, PyConversionExtension::Ptr, ConversionExtension> ext(m,
|
||||||
|
"ConversionExtensionPaddle",
|
||||||
|
py::dynamic_attr());
|
||||||
|
|
||||||
|
ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunctionNamed& f) {
|
||||||
|
return std::make_shared<PyConversionExtension>(op_type, f);
|
||||||
|
}));
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
void regclass_frontend_paddle_ConversionExtension(py::module m);
|
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
PYBIND11_MODULE(py_paddle_frontend, m) {
|
||||||
|
regclass_frontend_paddle_ConversionExtension(m);
|
||||||
|
}
|
@ -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)
|
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
#include <pybind11/functional.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
#include <pybind11/stl_bind.h>
|
||||||
|
|
||||||
|
#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_<ConversionExtension, ConversionExtension::Ptr, ov::frontend::ConversionExtensionBase> _ext(
|
||||||
|
m,
|
||||||
|
"_ConversionExtensionTensorflow",
|
||||||
|
py::dynamic_attr());
|
||||||
|
class PyConversionExtension : public ConversionExtension {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<PyConversionExtension>;
|
||||||
|
using PyCreatorFunction = std::function<ov::OutputVector(const ov::frontend::NodeContext*)>;
|
||||||
|
PyConversionExtension(const std::string& op_type, const PyCreatorFunction& f)
|
||||||
|
: ConversionExtension(op_type, [f](const ov::frontend::NodeContext& node) -> ov::OutputVector {
|
||||||
|
return f(static_cast<const ov::frontend::NodeContext*>(&node));
|
||||||
|
}) {}
|
||||||
|
};
|
||||||
|
py::class_<PyConversionExtension, PyConversionExtension::Ptr, ConversionExtension> ext(
|
||||||
|
m,
|
||||||
|
"ConversionExtensionTensorflow",
|
||||||
|
py::dynamic_attr());
|
||||||
|
|
||||||
|
ext.def(py::init([](const std::string& op_type, const PyConversionExtension::PyCreatorFunction& f) {
|
||||||
|
return std::make_shared<PyConversionExtension>(op_type, f);
|
||||||
|
}));
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
void regclass_frontend_tensorflow_ConversionExtension(py::module m);
|
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "extension.hpp"
|
||||||
|
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
PYBIND11_MODULE(py_tensorflow_frontend, m) {
|
||||||
|
regclass_frontend_tensorflow_ConversionExtension(m);
|
||||||
|
}
|
@ -32,10 +32,11 @@
|
|||||||
#include "pyopenvino/core/tensor.hpp"
|
#include "pyopenvino/core/tensor.hpp"
|
||||||
#include "pyopenvino/core/variable_state.hpp"
|
#include "pyopenvino/core/variable_state.hpp"
|
||||||
#include "pyopenvino/core/version.hpp"
|
#include "pyopenvino/core/version.hpp"
|
||||||
#include "pyopenvino/frontend/extensions.hpp"
|
#include "pyopenvino/frontend/extension.hpp"
|
||||||
#include "pyopenvino/frontend/frontend.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/manager.hpp"
|
||||||
|
#include "pyopenvino/frontend/node_context.hpp"
|
||||||
#include "pyopenvino/frontend/place.hpp"
|
#include "pyopenvino/frontend/place.hpp"
|
||||||
#include "pyopenvino/graph/any.hpp"
|
#include "pyopenvino/graph/any.hpp"
|
||||||
#include "pyopenvino/graph/descriptors/tensor.hpp"
|
#include "pyopenvino/graph/descriptors/tensor.hpp"
|
||||||
@ -133,6 +134,7 @@ PYBIND11_MODULE(pyopenvino, m) {
|
|||||||
regclass_ProfilingInfo(m);
|
regclass_ProfilingInfo(m);
|
||||||
regclass_Extension(m);
|
regclass_Extension(m);
|
||||||
|
|
||||||
|
// frontend
|
||||||
regclass_frontend_Place(m);
|
regclass_frontend_Place(m);
|
||||||
regclass_frontend_InitializationFailureFrontEnd(m);
|
regclass_frontend_InitializationFailureFrontEnd(m);
|
||||||
regclass_frontend_GeneralFailureFrontEnd(m);
|
regclass_frontend_GeneralFailureFrontEnd(m);
|
||||||
@ -142,10 +144,16 @@ PYBIND11_MODULE(pyopenvino, m) {
|
|||||||
regclass_frontend_FrontEndManager(m);
|
regclass_frontend_FrontEndManager(m);
|
||||||
regclass_frontend_FrontEnd(m);
|
regclass_frontend_FrontEnd(m);
|
||||||
regclass_frontend_InputModel(m);
|
regclass_frontend_InputModel(m);
|
||||||
|
regclass_frontend_NodeContext(m);
|
||||||
|
|
||||||
|
// frontend extensions
|
||||||
regclass_frontend_TelemetryExtension(m);
|
regclass_frontend_TelemetryExtension(m);
|
||||||
regclass_frontend_DecoderTransformationExtension(m);
|
regclass_frontend_DecoderTransformationExtension(m);
|
||||||
regclass_frontend_JsonConfigExtension(m);
|
regclass_frontend_JsonConfigExtension(m);
|
||||||
|
regclass_frontend_ConversionExtensionBase(m);
|
||||||
|
regclass_frontend_ConversionExtension(m);
|
||||||
regclass_frontend_ProgressReporterExtension(m);
|
regclass_frontend_ProgressReporterExtension(m);
|
||||||
|
|
||||||
|
// transformations
|
||||||
regmodule_offline_transformations(m);
|
regmodule_offline_transformations(m);
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,38 @@
|
|||||||
|
|
||||||
set(TARGET_FE_NAME "ov_mock_py_frontend")
|
set(TARGET_FE_NAME "ov_mock_py_frontend")
|
||||||
|
|
||||||
file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
|
||||||
file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
|
file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
|
||||||
|
|
||||||
source_group("src" FILES ${LIBRARY_SRC})
|
source_group("src" FILES ${LIBRARY_SRC})
|
||||||
source_group("include" FILES ${LIBRARY_HEADERS})
|
source_group("include" FILES ${LIBRARY_HEADERS})
|
||||||
|
|
||||||
# Create shared library
|
add_library(${TARGET_FE_NAME} ${LIBRARY_SRC} ${LIBRARY_HEADERS})
|
||||||
add_library(${TARGET_FE_NAME} SHARED ${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})
|
add_clang_format_target(${TARGET_FE_NAME}_clang FOR_TARGETS ${TARGET_FE_NAME})
|
||||||
|
|
||||||
|
@ -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<ov::Extension>& 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<ov::Extension>& 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<ov::Extension>& 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
|
@ -4,20 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ngraph/visibility.hpp"
|
|
||||||
#include "openvino/frontend/extension/telemetry.hpp"
|
#include "openvino/frontend/extension/telemetry.hpp"
|
||||||
#include "openvino/frontend/manager.hpp"
|
#include "openvino/frontend/manager.hpp"
|
||||||
#include "openvino/frontend/visibility.hpp"
|
#include "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
|
|
||||||
|
|
||||||
// OK to have 'using' in mock header
|
// OK to have 'using' in mock header
|
||||||
|
|
||||||
using namespace ngraph;
|
using namespace ngraph;
|
||||||
using namespace ov::frontend;
|
using namespace ov::frontend;
|
||||||
|
|
@ -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
|
@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// 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/manager.hpp"
|
||||||
#include "openvino/frontend/visibility.hpp"
|
#include "openvino/frontend/visibility.hpp"
|
@ -2,7 +2,6 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
||||||
set(TARGET_FE_NAME "ov_mock_py_frontend")
|
|
||||||
set(PYBIND_FE_NAME "pybind_mock_frontend")
|
set(PYBIND_FE_NAME "pybind_mock_frontend")
|
||||||
|
|
||||||
set(PYBIND_FE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pyngraph_mock_frontend_api.cpp)
|
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})
|
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})
|
add_clang_format_target(${PYBIND_FE_NAME}_clang FOR_TARGETS ${PYBIND_FE_NAME})
|
||||||
|
|
||||||
|
@ -5,12 +5,17 @@
|
|||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
#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;
|
namespace py = pybind11;
|
||||||
using namespace ngraph;
|
using namespace ngraph;
|
||||||
using namespace ov::frontend;
|
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) {
|
static void register_mock_frontend_stat(py::module m) {
|
||||||
m.def("get_fe_stat", &FrontEndMockPy::get_stat);
|
m.def("get_fe_stat", &FrontEndMockPy::get_stat);
|
||||||
m.def("clear_fe_stat", &FrontEndMockPy::clear_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);
|
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_<FrontEndWrapperPaddle, std::shared_ptr<FrontEndWrapperPaddle>> fe_paddle(m,
|
||||||
|
"FrontEndWrapperPaddle",
|
||||||
|
py::dynamic_attr());
|
||||||
|
fe_paddle.def(py::init([]() {
|
||||||
|
return std::make_shared<FrontEndWrapperPaddle>();
|
||||||
|
}));
|
||||||
|
fe_paddle.def(
|
||||||
|
"add_extension",
|
||||||
|
static_cast<void (FrontEnd::*)(const std::shared_ptr<ov::Extension>& 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_<FrontEndWrapperTensorflow, std::shared_ptr<FrontEndWrapperTensorflow>> fe_tensorflow(
|
||||||
|
m,
|
||||||
|
"FrontEndWrapperTensorflow",
|
||||||
|
py::dynamic_attr());
|
||||||
|
fe_tensorflow.def(py::init([]() {
|
||||||
|
return std::make_shared<FrontEndWrapperTensorflow>();
|
||||||
|
}));
|
||||||
|
fe_tensorflow.def(
|
||||||
|
"add_extension",
|
||||||
|
static_cast<void (FrontEnd::*)(const std::shared_ptr<ov::Extension>& 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) {
|
PYBIND11_MODULE(pybind_mock_frontend, m) {
|
||||||
m.doc() = "Mock frontend call counters for testing Pyngraph frontend bindings";
|
m.doc() = "Mock frontend call counters for testing Pyngraph frontend bindings";
|
||||||
register_mock_frontend_stat(m);
|
register_mock_frontend_stat(m);
|
||||||
register_mock_model_stat(m);
|
register_mock_model_stat(m);
|
||||||
register_mock_place_stat(m);
|
register_mock_place_stat(m);
|
||||||
|
register_frontend_wrappers(m);
|
||||||
}
|
}
|
||||||
|
2
src/bindings/python/tests/test_frontend/__init__.py
Normal file
2
src/bindings/python/tests/test_frontend/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Copyright (C) 2021 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
@ -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")
|
@ -13,7 +13,10 @@ from tests.runtime import get_runtime
|
|||||||
|
|
||||||
def create_onnx_model():
|
def create_onnx_model():
|
||||||
add = onnx.helper.make_node("Add", inputs=["x", "y"], outputs=["z"])
|
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"],
|
const_node = onnx.helper.make_node("Constant", [], outputs=["const_node"],
|
||||||
value=const_tensor, name="const_node")
|
value=const_tensor, name="const_node")
|
||||||
mul = onnx.helper.make_node("Mul", inputs=["z", "const_node"], outputs=["out"])
|
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")
|
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):
|
def run_function(function, *inputs, expected):
|
||||||
runtime = get_runtime()
|
runtime = get_runtime()
|
||||||
computation = runtime.computation(function)
|
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)
|
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()
|
fem = FrontEndManager()
|
||||||
onnx_model_filename = "model.onnx"
|
onnx_model_filename = "model.onnx"
|
||||||
|
onnx_model_with_custom_attributes_filename = "model_custom_attributes.onnx"
|
||||||
onnx_model_with_subgraphs_filename = "model_subgraphs.onnx"
|
onnx_model_with_subgraphs_filename = "model_subgraphs.onnx"
|
||||||
ONNX_FRONTEND_NAME = "onnx"
|
ONNX_FRONTEND_NAME = "onnx"
|
||||||
|
|
||||||
|
|
||||||
def setup_module():
|
def setup_module():
|
||||||
onnx.save_model(create_onnx_model(), onnx_model_filename)
|
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)
|
onnx.save_model(create_onnx_model_with_subgraphs(), onnx_model_with_subgraphs_filename)
|
||||||
|
|
||||||
|
|
||||||
def teardown_module():
|
def teardown_module():
|
||||||
os.remove(onnx_model_filename)
|
os.remove(onnx_model_filename)
|
||||||
|
os.remove(onnx_model_with_custom_attributes_filename)
|
||||||
os.remove(onnx_model_with_subgraphs_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("test.xx")
|
||||||
assert not fem.load_by_model("onnx.yy")
|
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
|
||||||
|
@ -1367,12 +1367,14 @@ def test_set_tensor_value():
|
|||||||
|
|
||||||
def test_not_supported_methods():
|
def test_not_supported_methods():
|
||||||
skip_if_onnx_frontend_is_disabled()
|
skip_if_onnx_frontend_is_disabled()
|
||||||
|
from openvino.frontend import GeneralFailure
|
||||||
|
|
||||||
fe = fem.load_by_framework(framework=ONNX_FRONTEND_NAME)
|
fe = fem.load_by_framework(framework=ONNX_FRONTEND_NAME)
|
||||||
model = fe.load("test_place_names.onnx")
|
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")
|
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():
|
def test_set_name_for_tensor():
|
||||||
@ -1389,18 +1391,18 @@ def test_set_name_for_tensor():
|
|||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
model.set_name_for_tensor(tensor=tensor, new_name="")
|
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
|
# ONNX model stores tensor info separately for inputs, outputs and between nodes tensors
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
model.set_name_for_tensor(tensor=tensor, new_name="in1")
|
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:
|
with pytest.raises(Exception) as e:
|
||||||
model.set_name_for_tensor(tensor=tensor, new_name="out1")
|
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:
|
with pytest.raises(Exception) as e:
|
||||||
model.set_name_for_tensor(tensor=tensor, new_name="sub_out")
|
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
|
# actual rename
|
||||||
model.set_name_for_tensor(tensor=tensor, new_name=new_name)
|
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:
|
with pytest.raises(Exception) as e:
|
||||||
model.set_name_for_dimension(input1, 0, "")
|
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")
|
one_const = model.get_place_by_tensor_name(tensor_name="one_const")
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
model.set_name_for_dimension(one_const, 0, dim_name)
|
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():
|
def test_set_input_partial_shape_using_input_edge():
|
||||||
|
@ -22,7 +22,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<Extension::Ptr> m_loaded_extensions;
|
std::vector<Extension::Ptr> m_loaded_extensions;
|
||||||
std::vector<std::pair<std::shared_ptr<DecoderTransformationExtension>, std::string>> m_target_extensions;
|
std::vector<std::pair<DecoderTransformationExtension::Ptr, std::string>> m_target_extensions;
|
||||||
};
|
};
|
||||||
} // namespace frontend
|
} // namespace frontend
|
||||||
} // namespace ov
|
} // namespace ov
|
||||||
|
@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
|||||||
|
|
||||||
add_executable(${TARGET_NAME} ${SRC})
|
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})
|
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
||||||
|
|
||||||
|
52
src/core/tests/frontend/onnx/conversion.cpp
Normal file
52
src/core/tests/frontend/onnx/conversion.cpp
Normal file
@ -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<ov::Extension>& extension) override {
|
||||||
|
ov::frontend::onnx::FrontEnd::add_extension(extension);
|
||||||
|
if (auto conv_ext = std::dynamic_pointer_cast<ConversionExtension>(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<TelemetryExtension>(extension)) {
|
||||||
|
EXPECT_EQ(m_extensions.telemetry, telemetry) << "TelemetryExtension is not registered.";
|
||||||
|
} else if (auto transformation = std::dynamic_pointer_cast<DecoderTransformationExtension>(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<ov::detail::SOExtension>(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<ONNXFrontendWrapper>();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(ONNXConversionExtensionTest,
|
||||||
|
FrontEndConversionExtensionTest,
|
||||||
|
::testing::Values(getTestData()),
|
||||||
|
FrontEndConversionExtensionTest::getTestCaseName);
|
@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
|||||||
|
|
||||||
add_executable(${TARGET_NAME} ${SRC})
|
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})
|
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
||||||
|
|
||||||
|
53
src/core/tests/frontend/paddle/conversion.cpp
Normal file
53
src/core/tests/frontend/paddle/conversion.cpp
Normal file
@ -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<ov::Extension>& extension) override {
|
||||||
|
ov::frontend::paddle::FrontEnd::add_extension(extension);
|
||||||
|
|
||||||
|
if (auto conv_ext = std::dynamic_pointer_cast<ConversionExtension>(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<TelemetryExtension>(extension)) {
|
||||||
|
EXPECT_EQ(m_telemetry, telemetry) << "TelemetryExtension is not registered.";
|
||||||
|
} else if (auto transformation = std::dynamic_pointer_cast<DecoderTransformationExtension>(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<ov::detail::SOExtension>(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<PaddleFrontendWrapper>();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(PDPDConversionExtensionTest,
|
||||||
|
FrontEndConversionExtensionTest,
|
||||||
|
::testing::Values(getTestData()),
|
||||||
|
FrontEndConversionExtensionTest::getTestCaseName);
|
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <openvino/frontend/extension/conversion.hpp>
|
||||||
|
#include <openvino/frontend/manager.hpp>
|
||||||
|
|
||||||
|
struct ConversionExtensionFEParam {
|
||||||
|
std::string m_frontEndName;
|
||||||
|
std::string m_modelsPath;
|
||||||
|
std::string m_modelName;
|
||||||
|
std::string m_translatorName;
|
||||||
|
std::shared_ptr<ov::frontend::FrontEnd> m_frontend;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FrontEndConversionExtensionTest : public ::testing::TestWithParam<ConversionExtensionFEParam> {
|
||||||
|
public:
|
||||||
|
ConversionExtensionFEParam m_param;
|
||||||
|
ov::frontend::FrontEndManager m_fem;
|
||||||
|
|
||||||
|
static std::string getTestCaseName(const testing::TestParamInfo<ConversionExtensionFEParam>& obj);
|
||||||
|
|
||||||
|
void SetUp() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initParamTest();
|
||||||
|
};
|
@ -19,7 +19,7 @@ public:
|
|||||||
return m_loaded_extensions;
|
return m_loaded_extensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::pair<std::shared_ptr<DecoderTransformationExtension>, std::string>> get_target_extensions() {
|
std::vector<std::pair<DecoderTransformationExtension::Ptr, std::string>> get_target_extensions() {
|
||||||
return m_target_extensions;
|
return m_target_extensions;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
87
src/core/tests/frontend/shared/src/conversion.cpp
Normal file
87
src/core/tests/frontend/shared/src/conversion.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <openvino/frontend/extension/conversion.hpp>
|
||||||
|
#include <openvino/frontend/extension/decoder_transformation.hpp>
|
||||||
|
#include <openvino/op/util/framework_node.hpp>
|
||||||
|
#include <openvino/opsets/opset8.hpp>
|
||||||
|
|
||||||
|
#include "conversion_extension.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
using namespace ov::frontend;
|
||||||
|
|
||||||
|
std::string FrontEndConversionExtensionTest::getTestCaseName(
|
||||||
|
const testing::TestParamInfo<ConversionExtensionFEParam>& 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<char>(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<ConversionExtension>(
|
||||||
|
m_param.m_translatorName,
|
||||||
|
[&](const NodeContext& node) -> std::map<std::string, ov::OutputVector> {
|
||||||
|
auto relu = std::make_shared<ov::opset8::Relu>(node.get_input("X"));
|
||||||
|
invoked = true;
|
||||||
|
return {{"Out", {relu}}};
|
||||||
|
}));
|
||||||
|
} else if (m_param.m_frontEndName == "tf") {
|
||||||
|
frontend->add_extension(
|
||||||
|
std::make_shared<ConversionExtension>(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<ov::opset8::Relu>(ng_input);
|
||||||
|
return {res};
|
||||||
|
}));
|
||||||
|
} else if (m_param.m_frontEndName == "onnx") {
|
||||||
|
frontend->add_extension(
|
||||||
|
std::make_shared<ConversionExtension>(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<ov::opset8::Add>(a, b);
|
||||||
|
return {res};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
std::shared_ptr<InputModel> input_model;
|
||||||
|
ASSERT_NO_THROW(input_model = frontend->load(m_param.m_modelName));
|
||||||
|
ASSERT_NE(input_model, nullptr);
|
||||||
|
std::shared_ptr<ov::Model> 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<InputModel> input_model;
|
||||||
|
ASSERT_NO_THROW(input_model = frontend->load(m_param.m_modelName));
|
||||||
|
ASSERT_NE(input_model, nullptr);
|
||||||
|
std::shared_ptr<ov::Model> model;
|
||||||
|
ASSERT_NO_THROW(model = frontend->convert(input_model));
|
||||||
|
ASSERT_NE(model, nullptr);
|
||||||
|
}
|
@ -142,7 +142,8 @@ TEST_P(FrontEndJsonConfigTest, testAddJsonConfigExtension) {
|
|||||||
auto loaded_ext = json_config_ext->get_loaded_extensions();
|
auto loaded_ext = json_config_ext->get_loaded_extensions();
|
||||||
auto target_ext = json_config_ext->get_target_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);
|
EXPECT_EQ(target_ext.size(), 3);
|
||||||
|
|
||||||
for (const auto& target : target_ext) {
|
for (const auto& target : target_ext) {
|
||||||
|
@ -4,14 +4,31 @@
|
|||||||
|
|
||||||
set(TARGET_NAME "test_builtin_extensions_1")
|
set(TARGET_NAME "test_builtin_extensions_1")
|
||||||
|
|
||||||
file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
file(GLOB LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||||
file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
|
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
|
# Create library
|
||||||
add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS})
|
add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS})
|
||||||
|
target_compile_definitions(${TARGET_NAME} PRIVATE ${DEFINITIONS})
|
||||||
target_link_libraries(${TARGET_NAME} PUBLIC nlohmann_json inference_engine_transformations frontend_common
|
target_link_libraries(${TARGET_NAME} PRIVATE ${DEPENDENCIES})
|
||||||
offline_transformations)
|
|
||||||
|
|
||||||
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
||||||
|
|
||||||
|
@ -3,7 +3,35 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <openvino/core/extension.hpp>
|
#include <openvino/core/extension.hpp>
|
||||||
|
#include <openvino/frontend/extension/conversion.hpp>
|
||||||
|
|
||||||
|
#ifdef ENABLE_OV_ONNX_FRONTEND
|
||||||
|
# include <openvino/frontend/onnx/extension/conversion.hpp>
|
||||||
|
# define ONNX_EXT std::make_shared<ov::frontend::onnx::ConversionExtension>("NewCustomOp_3", CustomTranslatorONNX),
|
||||||
|
#else
|
||||||
|
# define ONNX_EXT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_OV_PADDLE_FRONTEND
|
||||||
|
# include <openvino/frontend/paddle/extension/conversion.hpp>
|
||||||
|
# define PADDLE_EXT \
|
||||||
|
std::make_shared<ov::frontend::paddle::ConversionExtension>("NewCustomOp_4", CustomTranslatorPaddle),
|
||||||
|
#else
|
||||||
|
# define PADDLE_EXT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_OV_TF_FRONTEND
|
||||||
|
# include <openvino/frontend/tensorflow/extension/conversion.hpp>
|
||||||
|
# define TF_EXT \
|
||||||
|
std::make_shared<ov::frontend::tensorflow::ConversionExtension>("NewCustomOp_5", CustomTranslatorTensorflow)
|
||||||
|
#else
|
||||||
|
# define TF_EXT
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "test_extension.hpp"
|
#include "test_extension.hpp"
|
||||||
|
|
||||||
OPENVINO_CREATE_EXTENSIONS(std::vector<ov::Extension::Ptr>({std::make_shared<TestExtension1>()}));
|
OPENVINO_CREATE_EXTENSIONS(std::vector<ov::Extension::Ptr>(
|
||||||
|
{std::make_shared<TestExtension1>(),
|
||||||
|
std::make_shared<ov::frontend::ConversionExtension>("NewCustomOp_1", CustomTranslatorCommon_1),
|
||||||
|
std::make_shared<ov::frontend::ConversionExtension>("NewCustomOp_2", CustomTranslatorCommon_2),
|
||||||
|
ONNX_EXT PADDLE_EXT TF_EXT}));
|
||||||
|
@ -12,3 +12,23 @@ bool TestExtension1::transform(const std::shared_ptr<ov::Model>& function, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestExtension1::TestExtension1() : ov::frontend::JsonTransformationExtension("buildin_extensions_1::TestExtension1") {}
|
TestExtension1::TestExtension1() : ov::frontend::JsonTransformationExtension("buildin_extensions_1::TestExtension1") {}
|
||||||
|
|
||||||
|
ov::OutputVector CustomTranslatorCommon_1(const ov::frontend::NodeContext& node) {
|
||||||
|
return ov::OutputVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, ov::OutputVector> CustomTranslatorCommon_2(const ov::frontend::NodeContext& node) {
|
||||||
|
return std::map<std::string, ov::OutputVector>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ov::OutputVector CustomTranslatorTensorflow(const ov::frontend::NodeContext& node) {
|
||||||
|
return ov::OutputVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
ov::OutputVector CustomTranslatorONNX(const ov::frontend::NodeContext& node) {
|
||||||
|
return ov::OutputVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, ov::OutputVector> CustomTranslatorPaddle(const ov::frontend::NodeContext& node) {
|
||||||
|
return std::map<std::string, ov::OutputVector>();
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <extension/json_transformation.hpp>
|
#include <extension/json_transformation.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <openvino/frontend/node_context.hpp>
|
||||||
|
|
||||||
class TestExtension1 : public ov::frontend::JsonTransformationExtension {
|
class TestExtension1 : public ov::frontend::JsonTransformationExtension {
|
||||||
public:
|
public:
|
||||||
@ -13,3 +14,13 @@ public:
|
|||||||
|
|
||||||
bool transform(const std::shared_ptr<ov::Model>& function, const std::string& config) const override;
|
bool transform(const std::shared_ptr<ov::Model>& function, const std::string& config) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ov::OutputVector CustomTranslatorCommon_1(const ov::frontend::NodeContext& node);
|
||||||
|
|
||||||
|
std::map<std::string, ov::OutputVector> 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<std::string, ov::OutputVector> CustomTranslatorPaddle(const ov::frontend::NodeContext& node);
|
||||||
|
@ -10,7 +10,7 @@ file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
|
|||||||
# Create library
|
# Create library
|
||||||
add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS})
|
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)
|
offline_transformations)
|
||||||
|
|
||||||
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
||||||
|
@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
|||||||
|
|
||||||
add_executable(${TARGET_NAME} ${SRC})
|
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})
|
add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
|
||||||
|
|
||||||
|
53
src/core/tests/frontend/tensorflow/conversion.cpp
Normal file
53
src/core/tests/frontend/tensorflow/conversion.cpp
Normal file
@ -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<ov::Extension>& extension) override {
|
||||||
|
ov::frontend::tensorflow::FrontEnd::add_extension(extension);
|
||||||
|
|
||||||
|
if (auto conv_ext = std::dynamic_pointer_cast<ConversionExtension>(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<TelemetryExtension>(extension)) {
|
||||||
|
EXPECT_EQ(m_telemetry, telemetry) << "TelemetryExtension is not registered.";
|
||||||
|
} else if (auto transformation = std::dynamic_pointer_cast<DecoderTransformationExtension>(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<ov::detail::SOExtension>(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<TensorflowFrontendWrapper>();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(TFConversionExtensionTest,
|
||||||
|
FrontEndConversionExtensionTest,
|
||||||
|
::testing::Values(getTestData()),
|
||||||
|
FrontEndConversionExtensionTest::getTestCaseName);
|
@ -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<ConversionExtensionBase>;
|
||||||
|
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>;
|
||||||
|
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
|
@ -24,6 +24,7 @@ namespace frontend {
|
|||||||
/// calling corresponding ctor.
|
/// calling corresponding ctor.
|
||||||
class FRONTEND_API DecoderTransformationExtension : public ov::Extension {
|
class FRONTEND_API DecoderTransformationExtension : public ov::Extension {
|
||||||
public:
|
public:
|
||||||
|
using Ptr = std::shared_ptr<DecoderTransformationExtension>;
|
||||||
DecoderTransformationExtension() = default;
|
DecoderTransformationExtension() = default;
|
||||||
|
|
||||||
/// \brief Create a custom functional pass where code of the pass is implemented as a function.
|
/// \brief Create a custom functional pass where code of the pass is implemented as a function.
|
||||||
|
@ -20,6 +20,7 @@ namespace frontend {
|
|||||||
/// \brief Provides callback to report telemetry information back to Python code
|
/// \brief Provides callback to report telemetry information back to Python code
|
||||||
class FRONTEND_API TelemetryExtension : public ov::Extension {
|
class FRONTEND_API TelemetryExtension : public ov::Extension {
|
||||||
public:
|
public:
|
||||||
|
using Ptr = std::shared_ptr<TelemetryExtension>;
|
||||||
using error_callback = std::function<void(const std::string& category, const std::string& error_message)>;
|
using error_callback = std::function<void(const std::string& category, const std::string& error_message)>;
|
||||||
using event_callback = std::function<
|
using event_callback = std::function<
|
||||||
void(const std::string& category, const std::string& action, const std::string& label, int value)>;
|
void(const std::string& category, const std::string& action, const std::string& label, int value)>;
|
||||||
|
@ -22,7 +22,8 @@ using FrontEndFactory = std::function<FrontEnd::Ptr()>;
|
|||||||
/// frontends This is a main frontend entry point for client applications
|
/// frontends This is a main frontend entry point for client applications
|
||||||
class FRONTEND_API FrontEndManager final {
|
class FRONTEND_API FrontEndManager final {
|
||||||
public:
|
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
|
/// \brief Default move constructor
|
||||||
FrontEndManager(FrontEndManager&&) noexcept;
|
FrontEndManager(FrontEndManager&&) noexcept;
|
||||||
|
101
src/frontends/common/include/openvino/frontend/node_context.hpp
Normal file
101
src/frontends/common/include/openvino/frontend/node_context.hpp
Normal file
@ -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<Node> 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<Node> 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<Node> 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 <class T>
|
||||||
|
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<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns node attribute by name. Returns 'def' value if attribute does not exist
|
||||||
|
template <class T>
|
||||||
|
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<T>();
|
||||||
|
}
|
||||||
|
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<OutputVector(const NodeContext&)>;
|
||||||
|
using CreatorFunctionNamed = std::function<std::map<std::string, OutputVector>(const NodeContext&)>;
|
||||||
|
|
||||||
|
} // namespace frontend
|
||||||
|
} // namespace ov
|
8
src/frontends/common/src/extension/conversion.cpp
Normal file
8
src/frontends/common/src/extension/conversion.cpp
Normal file
@ -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;
|
@ -43,5 +43,7 @@ DecoderTransformationExtension::DecoderTransformationExtension(
|
|||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
void DecoderTransformationExtension::register_pass(ov::pass::Manager& manager) const {
|
void DecoderTransformationExtension::register_pass(ov::pass::Manager& manager) const {
|
||||||
m_registration(manager);
|
if (m_registration) {
|
||||||
|
m_registration(manager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,4 +191,4 @@ inline std::ostream& operator<<(std::ostream& outs, const Node& node) {
|
|||||||
|
|
||||||
} // namespace onnx_import
|
} // namespace onnx_import
|
||||||
|
|
||||||
} // namespace ngraph
|
} // namespace ngraph
|
@ -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>;
|
||||||
|
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
|
@ -4,21 +4,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <common/extension_holder.hpp>
|
#include "openvino/frontend/extension/conversion.hpp"
|
||||||
#include <openvino/frontend/frontend.hpp>
|
#include "openvino/frontend/extension/decoder_transformation.hpp"
|
||||||
|
#include "openvino/frontend/extension/extension_holder.hpp"
|
||||||
#ifdef OPENVINO_STATIC_LIBRARY
|
#include "openvino/frontend/extension/telemetry.hpp"
|
||||||
# define ONNX_FRONTEND_API
|
#include "openvino/frontend/frontend.hpp"
|
||||||
# define ONNX_FRONTEND_C_API
|
#include "openvino/frontend/onnx/visibility.hpp"
|
||||||
#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
|
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
@ -26,6 +17,8 @@ namespace onnx {
|
|||||||
|
|
||||||
class ONNX_FRONTEND_API FrontEnd : public ov::frontend::FrontEnd {
|
class ONNX_FRONTEND_API FrontEnd : public ov::frontend::FrontEnd {
|
||||||
public:
|
public:
|
||||||
|
~FrontEnd() override;
|
||||||
|
using Ptr = std::shared_ptr<FrontEnd>;
|
||||||
std::shared_ptr<ov::Model> convert(const InputModel::Ptr& model) const override;
|
std::shared_ptr<ov::Model> convert(const InputModel::Ptr& model) const override;
|
||||||
void convert(const std::shared_ptr<ov::Model>& partially_converted) const override;
|
void convert(const std::shared_ptr<ov::Model>& partially_converted) const override;
|
||||||
std::shared_ptr<ov::Model> decode(const InputModel::Ptr& model) const override;
|
std::shared_ptr<ov::Model> decode(const InputModel::Ptr& model) const override;
|
||||||
@ -36,7 +29,12 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
InputModel::Ptr load_impl(const std::vector<ov::Any>& params) const override;
|
InputModel::Ptr load_impl(const std::vector<ov::Any>& 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<Extension::Ptr> m_other_extensions;
|
||||||
|
std::vector<DecoderTransformationExtension::Ptr> m_transformation_extensions;
|
||||||
|
std::vector<ConversionExtensionBase::Ptr> m_conversion_extensions;
|
||||||
ExtensionHolder m_extensions;
|
ExtensionHolder m_extensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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<NodeContext>;
|
||||||
|
explicit NodeContext(const ngraph::onnx_import::Node& context);
|
||||||
|
size_t get_input_size() const override;
|
||||||
|
|
||||||
|
Output<ov::Node> 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<OutputVector(const ngraph::onnx_import::Node&)>;
|
||||||
|
} // namespace onnx
|
||||||
|
} // namespace frontend
|
||||||
|
} // namespace ov
|
@ -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
|
@ -25,6 +25,33 @@ Subgraph Attribute::get_subgraph(const Graph* parent_graph) const {
|
|||||||
return Subgraph{model_proto, parent_graph};
|
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 onnx_import
|
||||||
|
|
||||||
} // namespace ngraph
|
} // namespace ngraph
|
||||||
|
@ -327,6 +327,8 @@ public:
|
|||||||
return detail::attribute::get_value<T>(*m_attribute_proto);
|
return detail::attribute::get_value<T>(*m_attribute_proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ov::Any get_any() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ONNX_NAMESPACE::AttributeProto* m_attribute_proto;
|
const ONNX_NAMESPACE::AttributeProto* m_attribute_proto;
|
||||||
};
|
};
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/extension_holder.hpp"
|
|
||||||
#include "core/graph_cache.hpp"
|
#include "core/graph_cache.hpp"
|
||||||
#include "core/model.hpp"
|
#include "core/model.hpp"
|
||||||
#include "ngraph/function.hpp"
|
#include "ngraph/function.hpp"
|
||||||
#include "ngraph/op/parameter.hpp"
|
#include "ngraph/op/parameter.hpp"
|
||||||
#include "onnx_import/core/operator_set.hpp"
|
#include "onnx_import/core/operator_set.hpp"
|
||||||
|
#include "openvino/frontend/extension/extension_holder.hpp"
|
||||||
|
|
||||||
namespace ngraph {
|
namespace ngraph {
|
||||||
namespace onnx_import {
|
namespace onnx_import {
|
||||||
|
@ -162,6 +162,11 @@ Subgraph Node::Impl::get_attribute_value(const std::string& name) const {
|
|||||||
return get_subgraph_from_attribute(name);
|
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 Node::Impl::get_ng_inputs() const {
|
||||||
OutputVector result;
|
OutputVector result;
|
||||||
for (const auto& name : m_node_proto->input()) {
|
for (const auto& name : m_node_proto->input()) {
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "common/extension_holder.hpp"
|
|
||||||
#include "editor_types.hpp"
|
#include "editor_types.hpp"
|
||||||
#include "ngraph/function.hpp"
|
#include "ngraph/function.hpp"
|
||||||
#include "ngraph/op/constant.hpp"
|
#include "ngraph/op/constant.hpp"
|
||||||
#include "ngraph/partial_shape.hpp"
|
#include "ngraph/partial_shape.hpp"
|
||||||
#include "ngraph/type/element_type.hpp"
|
#include "ngraph/type/element_type.hpp"
|
||||||
#include "onnx_import/onnx_importer_visibility.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/progress_reporter_extension.hpp"
|
||||||
#include "openvino/frontend/extension/telemetry.hpp"
|
#include "openvino/frontend/extension/telemetry.hpp"
|
||||||
|
|
||||||
|
@ -5,13 +5,19 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <input_model.hpp>
|
#include <input_model.hpp>
|
||||||
#include <onnx_import/onnx.hpp>
|
#include <onnx_import/onnx.hpp>
|
||||||
|
#include <onnx_import/onnx_utils.hpp>
|
||||||
#include <openvino/frontend/exception.hpp>
|
#include <openvino/frontend/exception.hpp>
|
||||||
#include <openvino/frontend/manager.hpp>
|
#include <openvino/frontend/manager.hpp>
|
||||||
|
#include <openvino/frontend/onnx/extension/conversion.hpp>
|
||||||
#include <openvino/frontend/onnx/frontend.hpp>
|
#include <openvino/frontend/onnx/frontend.hpp>
|
||||||
|
#include <openvino/frontend/onnx/visibility.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utils/onnx_internal.hpp>
|
#include <utils/onnx_internal.hpp>
|
||||||
|
|
||||||
#include "onnx_common/onnx_model_validator.hpp"
|
#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;
|
||||||
using namespace ov::frontend::onnx;
|
using namespace ov::frontend::onnx;
|
||||||
@ -63,6 +69,19 @@ InputModel::Ptr FrontEnd::load_impl(const std::vector<ov::Any>& variants) const
|
|||||||
std::shared_ptr<ngraph::Function> FrontEnd::convert(const InputModel::Ptr& model) const {
|
std::shared_ptr<ngraph::Function> FrontEnd::convert(const InputModel::Ptr& model) const {
|
||||||
auto model_onnx = std::dynamic_pointer_cast<InputModel>(model);
|
auto model_onnx = std::dynamic_pointer_cast<InputModel>(model);
|
||||||
NGRAPH_CHECK(model_onnx != nullptr, "Invalid input 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();
|
return model_onnx->convert();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +154,42 @@ bool FrontEnd::supported_impl(const std::vector<ov::Any>& variants) const {
|
|||||||
void FrontEnd::add_extension(const std::shared_ptr<ov::Extension>& extension) {
|
void FrontEnd::add_extension(const std::shared_ptr<ov::Extension>& extension) {
|
||||||
if (auto telemetry = std::dynamic_pointer_cast<TelemetryExtension>(extension)) {
|
if (auto telemetry = std::dynamic_pointer_cast<TelemetryExtension>(extension)) {
|
||||||
m_extensions.telemetry = telemetry;
|
m_extensions.telemetry = telemetry;
|
||||||
|
} else if (auto transformation = std::dynamic_pointer_cast<DecoderTransformationExtension>(extension)) {
|
||||||
|
m_transformation_extensions.push_back(transformation);
|
||||||
|
} else if (const auto& so_ext = std::dynamic_pointer_cast<ov::detail::SOExtension>(extension)) {
|
||||||
|
add_extension(so_ext->extension());
|
||||||
|
m_other_extensions.push_back(so_ext);
|
||||||
|
} else if (auto common_conv_ext = std::dynamic_pointer_cast<ov::frontend::ConversionExtension>(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<ConversionExtension>(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<ProgressReporterExtension>(extension)) {
|
} else if (auto progress_reporter = std::dynamic_pointer_cast<ProgressReporterExtension>(extension)) {
|
||||||
m_extensions.progress_reporter = progress_reporter;
|
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();
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <openvino/frontend/input_model.hpp>
|
#include <openvino/frontend/input_model.hpp>
|
||||||
|
|
||||||
#include "common/extension_holder.hpp"
|
#include "openvino/frontend/extension/extension_holder.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
44
src/frontends/onnx/frontend/src/node_context.cpp
Normal file
44
src/frontends/onnx/frontend/src/node_context.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (C) 2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <onnx_import/core/node.hpp>
|
||||||
|
#include <openvino/frontend/onnx/node_context.hpp>
|
||||||
|
#include <utils/common.hpp>
|
||||||
|
|
||||||
|
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::Node> 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<ov::Any>(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<int64_t>() && type_info == typeid(ov::element::Type)) {
|
||||||
|
return ngraph::onnx_import::common::get_ngraph_element_type(data.as<int64_t>());
|
||||||
|
} else if (data.is<std::vector<int64_t>>() && type_info == typeid(std::vector<ov::element::Type>)) {
|
||||||
|
const auto& casted = data.as<std::vector<int64_t>>();
|
||||||
|
std::vector<ov::element::Type> 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;
|
||||||
|
}
|
@ -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))
|
m_map[domain_][name_].emplace(ver_, std::bind(op::set_##ver_::fn_, std::placeholders::_1))
|
||||||
|
|
||||||
OperatorsBridge::OperatorsBridge() {
|
OperatorsBridge::OperatorsBridge() {
|
||||||
|
_load_initial_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperatorsBridge::_load_initial_state() {
|
||||||
REGISTER_OPERATOR("Abs", 1, abs);
|
REGISTER_OPERATOR("Abs", 1, abs);
|
||||||
REGISTER_OPERATOR("Acos", 1, acos);
|
REGISTER_OPERATOR("Acos", 1, acos);
|
||||||
REGISTER_OPERATOR("Acosh", 1, acosh);
|
REGISTER_OPERATOR("Acosh", 1, acosh);
|
||||||
|
@ -61,6 +61,10 @@ public:
|
|||||||
return instance()._is_operator_registered(name, version, domain);
|
return instance()._is_operator_registered(name, version, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void load_initial_state() {
|
||||||
|
return instance()._load_initial_state();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Registered operators structure
|
// Registered operators structure
|
||||||
// {
|
// {
|
||||||
@ -91,6 +95,7 @@ private:
|
|||||||
|
|
||||||
bool _is_operator_registered(const std::string& name, std::int64_t version, const std::string& domain);
|
bool _is_operator_registered(const std::string& name, std::int64_t version, const std::string& domain);
|
||||||
|
|
||||||
|
void _load_initial_state();
|
||||||
std::mutex lock;
|
std::mutex lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "common/extension_holder.hpp"
|
|
||||||
#include "ngraph/function.hpp"
|
#include "ngraph/function.hpp"
|
||||||
|
#include "openvino/frontend/extension/extension_holder.hpp"
|
||||||
|
|
||||||
namespace ONNX_NAMESPACE {
|
namespace ONNX_NAMESPACE {
|
||||||
class ModelProto;
|
class ModelProto;
|
||||||
|
@ -7,4 +7,4 @@ ov_add_frontend(NAME paddle
|
|||||||
SHUTDOWN_PROTOBUF
|
SHUTDOWN_PROTOBUF
|
||||||
PROTOBUF_LITE
|
PROTOBUF_LITE
|
||||||
FILEDESCRIPTION "FrontEnd to load and convert PaddlePaddle file format"
|
FILEDESCRIPTION "FrontEnd to load and convert PaddlePaddle file format"
|
||||||
LINK_LIBRARIES openvino::runtime::dev)
|
LINK_LIBRARIES openvino::util openvino::runtime::dev)
|
||||||
|
@ -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<OutPortName, OutputVector>;
|
||||||
|
using NamedInputs = std::map<InPortName, OutputVector>;
|
||||||
|
|
||||||
|
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<OutPortName> 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
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <openvino/frontend/exception.hpp>
|
#include "openvino/frontend/exception.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
@ -14,13 +14,11 @@ class NodeContext;
|
|||||||
|
|
||||||
class OpValidationFailure : public ov::frontend::OpValidationFailure {
|
class OpValidationFailure : public ov::frontend::OpValidationFailure {
|
||||||
public:
|
public:
|
||||||
OpValidationFailure(const CheckLocInfo& check_loc_info,
|
OpValidationFailure(const CheckLocInfo& check_loc_info, const NodeContext& node, const std::string& explanation)
|
||||||
const paddle::NodeContext& node,
|
|
||||||
const std::string& explanation)
|
|
||||||
: ov::frontend::OpValidationFailure(check_loc_info, get_error_msg_prefix_paddle(node), explanation) {}
|
: ov::frontend::OpValidationFailure(check_loc_info, get_error_msg_prefix_paddle(node), explanation) {}
|
||||||
|
|
||||||
private:
|
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 paddle
|
||||||
} // namespace frontend
|
} // namespace frontend
|
@ -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>;
|
||||||
|
|
||||||
|
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
|
@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <openvino/frontend/extension/decoder_transformation.hpp>
|
#include "openvino/core/extension.hpp"
|
||||||
#include <openvino/frontend/extension/telemetry.hpp>
|
#include "openvino/frontend/extension/decoder_transformation.hpp"
|
||||||
#include <openvino/frontend/frontend.hpp>
|
#include "openvino/frontend/extension/telemetry.hpp"
|
||||||
#include <openvino/frontend/input_model.hpp>
|
#include "openvino/frontend/frontend.hpp"
|
||||||
|
#include "openvino/frontend/input_model.hpp"
|
||||||
#include "exceptions.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"
|
#include "openvino/frontend/paddle/visibility.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
@ -20,7 +22,8 @@ class OpPlace;
|
|||||||
|
|
||||||
class PADDLE_API FrontEnd : public ov::frontend::FrontEnd {
|
class PADDLE_API FrontEnd : public ov::frontend::FrontEnd {
|
||||||
public:
|
public:
|
||||||
FrontEnd() = default;
|
using Ptr = std::shared_ptr<FrontEnd>;
|
||||||
|
FrontEnd();
|
||||||
|
|
||||||
/// \brief Completely convert the remaining, not converted part of a function.
|
/// \brief Completely convert the remaining, not converted part of a function.
|
||||||
/// \param partiallyConverted partially converted OV Model
|
/// \param partiallyConverted partially converted OV Model
|
||||||
@ -68,13 +71,21 @@ protected:
|
|||||||
/// \return InputModel::Ptr
|
/// \return InputModel::Ptr
|
||||||
InputModel::Ptr load_impl(const std::vector<ov::Any>& params) const override;
|
InputModel::Ptr load_impl(const std::vector<ov::Any>& params) const override;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
static std::shared_ptr<Model> convert_each_node(
|
static std::shared_ptr<Model> convert_each_node(
|
||||||
const std::shared_ptr<InputModel>& frontend_model,
|
const std::shared_ptr<InputModel>& frontend_model,
|
||||||
std::function<std::map<std::string, OutputVector>(const std::map<std::string, Output<Node>>&,
|
std::function<std::map<std::string, OutputVector>(const std::map<std::string, Output<Node>>&,
|
||||||
const std::shared_ptr<OpPlace>&)> func);
|
const std::shared_ptr<OpPlace>&)> func);
|
||||||
std::shared_ptr<TelemetryExtension> m_telemetry;
|
|
||||||
std::vector<std::shared_ptr<DecoderTransformationExtension>> 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<Extension::Ptr> m_extensions;
|
||||||
|
TelemetryExtension::Ptr m_telemetry;
|
||||||
|
std::vector<DecoderTransformationExtension::Ptr> m_transformation_extensions;
|
||||||
|
std::vector<ConversionExtensionBase::Ptr> m_conversion_extensions;
|
||||||
|
|
||||||
|
TranslatorDictionaryType m_op_translators;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace paddle
|
} // namespace paddle
|
||||||
|
@ -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<OutPortName, OutputVector>;
|
||||||
|
using NamedInputs = std::map<InPortName, OutputVector>;
|
||||||
|
|
||||||
|
/// 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>;
|
||||||
|
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<Node> 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<Node> 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<OutPortName> 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>& node,
|
||||||
|
const std::vector<OutPortName>& 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>& node,
|
||||||
|
const std::vector<OutPortName>& 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<NamedOutputs(const NodeContext&)>;
|
||||||
|
using TranslatorDictionaryType = std::map<std::string, CreatorFunction>;
|
||||||
|
} // namespace paddle
|
||||||
|
} // namespace frontend
|
||||||
|
} // namespace ov
|
@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "decoder.hpp"
|
#include "decoder_proto.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -21,7 +21,7 @@ namespace paddle {
|
|||||||
|
|
||||||
using namespace ::paddle::framework;
|
using namespace ::paddle::framework;
|
||||||
|
|
||||||
std::map<::paddle::framework::proto::VarType_Type, ov::element::Type> TYPE_MAP{
|
std::map<proto::VarType_Type, ov::element::Type> TYPE_MAP{
|
||||||
{proto::VarType_Type::VarType_Type_BOOL, ov::element::boolean},
|
{proto::VarType_Type::VarType_Type_BOOL, ov::element::boolean},
|
||||||
{proto::VarType_Type::VarType_Type_INT16, ov::element::i16},
|
{proto::VarType_Type::VarType_Type_INT16, ov::element::i16},
|
||||||
{proto::VarType_Type::VarType_Type_INT32, ov::element::i32},
|
{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_INT8, ov::element::i8},
|
||||||
{proto::VarType_Type::VarType_Type_BF16, ov::element::bf16}};
|
{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);
|
auto attrs = decode_attribute_helper(name);
|
||||||
if (attrs.empty()) {
|
if (attrs.empty()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_info == typeid(std::string)) {
|
switch (attrs[0].type()) {
|
||||||
return attrs[0].s();
|
case proto::AttrType::INT:
|
||||||
} else if (type_info == typeid(int64_t)) {
|
|
||||||
return attrs[0].l();
|
|
||||||
} else if (type_info == typeid(std::vector<int64_t>)) {
|
|
||||||
return std::vector<int64_t>(attrs[0].longs().begin(), attrs[0].longs().end());
|
|
||||||
} else if (type_info == typeid(int32_t)) {
|
|
||||||
return attrs[0].i();
|
return attrs[0].i();
|
||||||
} else if (type_info == typeid(std::vector<int32_t>)) {
|
case proto::AttrType::INTS:
|
||||||
return std::vector<int32_t>(attrs[0].ints().begin(), attrs[0].ints().end());
|
return std::vector<int32_t>(attrs[0].ints().begin(), attrs[0].ints().end());
|
||||||
} else if (type_info == typeid(float)) {
|
case proto::AttrType::FLOAT:
|
||||||
return attrs[0].f();
|
return attrs[0].f();
|
||||||
} else if (type_info == typeid(std::vector<float>)) {
|
case proto::AttrType::FLOATS:
|
||||||
return std::vector<float>(attrs[0].floats().begin(), attrs[0].floats().end());
|
return std::vector<float>(attrs[0].floats().begin(), attrs[0].floats().end());
|
||||||
} else if (type_info == typeid(ov::element::Type)) {
|
case proto::AttrType::STRING:
|
||||||
return TYPE_MAP[static_cast<::paddle::framework::proto::VarType_Type>(attrs[0].i())];
|
return attrs[0].s();
|
||||||
} else if (type_info == typeid(bool)) {
|
case proto::AttrType::STRINGS:
|
||||||
|
return std::vector<std::string>(attrs[0].strings().begin(), attrs[0].strings().end());
|
||||||
|
case proto::AttrType::LONG:
|
||||||
|
return attrs[0].l();
|
||||||
|
case proto::AttrType::LONGS:
|
||||||
|
return std::vector<int64_t>(attrs[0].longs().begin(), attrs[0].longs().end());
|
||||||
|
case proto::AttrType::BOOLEAN:
|
||||||
return attrs[0].b();
|
return attrs[0].b();
|
||||||
|
case proto::AttrType::BOOLEANS:
|
||||||
|
return std::vector<bool>(attrs[0].bools().begin(), attrs[0].bools().end());
|
||||||
|
case proto::AttrType::BLOCK:
|
||||||
|
return attrs[0].block_idx();
|
||||||
|
case proto::AttrType::BLOCKS:
|
||||||
|
return std::vector<std::int32_t>(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
|
ov::Any DecoderProto::convert_attribute(const Any& data, const std::type_info& type_info) const {
|
||||||
return {};
|
if (data.is<int32_t>() && type_info == typeid(ov::element::Type)) {
|
||||||
|
return TYPE_MAP.at(static_cast<proto::VarType_Type>(data.as<int32_t>()));
|
||||||
|
} else if (data.is<std::vector<int32_t>>() && type_info == typeid(std::vector<ov::element::Type>)) {
|
||||||
|
const auto& casted = data.as<std::vector<int32_t>>();
|
||||||
|
std::vector<ov::element::Type> types(casted.size());
|
||||||
|
for (size_t i = 0; i < casted.size(); ++i) {
|
||||||
|
types[i] = TYPE_MAP.at(static_cast<proto::VarType_Type>(casted[i]));
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
// no conversion rules found.
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<paddle::OutPortName> DecoderProto::get_output_names() const {
|
std::vector<paddle::OutPortName> 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)) {
|
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());
|
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()),
|
FRONT_END_GENERAL_CHECK(std::equal(output_types.begin() + 1, output_types.end(), output_types.begin()),
|
||||||
"Port has tensors with different types connected.");
|
"Port has tensors with different types connected.");
|
||||||
return output_types[0];
|
return output_types[0];
|
@ -9,14 +9,14 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <openvino/core/any.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "framework.pb.h"
|
#include "framework.pb.h"
|
||||||
#include "node_context.hpp"
|
#include "openvino/core/any.hpp"
|
||||||
#include "openvino/frontend/paddle/frontend.hpp"
|
#include "openvino/frontend/paddle/frontend.hpp"
|
||||||
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
#include "place.hpp"
|
#include "place.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
@ -28,7 +28,9 @@ class DecoderProto : public paddle::DecoderBase {
|
|||||||
public:
|
public:
|
||||||
explicit DecoderProto(const std::shared_ptr<OpPlace>& op) : op_place(op) {}
|
explicit DecoderProto(const std::shared_ptr<OpPlace>& 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<paddle::OutPortName> get_output_names() const override;
|
std::vector<paddle::OutPortName> get_output_names() const override;
|
||||||
|
|
@ -2,9 +2,9 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// 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 ov {
|
||||||
namespace frontend {
|
namespace frontend {
|
@ -9,15 +9,17 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "decoder.hpp"
|
#include "decoder_proto.hpp"
|
||||||
#include "framework.pb.h"
|
#include "framework.pb.h"
|
||||||
#include "input_model.hpp"
|
#include "input_model.hpp"
|
||||||
#include "node_context.hpp"
|
|
||||||
#include "op_table.hpp"
|
#include "op_table.hpp"
|
||||||
|
#include "openvino/frontend/extension/conversion.hpp"
|
||||||
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
#include "openvino/opsets/opset7.hpp"
|
#include "openvino/opsets/opset7.hpp"
|
||||||
#include "paddle_fw_node.hpp"
|
#include "paddle_fw_node.hpp"
|
||||||
#include "paddle_utils.hpp"
|
#include "paddle_utils.hpp"
|
||||||
#include "place.hpp"
|
#include "place.hpp"
|
||||||
|
#include "so_extension.hpp"
|
||||||
|
|
||||||
using namespace ov::opset7;
|
using namespace ov::opset7;
|
||||||
using namespace ov;
|
using namespace ov;
|
||||||
@ -132,6 +134,8 @@ std::istream* variant_to_stream_ptr(const ov::Any& variant, std::ifstream& ext_s
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
FrontEnd::FrontEnd() : m_op_translators(paddle::get_supported_ops()) {}
|
||||||
|
|
||||||
std::shared_ptr<ov::Model> FrontEnd::convert_each_node(
|
std::shared_ptr<ov::Model> FrontEnd::convert_each_node(
|
||||||
const std::shared_ptr<ov::frontend::InputModel>& frontend_model,
|
const std::shared_ptr<ov::frontend::InputModel>& frontend_model,
|
||||||
std::function<std::map<std::string, OutputVector>(const std::map<std::string, Output<Node>>&,
|
std::function<std::map<std::string, OutputVector>(const std::map<std::string, Output<Node>>&,
|
||||||
@ -292,11 +296,10 @@ std::shared_ptr<ov::Model> FrontEnd::convert(const InputModel::Ptr& model) const
|
|||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, paddle::CreatorFunction> CREATORS_MAP = paddle::get_supported_ops();
|
|
||||||
auto f = convert_each_node(
|
auto f = convert_each_node(
|
||||||
paddle_model,
|
paddle_model,
|
||||||
[&](const std::map<std::string, Output<Node>>& nodes_dict, const std::shared_ptr<OpPlace>& op_place) {
|
[&](const std::map<std::string, Output<Node>>& nodes_dict, const std::shared_ptr<OpPlace>& 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;
|
return f;
|
||||||
}
|
}
|
||||||
@ -304,8 +307,7 @@ std::shared_ptr<ov::Model> FrontEnd::convert(const InputModel::Ptr& model) const
|
|||||||
void FrontEnd::convert(const std::shared_ptr<ov::Model>& partiallyConverted) const {
|
void FrontEnd::convert(const std::shared_ptr<ov::Model>& partiallyConverted) const {
|
||||||
for (const auto& node : partiallyConverted->get_ordered_ops()) {
|
for (const auto& node : partiallyConverted->get_ordered_ops()) {
|
||||||
if (ov::is_type<FrameworkNode>(node)) {
|
if (ov::is_type<FrameworkNode>(node)) {
|
||||||
paddle::normalize_framework_node(std::dynamic_pointer_cast<FrameworkNode>(node),
|
paddle::normalize_framework_node(std::dynamic_pointer_cast<FrameworkNode>(node), m_op_translators);
|
||||||
paddle::get_supported_ops());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& result : partiallyConverted->get_results()) {
|
for (const auto& result : partiallyConverted->get_results()) {
|
||||||
@ -329,13 +331,12 @@ std::shared_ptr<ov::Model> FrontEnd::convert_partially(const InputModel::Ptr& mo
|
|||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, paddle::CreatorFunction> CREATORS_MAP = paddle::get_supported_ops();
|
|
||||||
auto f = convert_each_node(
|
auto f = convert_each_node(
|
||||||
paddle_model,
|
paddle_model,
|
||||||
[&](const std::map<std::string, Output<Node>>& nodes_dict, const std::shared_ptr<OpPlace>& op_place) {
|
[&](const std::map<std::string, Output<Node>>& nodes_dict, const std::shared_ptr<OpPlace>& op_place) {
|
||||||
paddle::NamedOutputs named_outputs;
|
paddle::NamedOutputs named_outputs;
|
||||||
try {
|
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&) {
|
} catch (const OpConversionFailure&) {
|
||||||
named_outputs = paddle::make_framework_node(nodes_dict, op_place);
|
named_outputs = paddle::make_framework_node(nodes_dict, op_place);
|
||||||
}
|
}
|
||||||
@ -348,7 +349,6 @@ std::shared_ptr<ov::Model> FrontEnd::decode(const InputModel::Ptr& model) const
|
|||||||
auto paddle_model = std::dynamic_pointer_cast<InputModel>(model);
|
auto paddle_model = std::dynamic_pointer_cast<InputModel>(model);
|
||||||
FRONT_END_GENERAL_CHECK(paddle_model != nullptr, "Invalid input model");
|
FRONT_END_GENERAL_CHECK(paddle_model != nullptr, "Invalid input model");
|
||||||
|
|
||||||
std::map<std::string, paddle::CreatorFunction> CREATORS_MAP = paddle::get_supported_ops();
|
|
||||||
auto f = convert_each_node(paddle_model, paddle::make_framework_node);
|
auto f = convert_each_node(paddle_model, paddle::make_framework_node);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
@ -362,6 +362,19 @@ void FrontEnd::add_extension(const std::shared_ptr<ov::Extension>& extension) {
|
|||||||
m_telemetry = telemetry;
|
m_telemetry = telemetry;
|
||||||
} else if (auto transformation = std::dynamic_pointer_cast<DecoderTransformationExtension>(extension)) {
|
} else if (auto transformation = std::dynamic_pointer_cast<DecoderTransformationExtension>(extension)) {
|
||||||
m_transformation_extensions.push_back(transformation);
|
m_transformation_extensions.push_back(transformation);
|
||||||
|
} else if (const auto& so_ext = std::dynamic_pointer_cast<ov::detail::SOExtension>(extension)) {
|
||||||
|
add_extension(so_ext->extension());
|
||||||
|
m_extensions.push_back(so_ext);
|
||||||
|
} else if (auto common_conv_ext = std::dynamic_pointer_cast<ov::frontend::ConversionExtension>(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<ConversionExtension>(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);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "decoder.hpp"
|
#include "decoder_proto.hpp"
|
||||||
#include "framework.pb.h"
|
#include "framework.pb.h"
|
||||||
#include "input_model.hpp"
|
#include "input_model.hpp"
|
||||||
#include "node_context.hpp"
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
#include "openvino/opsets/opset7.hpp"
|
#include "openvino/opsets/opset7.hpp"
|
||||||
#include "paddle_utils.hpp"
|
#include "paddle_utils.hpp"
|
||||||
#include "place.hpp"
|
#include "place.hpp"
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <openvino/frontend/extension/telemetry.hpp>
|
#include "openvino/frontend/extension/telemetry.hpp"
|
||||||
#include <openvino/frontend/paddle/frontend.hpp>
|
#include "openvino/frontend/paddle/frontend.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <node_context.hpp>
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
|
|
||||||
#include "openvino/opsets/opset6.hpp"
|
#include "openvino/opsets/opset6.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
@ -11,7 +10,7 @@ namespace frontend {
|
|||||||
namespace paddle {
|
namespace paddle {
|
||||||
namespace op {
|
namespace op {
|
||||||
NamedOutputs argmax(const NodeContext& node) {
|
NamedOutputs argmax(const NodeContext& node) {
|
||||||
auto data = node.get_ng_input("X");
|
auto data = node.get_input("X");
|
||||||
bool flatten = node.get_attribute<bool>("flatten");
|
bool flatten = node.get_attribute<bool>("flatten");
|
||||||
const element::Type& index_element_type = element::i64;
|
const element::Type& index_element_type = element::i64;
|
||||||
const Output<ov::Node> k = ov::opset6::Constant::create(ov::element::i64, {}, {1});
|
const Output<ov::Node> k = ov::opset6::Constant::create(ov::element::i64, {}, {1});
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <node_context.hpp>
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
|
|
||||||
#include "openvino/opsets/opset6.hpp"
|
#include "openvino/opsets/opset6.hpp"
|
||||||
namespace ov {
|
namespace ov {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <node_context.hpp>
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
|
|
||||||
#include "openvino/opsets/opset6.hpp"
|
#include "openvino/opsets/opset6.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
@ -11,11 +10,11 @@ namespace frontend {
|
|||||||
namespace paddle {
|
namespace paddle {
|
||||||
namespace op {
|
namespace op {
|
||||||
NamedOutputs batch_norm(const NodeContext& node) {
|
NamedOutputs batch_norm(const NodeContext& node) {
|
||||||
auto data = node.get_ng_input("X");
|
auto data = node.get_input("X");
|
||||||
auto gamma = node.get_ng_input("Scale");
|
auto gamma = node.get_input("Scale");
|
||||||
auto beta = node.get_ng_input("Bias");
|
auto beta = node.get_input("Bias");
|
||||||
auto mean = node.get_ng_input("Mean");
|
auto mean = node.get_input("Mean");
|
||||||
auto variance = node.get_ng_input("Variance");
|
auto variance = node.get_input("Variance");
|
||||||
auto data_layout = node.get_attribute<std::string>("data_layout");
|
auto data_layout = node.get_attribute<std::string>("data_layout");
|
||||||
|
|
||||||
PADDLE_OP_CHECK(node, (data_layout == "NCHW" || data_layout == "NHWC"), "Not supported input data layout!");
|
PADDLE_OP_CHECK(node, (data_layout == "NCHW" || data_layout == "NHWC"), "Not supported input data layout!");
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <node_context.hpp>
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
|
|
||||||
#include "openvino/opsets/opset6.hpp"
|
#include "openvino/opsets/opset6.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
@ -11,7 +10,7 @@ namespace frontend {
|
|||||||
namespace paddle {
|
namespace paddle {
|
||||||
namespace op {
|
namespace op {
|
||||||
NamedOutputs cast(const NodeContext& node) {
|
NamedOutputs cast(const NodeContext& node) {
|
||||||
auto data = node.get_ng_input("X");
|
auto data = node.get_input("X");
|
||||||
auto out_dtype = node.get_attribute<ov::element::Type>("out_dtype");
|
auto out_dtype = node.get_attribute<ov::element::Type>("out_dtype");
|
||||||
|
|
||||||
return node.default_single_output_mapping({std::make_shared<ov::opset6::Convert>(data, out_dtype)}, {"Out"});
|
return node.default_single_output_mapping({std::make_shared<ov::opset6::Convert>(data, out_dtype)}, {"Out"});
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <node_context.hpp>
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
|
|
||||||
#include "openvino/opsets/opset6.hpp"
|
#include "openvino/opsets/opset6.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
@ -11,7 +10,7 @@ namespace frontend {
|
|||||||
namespace paddle {
|
namespace paddle {
|
||||||
namespace op {
|
namespace op {
|
||||||
NamedOutputs clip(const NodeContext& node) {
|
NamedOutputs clip(const NodeContext& node) {
|
||||||
auto data = node.get_ng_input("X");
|
auto data = node.get_input("X");
|
||||||
auto min = node.get_attribute<float>("min");
|
auto min = node.get_attribute<float>("min");
|
||||||
auto max = node.get_attribute<float>("max");
|
auto max = node.get_attribute<float>("max");
|
||||||
PADDLE_OP_CHECK(node, max >= min, "clip: max value must greater than min value!");
|
PADDLE_OP_CHECK(node, max >= min, "clip: max value must greater than min value!");
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <node_context.hpp>
|
#include "openvino/frontend/paddle/node_context.hpp"
|
||||||
|
|
||||||
#include "openvino/opsets/opset6.hpp"
|
#include "openvino/opsets/opset6.hpp"
|
||||||
|
|
||||||
namespace ov {
|
namespace ov {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user