diff --git a/src/bindings/python/src/openvino/frontend/__init__.py b/src/bindings/python/src/openvino/frontend/__init__.py index a008675fce0..156b240e00a 100644 --- a/src/bindings/python/src/openvino/frontend/__init__.py +++ b/src/bindings/python/src/openvino/frontend/__init__.py @@ -41,6 +41,8 @@ from openvino.pyopenvino import FrontEnd from openvino.pyopenvino import InputModel from openvino.pyopenvino import Place from openvino.pyopenvino import TelemetryExtension +from openvino.pyopenvino import DecoderTransformationExtension +from openvino.pyopenvino import JsonConfigExtension # exceptions from openvino.pyopenvino import NotImplementedFailure diff --git a/src/bindings/python/src/pyopenvino/core/extension.cpp b/src/bindings/python/src/pyopenvino/core/extension.cpp new file mode 100644 index 00000000000..0d4bafd28e8 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/core/extension.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include + +#include "openvino/frontend/manager.hpp" + +namespace py = pybind11; + +void regclass_Extension(py::module m) { + py::class_> ext(m, "Extension", py::dynamic_attr()); +} diff --git a/src/bindings/python/src/pyopenvino/core/extension.hpp b/src/bindings/python/src/pyopenvino/core/extension.hpp new file mode 100644 index 00000000000..537396df2f3 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/core/extension.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace py = pybind11; + +void regclass_Extension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/extensions.cpp b/src/bindings/python/src/pyopenvino/frontend/extensions.cpp new file mode 100644 index 00000000000..9bcf4090e8c --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/extensions.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include +#include + +#include "extension/json_config.hpp" +#include "manager.hpp" +#include "openvino/frontend/exception.hpp" +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "openvino/frontend/extension/telemetry.hpp" +#include "pyopenvino/graph/function.hpp" + +namespace py = pybind11; + +using namespace ov::frontend; + +void regclass_frontend_TelemetryExtension(py::module m) { + py::class_, ov::Extension> ext(m, + "TelemetryExtension", + py::dynamic_attr()); + + ext.def(py::init([](const std::string& event_category, + const TelemetryExtension::event_callback& send_event, + const TelemetryExtension::error_callback& send_error, + const TelemetryExtension::error_callback& send_stack_trace) { + return std::make_shared(event_category, send_event, send_error, send_stack_trace); + })); + + ext.def("send_event", &TelemetryExtension::send_event); + ext.def("send_error", &TelemetryExtension::send_error); + ext.def("send_stack_trace", &TelemetryExtension::send_stack_trace); +} + +void regclass_frontend_DecoderTransformationExtension(py::module m) { + py::class_, + ov::Extension> + ext(m, "DecoderTransformationExtension", py::dynamic_attr()); +} + +void regclass_frontend_JsonConfigExtension(py::module m) { + py::class_, + ov::frontend::DecoderTransformationExtension> + ext(m, "JsonConfigExtension", py::dynamic_attr()); + + ext.doc() = "Extension class to load and process ModelOptimizer JSON config file"; + + ext.def(py::init([](const std::string& path) { + return std::make_shared(path); + })); +} diff --git a/src/bindings/python/src/pyopenvino/frontend/extensions.hpp b/src/bindings/python/src/pyopenvino/frontend/extensions.hpp new file mode 100644 index 00000000000..03133fd0be6 --- /dev/null +++ b/src/bindings/python/src/pyopenvino/frontend/extensions.hpp @@ -0,0 +1,13 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +namespace py = pybind11; + +void regclass_frontend_TelemetryExtension(py::module m); +void regclass_frontend_DecoderTransformationExtension(py::module m); +void regclass_frontend_JsonConfigExtension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/frontend.cpp b/src/bindings/python/src/pyopenvino/frontend/frontend.cpp index c3e49181793..a510fa45998 100644 --- a/src/bindings/python/src/pyopenvino/frontend/frontend.cpp +++ b/src/bindings/python/src/pyopenvino/frontend/frontend.cpp @@ -8,8 +8,8 @@ #include #include "openvino/frontend/exception.hpp" +#include "openvino/frontend/extension/telemetry.hpp" #include "openvino/frontend/manager.hpp" -#include "openvino/frontend/telemetry_extension.hpp" #include "pyopenvino/graph/function.hpp" namespace py = pybind11; @@ -143,26 +143,3 @@ void regclass_frontend_FrontEnd(py::module m) { return ""; }); } - -void regclass_frontend_Extension(py::module m) { - py::class_> ext(m, "Extension", py::dynamic_attr()); -} - -void regclass_frontend_TelemetryExtension(py::module m) { - { - py::class_, ov::Extension> ext(m, - "TelemetryExtension", - py::dynamic_attr()); - - ext.def(py::init([](const std::string& event_category, - const TelemetryExtension::event_callback& send_event, - const TelemetryExtension::error_callback& send_error, - const TelemetryExtension::error_callback& send_stack_trace) { - return std::make_shared(event_category, send_event, send_error, send_stack_trace); - })); - - ext.def("send_event", &TelemetryExtension::send_event); - ext.def("send_error", &TelemetryExtension::send_error); - ext.def("send_stack_trace", &TelemetryExtension::send_stack_trace); - } -} diff --git a/src/bindings/python/src/pyopenvino/frontend/frontend.hpp b/src/bindings/python/src/pyopenvino/frontend/frontend.hpp index b6df63e9c26..50b5b252d8c 100644 --- a/src/bindings/python/src/pyopenvino/frontend/frontend.hpp +++ b/src/bindings/python/src/pyopenvino/frontend/frontend.hpp @@ -9,5 +9,3 @@ namespace py = pybind11; void regclass_frontend_FrontEnd(py::module m); -void regclass_frontend_Extension(py::module m); -void regclass_frontend_TelemetryExtension(py::module m); diff --git a/src/bindings/python/src/pyopenvino/frontend/manager.hpp b/src/bindings/python/src/pyopenvino/frontend/manager.hpp index aa2e0a16a04..7ab6abfd51f 100644 --- a/src/bindings/python/src/pyopenvino/frontend/manager.hpp +++ b/src/bindings/python/src/pyopenvino/frontend/manager.hpp @@ -14,4 +14,3 @@ void regclass_frontend_InitializationFailureFrontEnd(py::module m); void regclass_frontend_OpConversionFailureFrontEnd(py::module m); void regclass_frontend_OpValidationFailureFrontEnd(py::module m); void regclass_frontend_GeneralFailureFrontEnd(py::module m); - diff --git a/src/bindings/python/src/pyopenvino/pyopenvino.cpp b/src/bindings/python/src/pyopenvino/pyopenvino.cpp index 46bc6e1eb8f..e028e3ad389 100644 --- a/src/bindings/python/src/pyopenvino/pyopenvino.cpp +++ b/src/bindings/python/src/pyopenvino/pyopenvino.cpp @@ -24,6 +24,7 @@ #include "pyopenvino/core/compiled_model.hpp" #include "pyopenvino/core/containers.hpp" #include "pyopenvino/core/core.hpp" +#include "pyopenvino/core/extension.hpp" #include "pyopenvino/core/ie_parameter.hpp" #include "pyopenvino/core/infer_request.hpp" #include "pyopenvino/core/offline_transformations.hpp" @@ -31,6 +32,7 @@ #include "pyopenvino/core/tensor.hpp" #include "pyopenvino/core/variable_state.hpp" #include "pyopenvino/core/version.hpp" +#include "pyopenvino/frontend/extensions.hpp" #include "pyopenvino/frontend/frontend.hpp" #include "pyopenvino/frontend/inputmodel.hpp" #include "pyopenvino/frontend/manager.hpp" @@ -124,6 +126,7 @@ PYBIND11_MODULE(pyopenvino, m) { regclass_Parameter(m); regclass_AsyncInferQueue(m); regclass_ProfilingInfo(m); + regclass_Extension(m); regclass_frontend_Place(m); regclass_frontend_InitializationFailureFrontEnd(m); @@ -131,11 +134,12 @@ PYBIND11_MODULE(pyopenvino, m) { regclass_frontend_OpConversionFailureFrontEnd(m); regclass_frontend_OpValidationFailureFrontEnd(m); regclass_frontend_NotImplementedFailureFrontEnd(m); - regclass_frontend_Extension(m); regclass_frontend_FrontEndManager(m); regclass_frontend_FrontEnd(m); regclass_frontend_InputModel(m); regclass_frontend_TelemetryExtension(m); + regclass_frontend_DecoderTransformationExtension(m); + regclass_frontend_JsonConfigExtension(m); regmodule_offline_transformations(m); } diff --git a/src/common/offline_transformations/CMakeLists.txt b/src/common/offline_transformations/CMakeLists.txt index 36e41831f76..359cda2fa77 100644 --- a/src/common/offline_transformations/CMakeLists.txt +++ b/src/common/offline_transformations/CMakeLists.txt @@ -20,14 +20,18 @@ source_group("include" FILES ${PUBLIC_HEADERS}) add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${LIBRARY_SRC} ${PUBLIC_HEADERS}) target_link_libraries(${TARGET_NAME} PUBLIC ngraph inference_engine_transformations ngraph::reference - nlohmann_json_schema_validator - PRIVATE openvino::itt pugixml::static) + PRIVATE openvino::itt pugixml::static openvino::frontend::common + nlohmann_json_schema_validator nlohmann_json) target_include_directories(${TARGET_NAME} PUBLIC ${PUBLIC_HEADERS_DIR} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") add_cpplint_target(${TARGET_NAME}_cpplint FOR_TARGETS ${TARGET_NAME}) +# Add include path to so_extension.hpp +set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/json_extension/json_config.cpp + PROPERTIES INCLUDE_DIRECTORIES "${OpenVINO_SOURCE_DIR}/src/core/src/") + # developer package openvino_developer_export_targets(COMPONENT core TARGETS ${TARGET_NAME}) diff --git a/src/common/offline_transformations/include/extension/json_config.hpp b/src/common/offline_transformations/include/extension/json_config.hpp new file mode 100644 index 00000000000..863a12e8ba8 --- /dev/null +++ b/src/common/offline_transformations/include/extension/json_config.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "openvino/frontend/visibility.hpp" + +namespace ov { +namespace frontend { + +/// \brief JsonConfigExtension reads MO config file and delegate transformation functionality to specified +/// transformation ID specified in the config. +class JsonConfigExtension : public DecoderTransformationExtension { +public: + explicit JsonConfigExtension(const std::string& config_path); + +protected: + std::vector m_loaded_extensions; + std::vector, std::string>> m_target_extensions; +}; +} // namespace frontend +} // namespace ov diff --git a/src/common/offline_transformations/include/extension/json_transformation.hpp b/src/common/offline_transformations/include/extension/json_transformation.hpp new file mode 100644 index 00000000000..604c7e74cd4 --- /dev/null +++ b/src/common/offline_transformations/include/extension/json_transformation.hpp @@ -0,0 +1,54 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "openvino/core/extension.hpp" +#include "openvino/pass/graph_rewrite.hpp" +#include "openvino/pass/manager.hpp" +#include "openvino/pass/pass.hpp" + +namespace ov { +namespace frontend { + +/// \brief Describes transformation that JsonConfigExtension can use as a target transformation specified by ID. +/// JsonTransformationExtension passes JSON parsed object and matched points in the graph to JsonTransformationExtension +/// instance, which is derived from DecoderTransformationExtension. DecoderTransformationExtension itself cannot be +/// used for this purpose because we need to pass those additional objects which are the result of JSON parsing and +/// graph matching that JsonTransformationExtension performs. +/// +/// This class is left for backward compatibility only. In the future we would like to get rid off this class as well +/// as from JsonConfigExtension, and users will use DecoderTransformationExtension only to match sub-graph and modify it +/// like we do in any other transformations. +/// +/// Unlike DecoderTransformationExtension, which is initialized by some ready-to-use transformation code and is not used +/// to derive new classes by regular users, this class is intended to be derived from and it doesn't have convenient +/// ctos to be initialized. So it is intended for more advanced, internal users inside such components like Model +/// Optimizer. +class JsonTransformationExtension : public DecoderTransformationExtension { +public: + explicit JsonTransformationExtension(const std::string& id) : m_id(id) {} + + /// \brief The name of the transformation to identify it from JSON file field 'id' + const std::string& id() const { + return m_id; + } + + /// \brief Modifies OV Model according to the provided rules. + /// + /// \param[in] function The OV Model object. + /// \param[in] replacement_descriptions The rules to modify the model in .json format. + virtual bool transform(const std::shared_ptr& function, + const std::string& replacement_descriptions) const = 0; + +private: + std::string m_id; +}; +} // namespace frontend +} // namespace ov diff --git a/src/common/offline_transformations/src/json_extension/json_config.cpp b/src/common/offline_transformations/src/json_extension/json_config.cpp new file mode 100644 index 00000000000..25d05ca2085 --- /dev/null +++ b/src/common/offline_transformations/src/json_extension/json_config.cpp @@ -0,0 +1,204 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "extension/json_config.hpp" + +#include "nlohmann/json-schema.hpp" +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "extension/json_transformation.hpp" +#include "so_extension.hpp" + +namespace { +static const nlohmann::json validation_schema = +R"( +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Root", + "type": "array", + "default": [], + "items": { + "$id": "#root/items", + "title": "Items", + "type": "object", + "required": [ + "id", + "match_kind" + ], + "properties": { + "custom_attributes": { + "$id": "#root/items/custom_attributes", + "title": "Custom_attributes", + "type": "object", + "properties": { + } + }, + "id": { + "$id": "#root/items/id", + "title": "Id", + "type": "string", + "pattern": "^.*$", + "minLength": 1 + }, + "inputs": { + "$id": "#root/items/inputs", + "title": "Inputs", + "type": "array", + "default": [], + "items": { + "$id": "#root/items/inputs/items", + "title": "Items", + "type": "array", + "default": [], + "items": { + "$id": "#root/items/inputs/items/items", + "title": "Items", + "type": "object", + "properties": { + "node": { + "$id": "#root/items/inputs/items/items/node", + "title": "Node", + "type": "string", + "default": "", + "pattern": "^.*$" + }, + "port": { + "$id": "#root/items/inputs/items/items/port", + "title": "Port", + "type": "integer", + "default": 0 + } + }, + "required": ["node", "port"] + } + + } + }, + "instances": { + "$id": "#root/items/instances", + "title": "Instances", + "type": ["array", "object"], + "items": { + "$id": "#root/items/instances/items", + "title": "Items", + "type": "string", + "default": "", + "pattern": "^.*$" + } + }, + "match_kind": { + "$id": "#root/items/match_kind", + "title": "Match_kind", + "type": "string", + "enum": ["points", "scope", "general"], + "default": "points", + "pattern": "^.*$" + }, + "outputs": { + "$id": "#root/items/outputs", + "title": "Outputs", + "type": "array", + "default": [], + "items": { + "$id": "#root/items/outputs/items", + "title": "Items", + "type": "object", + "properties": { + "node": { + "$id": "#root/items/outputs/items/node", + "title": "Node", + "type": "string", + "default": "", + "pattern": "^.*$" + }, + "port": { + "$id": "#root/items/outputs/items/port", + "title": "Port", + "type": "integer", + "default": 0 + } + }, + "required": ["node", "port"] + } + + }, + "include_inputs_to_sub_graph": { + "$id": "#root/items/include_inputs_to_sub_graph", + "title": "Include_inputs_to_sub_graph", + "type": "boolean", + "default": false + }, + "include_outputs_to_sub_graph": { + "$id": "#root/items/include_outputs_to_sub_graph", + "title": "Include_outputs_to_sub_graph", + "type": "boolean", + "default": false + } + } + } +} +)"_json; +} // namespace + +using namespace ov; +using namespace ov::frontend; + +JsonConfigExtension::JsonConfigExtension(const std::string& config_path) + : DecoderTransformationExtension([this](std::shared_ptr f) { + bool res = false; + for (const auto& target_extension : m_target_extensions) { + if (auto extension = std::dynamic_pointer_cast(target_extension.first)) { + res |= extension->transform(f, target_extension.second); + } + } + return res; + }) { + // Load JSON config + nlohmann::json config_json; + std::ifstream config_file(config_path); + config_file >> config_json; + + // Validate JSON config + nlohmann::json_schema::json_validator validator; + try { + validator.set_root_schema(validation_schema); + } catch (const std::exception& e) { + OPENVINO_ASSERT(false, "Invalid json schema : ", e.what()); + } + + try { + validator.validate(config_json); + } catch (const std::exception& e) { + OPENVINO_ASSERT(false, "Json schema validation failed: ", e.what()); + } + + // Parse JSON Extensions + + // Group sections describing transformations by library. + std::unordered_map lib_to_sections; + for (const auto& section : config_json) { + lib_to_sections[section["library"]].push_back(section); + } + + // Load all extensions in each library and select required + for (const auto& it : lib_to_sections) { + const auto& lib = it.first; + const auto& sections = it.second; + + auto extensions = ov::detail::load_extensions(lib); + m_loaded_extensions.insert(m_loaded_extensions.end(), extensions.begin(), extensions.end()); + for (const auto& ext : extensions) { + auto so_extension = std::dynamic_pointer_cast(ext); + OPENVINO_ASSERT(so_extension, "Unexpected extension type loaded from shared library."); + auto extension = so_extension->extension(); + if (auto json_ext = std::dynamic_pointer_cast(extension)) { + for (const auto& section : sections) { + if (section["id"] == json_ext->id()) { + m_target_extensions.push_back({json_ext, section.dump()}); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/core/include/openvino/pass/pass.hpp b/src/core/include/openvino/pass/pass.hpp index ad0b9d65b81..fd96c27db03 100644 --- a/src/core/include/openvino/pass/pass.hpp +++ b/src/core/include/openvino/pass/pass.hpp @@ -89,7 +89,7 @@ private: class OPENVINO_API ModelPass : public PassBase { public: - OPENVINO_RTTI("ov::pass::FunctionPass"); + OPENVINO_RTTI("ov::pass::ModelPass"); ~ModelPass() override; OPENVINO_DEPRECATED("run_on_function() method is deprecated. Please use run_on_model() instead.") virtual bool run_on_function(std::shared_ptr m); diff --git a/src/core/tests/CMakeLists.txt b/src/core/tests/CMakeLists.txt index ec539ce6c11..63c977f86fe 100644 --- a/src/core/tests/CMakeLists.txt +++ b/src/core/tests/CMakeLists.txt @@ -517,7 +517,8 @@ if (ENABLE_OV_ONNX_FRONTEND) endif() # SOURCE FOR FRONTEND TESTING -file(GLOB FRONTEND_TESTS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/frontend/frontend_manager.cpp) +file(GLOB FRONTEND_TESTS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/frontend/frontend_manager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/frontend/decoder_transformation_extension.cpp) list(APPEND SRC ${FRONTEND_TESTS_SRC}) foreach(src IN LISTS SRC MULTI_TEST_SRC OP_EVAL_TEST_SRC) diff --git a/src/core/tests/frontend/decoder_transformation_extension.cpp b/src/core/tests/frontend/decoder_transformation_extension.cpp new file mode 100644 index 00000000000..c4f59ffeb1b --- /dev/null +++ b/src/core/tests/frontend/decoder_transformation_extension.cpp @@ -0,0 +1,55 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "gtest/gtest.h" +#include "openvino/frontend/extension/decoder_transformation.hpp" + +using namespace ov::frontend; + +TEST(DecoderTransformation, MatcherPass) { + bool flag = false; + DecoderTransformationExtension decoder_ext([&](ov::pass::MatcherPass* matcher) { + flag = true; + }); + + ov::pass::Manager manager; + decoder_ext.register_pass(manager); + manager.run_passes(std::make_shared(ov::ResultVector{}, ov::ParameterVector{})); + EXPECT_EQ(flag, true); +} + +TEST(DecoderTransformation, FunctionPass) { + bool flag = false; + DecoderTransformationExtension decoder_ext([&](const std::shared_ptr&) { + flag = true; + return flag; + }); + + ov::pass::Manager manager; + decoder_ext.register_pass(manager); + manager.run_passes(std::make_shared(ov::ResultVector{}, ov::ParameterVector{})); + EXPECT_EQ(flag, true); +} + +TEST(DecoderTransformation, TestPass) { + class TestPass : public ov::pass::ModelPass { + public: + OPENVINO_RTTI("ov::pass::TestPass"); + TestPass() = default; + TestPass(const TestPass& tp) = default; + bool run_on_model(const std::shared_ptr&) override { + *m_flag = true; + return *m_flag; + } + std::shared_ptr m_flag = std::make_shared(false); + } test_pass; + DecoderTransformationExtension decoder_ext(test_pass); + + ov::pass::Manager manager; + decoder_ext.register_pass(manager); + manager.run_passes(std::make_shared(ov::ResultVector{}, ov::ParameterVector{})); + EXPECT_EQ(*test_pass.m_flag, true); +} diff --git a/src/core/tests/frontend/onnx/json_config_extension.cpp b/src/core/tests/frontend/onnx/json_config_extension.cpp new file mode 100644 index 00000000000..a30a1df137e --- /dev/null +++ b/src/core/tests/frontend/onnx/json_config_extension.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "json_config.hpp" +#include "onnx_utils.hpp" + +using namespace ov::frontend; + +using ONNXJsonConfigTest = FrontEndJsonConfigTest; + +static JsonConfigFEParam getTestData() { + JsonConfigFEParam res; + res.m_frontEndName = ONNX_FE; + res.m_modelsPath = std::string(TEST_ONNX_MODELS_DIRNAME); + res.m_modelName = "controlflow/loop_2d_add.onnx"; + return res; +} + +INSTANTIATE_TEST_SUITE_P(ONNXJsonConfigTest, + FrontEndJsonConfigTest, + ::testing::Values(getTestData()), + FrontEndJsonConfigTest::getTestCaseName); diff --git a/src/core/tests/frontend/paddlepaddle/json_config_extension.cpp b/src/core/tests/frontend/paddlepaddle/json_config_extension.cpp new file mode 100644 index 00000000000..507a3f9db23 --- /dev/null +++ b/src/core/tests/frontend/paddlepaddle/json_config_extension.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "json_config.hpp" +#include "paddle_utils.hpp" + +using namespace ov::frontend; + +using PDPDJsonConfigTest = FrontEndJsonConfigTest; + +static JsonConfigFEParam getTestData() { + JsonConfigFEParam res; + res.m_frontEndName = PADDLE_FE; + res.m_modelsPath = std::string(TEST_PADDLE_MODELS_DIRNAME); + res.m_modelName = "relu/relu.pdmodel"; + return res; +} + +INSTANTIATE_TEST_SUITE_P(PDPDJsonConfigTest, + FrontEndJsonConfigTest, + ::testing::Values(getTestData()), + FrontEndJsonConfigTest::getTestCaseName); diff --git a/src/core/tests/frontend/shared/CMakeLists.txt b/src/core/tests/frontend/shared/CMakeLists.txt index ae4bcb5ac04..71cf6f5c92a 100644 --- a/src/core/tests/frontend/shared/CMakeLists.txt +++ b/src/core/tests/frontend/shared/CMakeLists.txt @@ -9,10 +9,14 @@ file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp) add_library(${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ${LIBRARY_SRC} ${LIBRARY_HEADERS}) +add_subdirectory(test_builtin_extensions_1) +add_subdirectory(test_builtin_extensions_2) + target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../..) target_link_libraries(${TARGET_NAME} PUBLIC frontend_common engines_test_util - ngraph cnpy commonTestUtils ngraph_test_util openvino::util) + offline_transformations ngraph cnpy commonTestUtils ngraph_test_util openvino::util + nlohmann_json_schema_validator test_builtin_extensions_1 test_builtin_extensions_2) target_compile_definitions(${TARGET_NAME} PRIVATE diff --git a/src/core/tests/frontend/shared/include/json_config.hpp b/src/core/tests/frontend/shared/include/json_config.hpp new file mode 100644 index 00000000000..9ca0b130602 --- /dev/null +++ b/src/core/tests/frontend/shared/include/json_config.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include + +#include +#include + +class JsonConfigExtensionWrapper : public ov::frontend::JsonConfigExtension { +public: + explicit JsonConfigExtensionWrapper(const std::string& config_path) + : ov::frontend::JsonConfigExtension(config_path){}; + ~JsonConfigExtensionWrapper() override = default; + + std::vector get_loaded_extensions() { + return m_loaded_extensions; + }; + + std::vector, std::string>> get_target_extensions() { + return m_target_extensions; + } +}; + +struct JsonConfigFEParam { + std::string m_frontEndName; + std::string m_modelsPath; + std::string m_modelName; +}; + +class FrontEndJsonConfigTest : public ::testing::TestWithParam { +public: + std::string m_file_name = "test_json.json"; + std::ofstream m_output_json; + JsonConfigFEParam m_param; + ov::frontend::FrontEndManager m_fem; + + static std::string getTestCaseName(const testing::TestParamInfo& obj); + + void SetUp() override; + void TearDown() override; + +protected: + void generate_json_config(); + void initParamTest(); +}; diff --git a/src/core/tests/frontend/shared/src/json_config.cpp b/src/core/tests/frontend/shared/src/json_config.cpp new file mode 100644 index 00000000000..a12dab60425 --- /dev/null +++ b/src/core/tests/frontend/shared/src/json_config.cpp @@ -0,0 +1,194 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "json_config.hpp" + +#include +#include +#include +#include +#include + +#include "utils.hpp" + +using namespace ov::frontend; + +std::string FrontEndJsonConfigTest::getTestCaseName(const testing::TestParamInfo& obj) { + std::string res = obj.param.m_frontEndName + "_" + obj.param.m_modelName; + return FrontEndTestUtils::fileToTestName(res); +} + +void FrontEndJsonConfigTest::SetUp() { + FrontEndTestUtils::setupTestEnv(); + m_fem = FrontEndManager(); // re-initialize after setting up environment + initParamTest(); +} + +void FrontEndJsonConfigTest::TearDown() { + m_output_json.close(); + std::remove(m_file_name.c_str()); +} + +void FrontEndJsonConfigTest::initParamTest() { + m_param = GetParam(); + m_param.m_modelName = FrontEndTestUtils::make_model_path(m_param.m_modelsPath + m_param.m_modelName); +} + +inline std::string get_lib_path(const std::string& lib_name) { + return ov::util::make_plugin_library_name(ov::util::get_ov_lib_path(), lib_name + IE_BUILD_POSTFIX); +} + +void FrontEndJsonConfigTest::generate_json_config() { + std::string json = R"( + [ + { + "custom_attributes": { + "test_attribute": true + }, + "id": "buildin_extensions_1::TestExtension1", + "library": "test_builtin_extensions_1", + "match_kind": "scope" + }, + { + "custom_attributes": { + "test_attribute": true + }, + "id": "buildin_extensions_2::TestExtension1", + "library": "test_builtin_extensions_2", + "match_kind": "scope" + }, + { + "custom_attributes": { + "test_attribute": true + }, + "id": "buildin_extensions_2::TestExtension2", + "library": "test_builtin_extensions_2", + "match_kind": "scope" + } + ] + )"; + nlohmann::json config_json = nlohmann::json::parse(json); + + // update lib path + for (auto& section : config_json) { + section["library"] = get_lib_path(section["library"]); + } + + m_output_json.open(m_file_name); + m_output_json << std::setw(4) << config_json << std::endl; +} + +/////////////////////////////////////////////////////////////////// + +TEST_P(FrontEndJsonConfigTest, testJsonConfig) { + EXPECT_NO_THROW(generate_json_config()); +} + +TEST_P(FrontEndJsonConfigTest, testAddJsonConfigExtension) { + EXPECT_NO_THROW(generate_json_config()); + std::map reference_map = { + {"buildin_extensions_1::TestExtension1", + nlohmann::json::parse( + R"( + { + "custom_attributes": { + "test_attribute": true + }, + "id": "buildin_extensions_1::TestExtension1", + "library": "test_builtin_extensions_1", + "match_kind": "scope" + } + )")}, + {"buildin_extensions_2::TestExtension1", + nlohmann::json::parse( + R"( + { + "custom_attributes": { + "test_attribute": true + }, + "id": "buildin_extensions_2::TestExtension1", + "library": "test_builtin_extensions_2", + "match_kind": "scope" + } + )")}, + {"buildin_extensions_2::TestExtension2", + nlohmann::json::parse( + R"( + { + "custom_attributes": { + "test_attribute": true + }, + "id": "buildin_extensions_2::TestExtension2", + "library": "test_builtin_extensions_2", + "match_kind": "scope" + } + )")}, + }; + + for (auto& ref_val : reference_map) { + ref_val.second["library"] = get_lib_path(ref_val.second["library"]); + } + + std::shared_ptr function; + { + ov::frontend::FrontEnd::Ptr m_frontEnd; + ov::frontend::InputModel::Ptr m_inputModel; + m_frontEnd = m_fem.load_by_framework(m_param.m_frontEndName); + + auto json_config_ext = std::make_shared(m_file_name); + m_frontEnd->add_extension(json_config_ext); + + auto loaded_ext = json_config_ext->get_loaded_extensions(); + auto target_ext = json_config_ext->get_target_extensions(); + + EXPECT_EQ(loaded_ext.size(), 3); + EXPECT_EQ(target_ext.size(), 3); + + for (const auto& target : target_ext) { + auto transformation = std::dynamic_pointer_cast(target.first); + EXPECT_NE(transformation, nullptr); + EXPECT_EQ(reference_map.at(transformation->id()).dump(), target.second); + } + ASSERT_NO_THROW(m_inputModel = m_frontEnd->load(m_param.m_modelName)); + ASSERT_NE(m_inputModel, nullptr); + + ASSERT_NO_THROW(function = m_frontEnd->convert(m_inputModel)); + ASSERT_NE(function, nullptr); + EXPECT_EQ(function->get_friendly_name(), "TestFunction"); + } +} + +TEST_P(FrontEndJsonConfigTest, compareFunctions) { + EXPECT_NO_THROW(generate_json_config()); + + std::shared_ptr function; + { + ov::frontend::FrontEnd::Ptr m_frontEnd; + ov::frontend::InputModel::Ptr m_inputModel; + m_frontEnd = m_fem.load_by_framework(m_param.m_frontEndName); + + auto json_config_ext = std::make_shared(m_file_name); + m_frontEnd->add_extension(json_config_ext); + + ASSERT_NO_THROW(m_inputModel = m_frontEnd->load(m_param.m_modelName)); + ASSERT_NE(m_inputModel, nullptr); + + ASSERT_NO_THROW(function = m_frontEnd->convert(m_inputModel)); + ASSERT_NE(function, nullptr); + } + + std::shared_ptr function_ref; + { + ov::frontend::FrontEnd::Ptr m_frontEnd; + ov::frontend::InputModel::Ptr m_inputModel; + m_frontEnd = m_fem.load_by_framework(m_param.m_frontEndName); + + ASSERT_NO_THROW(m_inputModel = m_frontEnd->load(m_param.m_modelName)); + ASSERT_NE(m_inputModel, nullptr); + + ASSERT_NO_THROW(function_ref = m_frontEnd->convert(m_inputModel)); + ASSERT_NE(function, nullptr); + } + compare_functions(function, function_ref); +} diff --git a/src/core/tests/frontend/shared/src/telemetry.cpp b/src/core/tests/frontend/shared/src/telemetry.cpp index c96b05b990e..38188dae7e8 100644 --- a/src/core/tests/frontend/shared/src/telemetry.cpp +++ b/src/core/tests/frontend/shared/src/telemetry.cpp @@ -4,8 +4,7 @@ #include "telemetry.hpp" -#include - +#include "openvino/frontend/extension/telemetry.hpp" #include "utils.hpp" using namespace ov::frontend; diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt b/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt new file mode 100644 index 00000000000..cd843295ae2 --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +set(TARGET_NAME "test_builtin_extensions_1") + +file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) + +# Create library +add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS}) + +target_link_libraries(${TARGET_NAME} PUBLIC nlohmann_json inference_engine_transformations frontend_common + offline_transformations) + +add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) + +if(WIN32) + install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL + LIBRARY DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL) +else() + install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION tests/lib COMPONENT tests EXCLUDE_FROM_ALL + LIBRARY DESTINATION tests/lib COMPONENT tests EXCLUDE_FROM_ALL) +endif() diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp b/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp new file mode 100644 index 00000000000..ada294f7fc2 --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/builtin_extensions.cpp @@ -0,0 +1,9 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "test_extension.hpp" + +OPENVINO_CREATE_EXTENSIONS(std::vector({std::make_shared()})); diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp new file mode 100644 index 00000000000..796bd3c2df9 --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "test_extension.hpp" + +#include + +bool TestExtension1::transform(const std::shared_ptr& function, const std::string& config) const { + function->set_friendly_name("TestFunction"); + return true; +} + +TestExtension1::TestExtension1() : ov::frontend::JsonTransformationExtension("buildin_extensions_1::TestExtension1") {} diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp new file mode 100644 index 00000000000..83b69a55be3 --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_1/test_extension.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +class TestExtension1 : public ov::frontend::JsonTransformationExtension { +public: + TestExtension1(); + + bool transform(const std::shared_ptr& function, const std::string& config) const override; +}; diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt b/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt new file mode 100644 index 00000000000..e773d4fd02b --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_2/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (C) 2018-2021 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 +# + +set(TARGET_NAME "test_builtin_extensions_2") + +file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) + +# Create library +add_library(${TARGET_NAME} SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS}) + +target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json inference_engine_transformations frontend_common + offline_transformations) + +add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME}) + +if(WIN32) + install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL + LIBRARY DESTINATION tests COMPONENT tests EXCLUDE_FROM_ALL) +else() + install(TARGETS ${TARGET_NAME} + RUNTIME DESTINATION tests/lib COMPONENT tests EXCLUDE_FROM_ALL + LIBRARY DESTINATION tests/lib COMPONENT tests EXCLUDE_FROM_ALL) +endif() diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_2/builtin_extensions.cpp b/src/core/tests/frontend/shared/test_builtin_extensions_2/builtin_extensions.cpp new file mode 100644 index 00000000000..f601200dbff --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_2/builtin_extensions.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "test_extensions.hpp" + +OPENVINO_CREATE_EXTENSIONS(std::vector({std::make_shared(), + std::make_shared()})); diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_2/test_extensions.cpp b/src/core/tests/frontend/shared/test_builtin_extensions_2/test_extensions.cpp new file mode 100644 index 00000000000..e94716c6416 --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_2/test_extensions.cpp @@ -0,0 +1,21 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "test_extensions.hpp" + +#include + +bool TestExtension1::transform(const std::shared_ptr& function, const std::string& config) const { + function->set_friendly_name("TestFunction"); + return true; +} + +TestExtension1::TestExtension1() : ov::frontend::JsonTransformationExtension("buildin_extensions_2::TestExtension1") {} + +bool TestExtension2::transform(const std::shared_ptr& function, const std::string& config) const { + function->set_friendly_name("TestFunction"); + return true; +} + +TestExtension2::TestExtension2() : ov::frontend::JsonTransformationExtension("buildin_extensions_2::TestExtension2") {} diff --git a/src/core/tests/frontend/shared/test_builtin_extensions_2/test_extensions.hpp b/src/core/tests/frontend/shared/test_builtin_extensions_2/test_extensions.hpp new file mode 100644 index 00000000000..337f1f2e9b2 --- /dev/null +++ b/src/core/tests/frontend/shared/test_builtin_extensions_2/test_extensions.hpp @@ -0,0 +1,22 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include + +class TestExtension1 : public ov::frontend::JsonTransformationExtension { +public: + TestExtension1(); + + bool transform(const std::shared_ptr& function, const std::string& config) const override; +}; + +class TestExtension2 : public ov::frontend::JsonTransformationExtension { +public: + TestExtension2(); + + bool transform(const std::shared_ptr& function, const std::string& config) const override; +}; diff --git a/src/core/tests/frontend/tensorflow/json_config_extension.cpp b/src/core/tests/frontend/tensorflow/json_config_extension.cpp new file mode 100644 index 00000000000..76a68045efc --- /dev/null +++ b/src/core/tests/frontend/tensorflow/json_config_extension.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "json_config.hpp" +#include "tf_utils.hpp" + +using namespace ov::frontend; + +using TFJsonConfigTest = FrontEndJsonConfigTest; + +static JsonConfigFEParam getTestData() { + JsonConfigFEParam res; + res.m_frontEndName = TF_FE; + res.m_modelsPath = std::string(TEST_TENSORFLOW_MODELS_DIRNAME); + res.m_modelName = "2in_2out/2in_2out.pb"; + return res; +} + +INSTANTIATE_TEST_SUITE_P(TFJsonConfigTest, + FrontEndJsonConfigTest, + ::testing::Values(getTestData()), + FrontEndJsonConfigTest::getTestCaseName); diff --git a/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp b/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp new file mode 100644 index 00000000000..2b0d1672b31 --- /dev/null +++ b/src/frontends/common/include/openvino/frontend/extension/decoder_transformation.hpp @@ -0,0 +1,56 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include + +#include "openvino/core/extension.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 { + +/// \brief Holds a transformation that is applied just after the original model graph is decoded. +/// This class is a holder for transformation. The transformation can be specified as +/// FunctionPass or MathcerPass derivatives or as a function that can be used to build corresponding +/// FunctionPass or MatcherPass object. The type of the extension is determined in the moment of creation by +/// calling corresponding ctor. +class FRONTEND_API DecoderTransformationExtension : public ov::Extension { +public: + DecoderTransformationExtension() = default; + + /// \brief Create a custom functional pass where code of the pass is implemented as a function. + explicit DecoderTransformationExtension(const std::function)>& function_pass); + + /// \brief Create a custom matcher pass where the code of matcher pass initialization is a given function. + explicit DecoderTransformationExtension( + const std::function& matcher_pass_initializer); + + /// \brief Register existing transformation object which will be copied and kept for further registration. + template ::value, bool>::type = true> + explicit DecoderTransformationExtension(const Transformation& transformation) + : m_registration([=](ov::pass::Manager& manager) { + manager.register_pass(transformation); + }) {} + + /// \brief Register pass from this object in a given pass manager object + void register_pass(ov::pass::Manager& manager) const; + +protected: + void set_registration(const std::function& registration) { + m_registration = registration; + } + +private: + std::function m_registration; +}; +} // namespace frontend +} // namespace ov diff --git a/src/frontends/common/include/openvino/frontend/telemetry_extension.hpp b/src/frontends/common/include/openvino/frontend/extension/telemetry.hpp similarity index 96% rename from src/frontends/common/include/openvino/frontend/telemetry_extension.hpp rename to src/frontends/common/include/openvino/frontend/extension/telemetry.hpp index b1454414b3e..22a03d93b51 100644 --- a/src/frontends/common/include/openvino/frontend/telemetry_extension.hpp +++ b/src/frontends/common/include/openvino/frontend/extension/telemetry.hpp @@ -9,10 +9,10 @@ #include #include "openvino/core/extension.hpp" +#include "openvino/frontend/visibility.hpp" #include "openvino/pass/graph_rewrite.hpp" #include "openvino/pass/manager.hpp" #include "openvino/pass/pass.hpp" -#include "visibility.hpp" namespace ov { namespace frontend { diff --git a/src/frontends/common/src/extension/decoder_transformation.cpp b/src/frontends/common/src/extension/decoder_transformation.cpp new file mode 100644 index 00000000000..3f66563ab36 --- /dev/null +++ b/src/frontends/common/src/extension/decoder_transformation.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "openvino/frontend/extension/decoder_transformation.hpp" + +#include + +using namespace ov; +using namespace ov::frontend; + +/// \brief Helper class to register user function as a FunctionPass +class CustomModelPass : public ov::pass::ModelPass { +public: + explicit CustomModelPass(std::function)> pass) : m_pass(std::move(pass)) {} + + bool run_on_model(const std::shared_ptr& f) override { + return m_pass(f); + } + +private: + std::function)> m_pass; +}; + +/// \brief Helper class to register user matcher pass initialization as a MatcherPass +class CustomMatcherPass : public ov::pass::MatcherPass { +public: + explicit CustomMatcherPass(const std::function& matcher_pass_initializer) { + matcher_pass_initializer(this); + } +}; + +DecoderTransformationExtension::DecoderTransformationExtension( + const std::function)>& function_pass) + : m_registration([=](ov::pass::Manager& manager) { + manager.register_pass(function_pass); + }) {} + +DecoderTransformationExtension::DecoderTransformationExtension( + const std::function& matcher_pass_initializer) + : m_registration([=](ov::pass::Manager& manager) { + manager.register_pass(matcher_pass_initializer); + }) {} + +void DecoderTransformationExtension::register_pass(ov::pass::Manager& manager) const { + m_registration(manager); +} diff --git a/src/frontends/common/src/telemetry_extension.cpp b/src/frontends/common/src/extension/telemetry.cpp similarity index 95% rename from src/frontends/common/src/telemetry_extension.cpp rename to src/frontends/common/src/extension/telemetry.cpp index 8dfa0c3725d..7cb172ec631 100644 --- a/src/frontends/common/src/telemetry_extension.cpp +++ b/src/frontends/common/src/extension/telemetry.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "openvino/frontend/telemetry_extension.hpp" +#include "openvino/frontend/extension/telemetry.hpp" using namespace ov::frontend; diff --git a/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp b/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp index 5a393a0c2cb..17d7f1cf494 100644 --- a/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp +++ b/src/frontends/ir/include/openvino/frontend/ir/frontend.hpp @@ -5,9 +5,9 @@ #pragma once #include "openvino/frontend/exception.hpp" +#include "openvino/frontend/extension/telemetry.hpp" #include "openvino/frontend/frontend.hpp" #include "openvino/frontend/ir/visibility.hpp" -#include "openvino/frontend/telemetry_extension.hpp" #include "openvino/openvino.hpp" namespace ov { diff --git a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp index defe06c97b9..cfa4016e4b5 100644 --- a/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp +++ b/src/frontends/onnx/frontend/include/openvino/frontend/onnx/frontend.hpp @@ -5,7 +5,8 @@ #pragma once #include -#include + +#include "openvino/frontend/extension/telemetry.hpp" #ifdef OPENVINO_STATIC_LIBRARY # define ONNX_FRONTEND_API diff --git a/src/frontends/onnx/frontend/src/core/graph.hpp b/src/frontends/onnx/frontend/src/core/graph.hpp index 49991b29754..35d9a20d2b7 100644 --- a/src/frontends/onnx/frontend/src/core/graph.hpp +++ b/src/frontends/onnx/frontend/src/core/graph.hpp @@ -15,7 +15,7 @@ #include "ngraph/function.hpp" #include "ngraph/op/parameter.hpp" #include "onnx_import/core/operator_set.hpp" -#include "openvino/frontend/telemetry_extension.hpp" +#include "openvino/frontend/extension/telemetry.hpp" namespace ngraph { namespace onnx_import { diff --git a/src/frontends/onnx/frontend/src/editor.hpp b/src/frontends/onnx/frontend/src/editor.hpp index 39ec6125ef6..1f4a37027ff 100644 --- a/src/frontends/onnx/frontend/src/editor.hpp +++ b/src/frontends/onnx/frontend/src/editor.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include "editor_types.hpp" #include "ngraph/function.hpp" @@ -15,6 +14,7 @@ #include "ngraph/partial_shape.hpp" #include "ngraph/type/element_type.hpp" #include "onnx_import/onnx_importer_visibility.hpp" +#include "openvino/frontend/extension/telemetry.hpp" namespace ov { namespace onnx_editor { diff --git a/src/frontends/onnx/frontend/src/frontend.cpp b/src/frontends/onnx/frontend/src/frontend.cpp index c8e2ba554f1..9f7180b86ce 100644 --- a/src/frontends/onnx/frontend/src/frontend.cpp +++ b/src/frontends/onnx/frontend/src/frontend.cpp @@ -8,11 +8,11 @@ #include #include #include -#include #include #include #include "onnx_common/onnx_model_validator.hpp" +#include "openvino/frontend/extension/telemetry.hpp" using namespace ov; using namespace ov::frontend::onnx; diff --git a/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp b/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp index dba12e3b2c6..c564cfe7210 100644 --- a/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp +++ b/src/frontends/onnx/frontend/src/utils/onnx_internal.hpp @@ -8,7 +8,7 @@ #include #include "ngraph/function.hpp" -#include "openvino/frontend/telemetry_extension.hpp" +#include "openvino/frontend/extension/telemetry.hpp" namespace ONNX_NAMESPACE { class ModelProto; diff --git a/src/frontends/paddlepaddle/include/paddlepaddle_frontend/frontend.hpp b/src/frontends/paddlepaddle/include/paddlepaddle_frontend/frontend.hpp index a88f13c779e..fd705b2913e 100644 --- a/src/frontends/paddlepaddle/include/paddlepaddle_frontend/frontend.hpp +++ b/src/frontends/paddlepaddle/include/paddlepaddle_frontend/frontend.hpp @@ -4,8 +4,9 @@ #pragma once +#include +#include #include -#include #include "exceptions.hpp" #include "model.hpp" @@ -70,6 +71,7 @@ private: std::function(const std::map>&, const std::shared_ptr&)> func); std::shared_ptr m_telemetry; + std::vector> m_transformation_extensions; }; } // namespace frontend diff --git a/src/frontends/paddlepaddle/include/paddlepaddle_frontend/model.hpp b/src/frontends/paddlepaddle/include/paddlepaddle_frontend/model.hpp index 3fa9dbe7a99..491af81b3ba 100644 --- a/src/frontends/paddlepaddle/include/paddlepaddle_frontend/model.hpp +++ b/src/frontends/paddlepaddle/include/paddlepaddle_frontend/model.hpp @@ -4,8 +4,8 @@ #pragma once +#include #include -#include #include "paddlepaddle_frontend/utility.hpp" diff --git a/src/frontends/paddlepaddle/src/frontend.cpp b/src/frontends/paddlepaddle/src/frontend.cpp index e9a27c643f1..c6e41123bdd 100644 --- a/src/frontends/paddlepaddle/src/frontend.cpp +++ b/src/frontends/paddlepaddle/src/frontend.cpp @@ -278,6 +278,20 @@ InputModel::Ptr FrontEndPDPD::load_impl(const std::vector& variants) co std::shared_ptr FrontEndPDPD::convert(const InputModel::Ptr& model) const { auto pdpd_model = std::dynamic_pointer_cast(model); + FRONT_END_GENERAL_CHECK(pdpd_model != nullptr, "Invalid input model"); + + if (!m_transformation_extensions.empty()) { + auto function = decode(model); + + pass::Manager manager; + for (const auto& transformation : m_transformation_extensions) { + transformation->register_pass(manager); + } + manager.run_passes(function); + convert(function); + return function; + } + std::map CREATORS_MAP = pdpd::get_supported_ops(); auto f = convert_each_node( pdpd_model, @@ -294,13 +308,27 @@ void FrontEndPDPD::convert(const std::shared_ptr& partiallyConverted) pdpd::get_supported_ops()); } } - for (auto result : partiallyConverted->get_results()) { + for (const auto& result : partiallyConverted->get_results()) { result->validate_and_infer_types(); } } std::shared_ptr FrontEndPDPD::convert_partially(const InputModel::Ptr& model) const { auto pdpd_model = std::dynamic_pointer_cast(model); + FRONT_END_GENERAL_CHECK(pdpd_model != nullptr, "Invalid input model"); + + if (!m_transformation_extensions.empty()) { + auto function = decode(model); + + pass::Manager manager; + for (const auto& transformation : m_transformation_extensions) { + transformation->register_pass(manager); + } + manager.run_passes(function); + convert(function); + return function; + } + std::map CREATORS_MAP = pdpd::get_supported_ops(); auto f = convert_each_node( pdpd_model, @@ -318,6 +346,8 @@ std::shared_ptr FrontEndPDPD::convert_partially(const InputModel::Ptr std::shared_ptr FrontEndPDPD::decode(const InputModel::Ptr& model) const { auto pdpd_model = std::dynamic_pointer_cast(model); + FRONT_END_GENERAL_CHECK(pdpd_model != nullptr, "Invalid input model"); + std::map CREATORS_MAP = pdpd::get_supported_ops(); auto f = convert_each_node(pdpd_model, pdpd::make_framework_node); return f; @@ -330,6 +360,8 @@ std::string FrontEndPDPD::get_name() const { void FrontEndPDPD::add_extension(const std::shared_ptr& extension) { if (auto telemetry = std::dynamic_pointer_cast(extension)) { m_telemetry = telemetry; + } else if (auto transformation = std::dynamic_pointer_cast(extension)) { + m_transformation_extensions.push_back(transformation); } } diff --git a/src/frontends/tensorflow/include/tensorflow_frontend/frontend.hpp b/src/frontends/tensorflow/include/tensorflow_frontend/frontend.hpp index 59b91d0f9d1..274f47bd041 100644 --- a/src/frontends/tensorflow/include/tensorflow_frontend/frontend.hpp +++ b/src/frontends/tensorflow/include/tensorflow_frontend/frontend.hpp @@ -9,9 +9,10 @@ #include "openvino/core/any.hpp" #include "openvino/core/node_vector.hpp" +#include "openvino/frontend/extension/decoder_transformation.hpp" +#include "openvino/frontend/extension/telemetry.hpp" #include "openvino/frontend/frontend.hpp" #include "openvino/frontend/input_model.hpp" -#include "openvino/frontend/telemetry_extension.hpp" #include "tensorflow_frontend/utility.hpp" namespace ov { @@ -83,6 +84,7 @@ private: std::shared_ptr& ng_function) const; std::shared_ptr m_telemetry; + std::vector> m_transformation_extensions; }; } // namespace frontend } // namespace ov diff --git a/src/frontends/tensorflow/src/frontend.cpp b/src/frontends/tensorflow/src/frontend.cpp index d9bbf954c02..51ee27fcc12 100644 --- a/src/frontends/tensorflow/src/frontend.cpp +++ b/src/frontends/tensorflow/src/frontend.cpp @@ -308,6 +308,20 @@ ov::frontend::InputModel::Ptr FrontEndTF::load_impl(const std::vector& std::shared_ptr FrontEndTF::convert(const ov::frontend::InputModel::Ptr& model) const { auto model_tf = std::dynamic_pointer_cast(model); + FRONT_END_GENERAL_CHECK(model_tf != nullptr, "Invalid input model"); + + if (!m_transformation_extensions.empty()) { + auto function = decode(model); + + pass::Manager manager; + for (const auto& transformation : m_transformation_extensions) { + transformation->register_pass(manager); + } + manager.run_passes(function); + convert(function); + return function; + } + std::shared_ptr f; translate_graph(model_tf, "here_should_be_a_graph_name", true, false, f); normalize(f); @@ -318,6 +332,20 @@ std::shared_ptr FrontEndTF::convert(const ov::frontend::InputModel::P std::shared_ptr FrontEndTF::convert_partially(const ov::frontend::InputModel::Ptr& model) const { auto model_tf = std::dynamic_pointer_cast(model); + FRONT_END_GENERAL_CHECK(model_tf != nullptr, "Invalid input model"); + + if (!m_transformation_extensions.empty()) { + auto function = decode(model); + + pass::Manager manager; + for (const auto& transformation : m_transformation_extensions) { + transformation->register_pass(manager); + } + manager.run_passes(function); + convert(function); + return function; + } + std::shared_ptr f; translate_graph(model_tf, "here_should_be_a_graph_name", false, false, f); normalize(f); @@ -353,5 +381,7 @@ void FrontEndTF::normalize(const std::shared_ptr& function) const { void FrontEndTF::add_extension(const std::shared_ptr& extension) { if (auto telemetry = std::dynamic_pointer_cast(extension)) { m_telemetry = telemetry; + } else if (auto transformation = std::dynamic_pointer_cast(extension)) { + m_transformation_extensions.push_back(transformation); } } diff --git a/src/frontends/tensorflow/src/model.hpp b/src/frontends/tensorflow/src/model.hpp index 631eb76f116..2ff9d73706c 100644 --- a/src/frontends/tensorflow/src/model.hpp +++ b/src/frontends/tensorflow/src/model.hpp @@ -4,9 +4,9 @@ #pragma once +#include "openvino/frontend/extension/telemetry.hpp" #include "openvino/frontend/input_model.hpp" #include "openvino/frontend/place.hpp" -#include "openvino/frontend/telemetry_extension.hpp" #include "tensorflow_frontend/graph_iterator.hpp" namespace ov { diff --git a/thirdparty/json/CMakeLists.txt b/thirdparty/json/CMakeLists.txt index 18107b7ef82..ef256d2061d 100644 --- a/thirdparty/json/CMakeLists.txt +++ b/thirdparty/json/CMakeLists.txt @@ -4,6 +4,8 @@ # suppress shadowing names warning set(JSON_SystemInclude ON CACHE BOOL "" FORCE) +# disabled due to compiler issues +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE OFF) add_subdirectory(nlohmann_json EXCLUDE_FROM_ALL) set(BUILD_SHARED_LIBS OFF)