Introduce OV Extension base api (#7562)
* Moved so loader to utils * Fixed extension tests * Fixed tests and style * Fixed style and tests * Fixed ARM build * Fix windows * Fix ieFuncTests * Wrap runtime exception * Fixed tests * Added separate new extension * Fixed unicode extension loading * Try to fix windows * Fixed windows * Fixed macro * Fixed doc * Fixed build * Fixed comments * Try to fix build * Fixed build * Fixed build * Fixed shared_from_this * Temp commit * Changed extension * Fixed merge conflicts * Removed ngraph namespace from new extensions * Fixed code style * Added core add_extension methods and tests * Added new tests * Implement tile operation * Enabled new extensions support * Fixed build * Fixed code style * Try to fix windows * Changed base extension class * Removed redundant Ptr * Fixed comments * Fixed friend decl * Fixed Windows export * Fixed centos * Added template add_extension method * Move destructor to public * Removed BaseExtension class * Added variadic add_extension methods * Fixed doc and typo * Added BaseOpDestructor * Allow to create new extension only for new operations * Revert tests * Fixed comments * Fixed comments * Fixed comment * Added SO Extension wrapper
This commit is contained in:
parent
d8f9445a96
commit
4122ef50d6
|
|
@ -1,8 +1,6 @@
|
|||
# custom OpenVINO values
|
||||
CppMethod: '^(operator\W+|[a-z_\d]+|signaling_NaN|quiet_NaN)$'
|
||||
# TODO: remove stopwatch|unsupported_op
|
||||
ClassName: '^([A-Z][\w]+|b?float16|numeric_limits|ngraph_error|stopwatch|unsupported_op)$'
|
||||
# TODO: remove oi_pair
|
||||
StructName: '^([A-Z][\w]+|element_type_traits|hash|oi_pair)$'
|
||||
FunctionName: '^(operator\W+|[a-z_\d]+)$'
|
||||
Namespace: '^([a-z\d_]+|InferenceEngine)$'
|
||||
|
|
@ -20,11 +18,11 @@ VariableReference: '^\w+$'
|
|||
|
||||
EnumName: '^[A-Z][\w]+$'
|
||||
# excepts element_type
|
||||
# TODO: Fix interpolate
|
||||
EnumConstantName: '^([A-Z\d_]+|undefined|dynamic|boolean|bf16|f16|f32|f64|i4|i8|i16|i32|i64|u1|u4|u8|u16|u32|u64|asymmetric|align_corners|round_prefer_floor|round_prefer_ceil|floor|ceil|simple|nearest|linear|linear_onnx|cubic|area|scales|sizes|half_pixel|tf_half_pixel_for_nn|pytorch_half_pixel|asymetric)$'
|
||||
# TODO: align
|
||||
UsingDeclaration: '^.*$'
|
||||
TypedefName: '^.*$'
|
||||
CxxDynamicCastExpression: '^.*$'
|
||||
|
||||
# not needed values
|
||||
ClassTemplatePartialSpecialization: 'XXXX'
|
||||
|
|
@ -65,7 +63,6 @@ StatementExpression: 'XXXX'
|
|||
GenericSelectionExpression: 'XXXX'
|
||||
GnuNullExpression: 'XXXX'
|
||||
CxxStaticCastExpression: '^.*$'
|
||||
CxxDynamicCastExpression: 'XXXX'
|
||||
CxxReinterpretCastExpression: '^.*$'
|
||||
CxxConstCastExpression: 'XXXX'
|
||||
CxxFunctionalCastExpression: '^.*$'
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ if(NOT ENABLE_DOCKER)
|
|||
|
||||
# install
|
||||
|
||||
install(TARGETS templatePlugin template_extension
|
||||
install(TARGETS templatePlugin template_extension template_ov_extension
|
||||
LIBRARY DESTINATION ${IE_CPACK_RUNTIME_PATH} COMPONENT tests EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ To add your custom nGraph operation, create a new class that extends `ngraph::Op
|
|||
|
||||
Based on that, declaration of an operation class can look as follows:
|
||||
|
||||
@snippet template_extension/op.hpp op:header
|
||||
@snippet template_extension/old/op.hpp op:header
|
||||
|
||||
### Class Fields
|
||||
|
||||
|
|
@ -35,37 +35,37 @@ nGraph operation contains two constructors:
|
|||
* Default constructor, which enables you to create an operation without attributes
|
||||
* Constructor that creates and validates an operation with specified inputs and attributes
|
||||
|
||||
@snippet template_extension/op.cpp op:ctor
|
||||
@snippet template_extension/old/op.cpp op:ctor
|
||||
|
||||
### `validate_and_infer_types()`
|
||||
|
||||
`ngraph::Node::validate_and_infer_types` method validates operation attributes and calculates output shapes using attributes of the operation.
|
||||
|
||||
@snippet template_extension/op.cpp op:validate
|
||||
@snippet template_extension/old/op.cpp op:validate
|
||||
|
||||
### `clone_with_new_inputs()`
|
||||
|
||||
`ngraph::Node::clone_with_new_inputs` method creates a copy of the nGraph operation with new inputs.
|
||||
|
||||
@snippet template_extension/op.cpp op:copy
|
||||
@snippet template_extension/old/op.cpp op:copy
|
||||
|
||||
### `visit_attributes()`
|
||||
|
||||
`ngraph::Node::visit_attributes` method enables you to visit all operation attributes.
|
||||
|
||||
@snippet template_extension/op.cpp op:visit_attributes
|
||||
@snippet template_extension/old/op.cpp op:visit_attributes
|
||||
|
||||
### `evaluate()` and `has_evaluate()`
|
||||
|
||||
`ngraph::Node::evaluate` method enables you to apply constant folding to an operation.
|
||||
|
||||
@snippet template_extension/op.cpp op:evaluate
|
||||
@snippet template_extension/old/op.cpp op:evaluate
|
||||
|
||||
## Register Custom Operations in Extension Class
|
||||
|
||||
To add custom operations to the [Extension](Extension.md) class, create an operation set with custom operations and implement the `InferenceEngine::IExtension::getOpSets` method:
|
||||
|
||||
@snippet template_extension/extension.cpp extension:getOpSets
|
||||
@snippet template_extension/old/extension.cpp extension:getOpSets
|
||||
|
||||
This method returns a map of opsets that exist in the extension library.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ Inference Engine build infrastructure provides the Inference Engine Package for
|
|||
|
||||
To build an extension library, use the following CMake script:
|
||||
|
||||
@snippet template_extension/CMakeLists.txt cmake:extension
|
||||
@snippet template_extension/old/CMakeLists.txt cmake:extension
|
||||
|
||||
This CMake script finds the Inference Engine and nGraph using the `find_package` CMake command.
|
||||
|
||||
To build an extension library, run the commands below:
|
||||
|
||||
```sh
|
||||
$ cd template_extension
|
||||
$ cd template_extension/old
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DOpenVINO_DIR=[OpenVINO_DIR] ../
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ The primary means of the performance of the CPU codepath in the Inference Engine
|
|||
All custom kernels for the CPU plugin should be inherited from the InferenceEngine::ILayerExecImpl interface.
|
||||
Based on that, declaration of a kernel implementation class can look as follows:
|
||||
|
||||
@snippet template_extension/cpu_kernel.hpp cpu_implementation:header
|
||||
@snippet template_extension/old/cpu_kernel.hpp cpu_implementation:header
|
||||
|
||||
### Class Fields
|
||||
|
||||
|
|
@ -22,25 +22,25 @@ The provided implementation has several fields:
|
|||
|
||||
An implementation constructor checks parameters of an nGraph operation, stores required attributes, and stores an error message in the case of an error.
|
||||
|
||||
@snippet template_extension/cpu_kernel.cpp cpu_implementation:ctor
|
||||
@snippet template_extension/old/cpu_kernel.cpp cpu_implementation:ctor
|
||||
|
||||
### `getSupportedConfigurations`
|
||||
|
||||
InferenceEngine::ILayerExecImpl::getSupportedConfigurations method returns all supported configuration formats (input/output tensor layouts) for your implementation. To specify formats of data, use InferenceEngine::TensorDesc. Refer to the [Memory Primitives](../Memory_primitives.md) section for instructions.
|
||||
|
||||
@snippet template_extension/cpu_kernel.cpp cpu_implementation:getSupportedConfigurations
|
||||
@snippet template_extension/old/cpu_kernel.cpp cpu_implementation:getSupportedConfigurations
|
||||
|
||||
### `init`
|
||||
|
||||
InferenceEngine::ILayerExecImpl::init method gets a runtime-selected configuration from a vector that is populated from the `getSupportedConfigurations` method and checks the parameters:
|
||||
|
||||
@snippet template_extension/cpu_kernel.cpp cpu_implementation:init
|
||||
@snippet template_extension/old/cpu_kernel.cpp cpu_implementation:init
|
||||
|
||||
### `execute`
|
||||
|
||||
InferenceEngine::ILayerExecImpl::execute method accepts and processes the actual tenors as input/output blobs:
|
||||
|
||||
@snippet template_extension/cpu_kernel.cpp cpu_implementation:execute
|
||||
@snippet template_extension/old/cpu_kernel.cpp cpu_implementation:execute
|
||||
|
||||
## Register Implementation in `Extension` Class
|
||||
|
||||
|
|
@ -52,13 +52,13 @@ To register custom kernel implementation in the [Extension](Extension.md) class,
|
|||
|
||||
InferenceEngine::IExtension::getImplTypes returns a vector of implementation types for an operation.
|
||||
|
||||
@snippet template_extension/extension.cpp extension:getImplTypes
|
||||
@snippet template_extension/old/extension.cpp extension:getImplTypes
|
||||
|
||||
### <a name="getImplementation"><code>getImplementation</code></a>
|
||||
|
||||
InferenceEngine::IExtension::getImplementation returns the kernel implementation with a specified type for an operation.
|
||||
|
||||
@snippet template_extension/extension.cpp extension:getImplementation
|
||||
@snippet template_extension/old/extension.cpp extension:getImplementation
|
||||
|
||||
|
||||
## Load Extension with Executable Kernels to Plugin
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ If you do not need an operator anymore, unregister it by calling `unregister_ope
|
|||
|
||||
The same principles apply when registering a custom ONNX operator based on custom nGraph operations.
|
||||
This example shows how to register a custom ONNX operator based on `Operation` presented in [this tutorial](AddingNGraphOps.md), which is used in [TemplateExtension](Extension.md).
|
||||
@snippet template_extension/extension.cpp extension:ctor
|
||||
@snippet template_extension/old/extension.cpp extension:ctor
|
||||
|
||||
Here, the `register_operator` function is called in the constructor of Extension. The constructor makes sure that the function is called before InferenceEngine::Core::ReadNetwork, because InferenceEngine::Core::AddExtension must be called before a model with a custom operator is read.
|
||||
|
||||
The example below demonstrates how to unregister an operator from the destructor of Extension:
|
||||
@snippet template_extension/extension.cpp extension:dtor
|
||||
@snippet template_extension/old/extension.cpp extension:dtor
|
||||
|
||||
> **REQUIRED**: It is mandatory to unregister a custom ONNX operator if it is defined in a dynamic shared library.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ used as an example in this document and `FFT` used as a more complex example fro
|
|||
|
||||
Based on that, the declaration of an extension class can look as follows:
|
||||
|
||||
@snippet template_extension/extension.hpp extension:header
|
||||
@snippet template_extension/old/extension.hpp extension:header
|
||||
|
||||
The extension library should contain and export the InferenceEngine::CreateExtension method, which creates an `Extension` class:
|
||||
|
||||
@snippet template_extension/extension.cpp extension:CreateExtension
|
||||
@snippet template_extension/old/extension.cpp extension:CreateExtension
|
||||
|
||||
Also, an `Extension` object should implement the following methods:
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ Also, an `Extension` object should implement the following methods:
|
|||
|
||||
* InferenceEngine::IExtension::GetVersion returns information about the version of the library.
|
||||
|
||||
@snippet template_extension/extension.cpp extension:GetVersion
|
||||
@snippet template_extension/old/extension.cpp extension:GetVersion
|
||||
|
||||
Implement the InferenceEngine::IExtension::getOpSets method if the extension contains custom layers.
|
||||
Read [Custom nGraph Operation](AddingNGraphOps.md) for more information.
|
||||
|
|
|
|||
|
|
@ -2,36 +2,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# [cmake:extension]
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(TARGET_NAME "template_extension")
|
||||
|
||||
find_package(OpenVINO REQUIRED COMPONENTS Runtime OPTIONAL_COMPONENTS ONNX)
|
||||
find_package(OpenCV QUIET COMPONENTS core)
|
||||
|
||||
set(SRC cpu_kernel.cpp extension.cpp op.cpp)
|
||||
|
||||
if(OpenCV_FOUND)
|
||||
set(SRC ${SRC} fft_kernel.cpp fft_op.cpp)
|
||||
endif()
|
||||
|
||||
add_library(${TARGET_NAME} MODULE ${SRC})
|
||||
|
||||
if(OpenCV_FOUND)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE OPENCV_IMPORT_ENABLED)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE opencv_core)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE IMPLEMENT_INFERENCE_EXTENSION_API)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE openvino::core openvino::runtime)
|
||||
|
||||
if(OpenVINO_Frontend_ONNX_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE openvino::frontend::onnx)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE OPENVINO_ONNX_FRONTEND_ENABLED)
|
||||
endif()
|
||||
# [cmake:extension]
|
||||
|
||||
# Enable code style check
|
||||
file(GLOB_RECURSE template_extension_src "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")
|
||||
add_clang_format_target(${TARGET_NAME}_clang FOR_SOURCES ${template_extension_src})
|
||||
add_subdirectory(old)
|
||||
add_subdirectory(new)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# [cmake:extension]
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(TARGET_NAME "template_ov_extension")
|
||||
|
||||
find_package(OpenVINO)
|
||||
|
||||
set(SRC identity.cpp ov_extension.cpp)
|
||||
|
||||
add_library(${TARGET_NAME} MODULE ${SRC})
|
||||
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE IMPLEMENT_OPENVINO_EXTENSION_API)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE openvino::core)
|
||||
# [cmake:extension]
|
||||
|
||||
# Enable code style check
|
||||
file(GLOB_RECURSE template_extension_src "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")
|
||||
add_clang_format_target(${TARGET_NAME}_clang FOR_SOURCES ${template_extension_src})
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "identity.hpp"
|
||||
|
||||
using namespace TemplateExtension;
|
||||
|
||||
//! [op:ctor]
|
||||
Identity::Identity(const ov::Output<ov::Node>& arg) : Op({arg}) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
//! [op:ctor]
|
||||
|
||||
//! [op:validate]
|
||||
void Identity::validate_and_infer_types() {
|
||||
// Operation doesn't change shapes end element type
|
||||
set_output_type(0, get_input_element_type(0), get_input_partial_shape(0));
|
||||
}
|
||||
//! [op:validate]
|
||||
|
||||
//! [op:copy]
|
||||
std::shared_ptr<ov::Node> Identity::clone_with_new_inputs(const ov::OutputVector& new_args) const {
|
||||
OPENVINO_ASSERT(new_args.size() != 1, "Incorrect number of new arguments");
|
||||
|
||||
return std::make_shared<Identity>(new_args.at(0));
|
||||
}
|
||||
//! [op:copy]
|
||||
|
||||
//! [op:visit_attributes]
|
||||
bool Identity::visit_attributes(ov::AttributeVisitor& visitor) {
|
||||
return true;
|
||||
}
|
||||
//! [op:visit_attributes]
|
||||
|
||||
//! [op:evaluate]
|
||||
bool Identity::evaluate(ov::runtime::TensorVector& outputs, const ov::runtime::TensorVector& inputs) const {
|
||||
auto in = inputs[0];
|
||||
auto out = outputs[0];
|
||||
out.set_shape(in.get_shape());
|
||||
memcpy(out.data(), in.data(), in.get_size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Identity::has_evaluate() const {
|
||||
return true;
|
||||
}
|
||||
//! [op:evaluate]
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvino/op/op.hpp>
|
||||
|
||||
//! [op:header]
|
||||
namespace TemplateExtension {
|
||||
|
||||
class Identity : public ov::op::Op {
|
||||
public:
|
||||
OPENVINO_OP("Identity");
|
||||
|
||||
Identity() = default;
|
||||
Identity(const ov::Output<ov::Node>& arg);
|
||||
void validate_and_infer_types() override;
|
||||
std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector& new_args) const override;
|
||||
bool visit_attributes(ov::AttributeVisitor& visitor) override;
|
||||
|
||||
bool evaluate(ov::runtime::TensorVector& outputs, const ov::runtime::TensorVector& inputs) const override;
|
||||
bool has_evaluate() const override;
|
||||
};
|
||||
//! [op:header]
|
||||
|
||||
} // namespace TemplateExtension
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <openvino/core/extension.hpp>
|
||||
#include <openvino/core/op_extension.hpp>
|
||||
|
||||
#include "identity.hpp"
|
||||
|
||||
OPENVINO_CREATE_EXTENSIONS(
|
||||
std::vector<ov::Extension::Ptr>({std::make_shared<ov::OpExtension<TemplateExtension::Identity>>()}));
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright (C) 2018-2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# [cmake:extension]
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(TARGET_NAME "template_extension")
|
||||
|
||||
find_package(OpenVINO REQUIRED COMPONENTS Runtime OPTIONAL_COMPONENTS ONNX)
|
||||
find_package(OpenCV QUIET COMPONENTS core)
|
||||
|
||||
set(SRC cpu_kernel.cpp extension.cpp op.cpp)
|
||||
|
||||
if(OpenCV_FOUND)
|
||||
set(SRC ${SRC} fft_kernel.cpp fft_op.cpp)
|
||||
endif()
|
||||
|
||||
add_library(${TARGET_NAME} MODULE ${SRC})
|
||||
|
||||
if(OpenCV_FOUND)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE OPENCV_IMPORT_ENABLED)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE opencv_core)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE IMPLEMENT_INFERENCE_EXTENSION_API)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE openvino::core openvino::runtime)
|
||||
|
||||
if(OpenVINO_Frontend_ONNX_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE openvino::frontend::onnx)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE OPENVINO_ONNX_FRONTEND_ENABLED)
|
||||
endif()
|
||||
# [cmake:extension]
|
||||
|
||||
# Enable code style check
|
||||
file(GLOB_RECURSE template_extension_src "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")
|
||||
add_clang_format_target(${TARGET_NAME}_clang FOR_SOURCES ${template_extension_src})
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "ie_plugin_config.hpp"
|
||||
#include "ngraph/partial_shape.hpp"
|
||||
#include "openvino/op/util/framework_node.hpp"
|
||||
|
||||
const std::string EXPORTED_NETWORK_NAME = "undefined";
|
||||
std::map<std::string, InferenceEngine::Precision> precision_map = {{"FP32", InferenceEngine::Precision::FP32},
|
||||
|
|
@ -197,7 +198,11 @@ public:
|
|||
}
|
||||
|
||||
std::map<std::string, ngraph::OpSet> getOpSets() override {
|
||||
return {{"framework_node_ext", ngraph::OpSet()}};
|
||||
std::map<std::string, ngraph::OpSet> opsets;
|
||||
ngraph::OpSet opset;
|
||||
opset.insert<ov::op::util::FrameworkNode>();
|
||||
opsets["util"] = opset;
|
||||
return opsets;
|
||||
}
|
||||
|
||||
void Unload() noexcept override {}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ file (GLOB LIBRARY_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/cpp_interfaces/interface/*.cpp
|
||||
)
|
||||
|
||||
# Add include path to so_extension.hpp
|
||||
set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/ie_core.cpp
|
||||
APPEND PROPERTY INCLUDE_DIRECTORIES "${OpenVINO_SOURCE_DIR}/ngraph/core/src/")
|
||||
|
||||
# TODO: WA for OneHot pass usage in reshape
|
||||
set(LEGACY_SRC_ROOT "${IE_MAIN_SOURCE_DIR}/src/legacy_api/src")
|
||||
set(LEGACY_LIBRARY_SHARED_SRCS
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@
|
|||
#include <vector>
|
||||
|
||||
#include "ie_plugin_config.hpp"
|
||||
#include "openvino/core/extension.hpp"
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
#include "openvino/core/version.hpp"
|
||||
#include "openvino/op/op.hpp"
|
||||
#include "openvino/runtime/common.hpp"
|
||||
#include "openvino/runtime/executable_network.hpp"
|
||||
#include "openvino/runtime/remote_context.hpp"
|
||||
|
|
@ -147,9 +150,79 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Registers extension
|
||||
* @deprecated This method is deprecated. Please use other add_extension methods
|
||||
* @param extension Pointer to already loaded extension
|
||||
*/
|
||||
OPENVINO_DEPRECATED("Please use add_extension(ov::Extension) or add_extension(path_to_library) instead.")
|
||||
void add_extension(const std::shared_ptr<ie::IExtension>& extension);
|
||||
/**
|
||||
* @brief Registers extension
|
||||
* @param library_path path to library with ov::Extension
|
||||
*/
|
||||
void add_extension(const std::string& library_path);
|
||||
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
|
||||
/**
|
||||
* @brief Registers extension
|
||||
* @param library_path path to library with ov::Extension
|
||||
*/
|
||||
void add_extension(const std::wstring& library_path);
|
||||
#endif
|
||||
/**
|
||||
* @brief Registers extension
|
||||
* @param extension Pointer to base extension
|
||||
*/
|
||||
void add_extension(const std::shared_ptr<ov::Extension>& extension);
|
||||
/**
|
||||
* @brief Registers extensions
|
||||
* @param extensions Vector of loaded base extensions
|
||||
*/
|
||||
void add_extension(const std::vector<std::shared_ptr<ov::Extension>>& extensions);
|
||||
|
||||
/**
|
||||
* @brief Registers extension
|
||||
* @param extension Extension class which is inherited from ov::Extension class
|
||||
*/
|
||||
template <class T, typename std::enable_if<std::is_base_of<ov::Extension, T>::value, bool>::type = true>
|
||||
void add_extension(const T& extension) {
|
||||
std::shared_ptr<ov::Extension> ext = std::make_shared<T>(extension);
|
||||
add_extension(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers extensions
|
||||
* @param extension Extension class which is inherited from ov::Extension class
|
||||
* @param args list of extensions
|
||||
*/
|
||||
template <class T,
|
||||
class... Targs,
|
||||
typename std::enable_if<std::is_base_of<ov::Extension, T>::value, bool>::type = true>
|
||||
void add_extension(const T& extension, Targs... args) {
|
||||
std::shared_ptr<ov::Extension> ext = std::make_shared<T>(extension);
|
||||
add_extension(ext);
|
||||
add_extension(args...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers custom operation
|
||||
*/
|
||||
template <class T, typename std::enable_if<std::is_base_of<ov::op::Op, T>::value, bool>::type = true>
|
||||
void add_extension() {
|
||||
std::shared_ptr<ov::Extension> ext = std::make_shared<ov::OpExtension<T>>();
|
||||
add_extension(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers custom operations
|
||||
*/
|
||||
template <class T,
|
||||
class... Targs,
|
||||
typename std::enable_if<std::is_base_of<ov::op::Op, T>::value && sizeof...(Targs), bool>::type = true>
|
||||
void add_extension() {
|
||||
std::shared_ptr<ov::Extension> ext = std::make_shared<ov::OpExtension<T>>();
|
||||
add_extension(ext);
|
||||
if (sizeof...(Targs) > 0)
|
||||
add_extension<Targs...>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an executable network from a previously exported network
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "openvino/runtime/executable_network.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "openvino/util/shared_object.hpp"
|
||||
#include "so_extension.hpp"
|
||||
#include "xml_parse_utils.h"
|
||||
|
||||
#ifdef OPENVINO_STATIC_LIBRARY
|
||||
|
|
@ -195,6 +196,7 @@ class CoreImpl : public ie::ICore, public std::enable_shared_from_this<ie::ICore
|
|||
mutable std::unordered_set<std::string> opsetNames;
|
||||
// TODO: make extensions to be optional with conditional compilation
|
||||
mutable std::vector<ie::IExtensionPtr> extensions;
|
||||
std::vector<ov::Extension::Ptr> ov_extensions;
|
||||
|
||||
std::map<std::string, PluginDescriptor> pluginRegistry;
|
||||
mutable std::mutex pluginsMutex; // to lock parallel access to pluginRegistry and plugins
|
||||
|
|
@ -483,12 +485,12 @@ public:
|
|||
|
||||
ie::CNNNetwork ReadNetwork(const std::string& modelPath, const std::string& binPath) const override {
|
||||
OV_ITT_SCOPE(FIRST_INFERENCE, ov::itt::domains::IE_RT, "CoreImpl::ReadNetwork from file");
|
||||
return InferenceEngine::details::ReadNetwork(modelPath, binPath, extensions, newAPI);
|
||||
return InferenceEngine::details::ReadNetwork(modelPath, binPath, extensions, ov_extensions, newAPI);
|
||||
}
|
||||
|
||||
ie::CNNNetwork ReadNetwork(const std::string& model, const ie::Blob::CPtr& weights) const override {
|
||||
OV_ITT_SCOPE(FIRST_INFERENCE, ov::itt::domains::IE_RT, "CoreImpl::ReadNetwork from memory");
|
||||
return InferenceEngine::details::ReadNetwork(model, weights, extensions, newAPI);
|
||||
return InferenceEngine::details::ReadNetwork(model, weights, extensions, ov_extensions, newAPI);
|
||||
}
|
||||
|
||||
bool isNewAPI() const override {
|
||||
|
|
@ -986,6 +988,13 @@ public:
|
|||
AddExtensionUnsafe(extension);
|
||||
}
|
||||
|
||||
void AddOVExtensions(const std::vector<ov::Extension::Ptr>& extensions) {
|
||||
std::lock_guard<std::mutex> lock(pluginsMutex);
|
||||
for (const auto& ext : extensions) {
|
||||
ov_extensions.emplace_back(ext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides a list of extensions
|
||||
* @return A list of registered extensions
|
||||
|
|
@ -994,6 +1003,10 @@ public:
|
|||
return extensions;
|
||||
}
|
||||
|
||||
const std::vector<ov::Extension::Ptr>& GetOVExtensions() const {
|
||||
return ov_extensions;
|
||||
}
|
||||
|
||||
std::map<std::string, ie::Version> GetVersions(const std::string& deviceName) const {
|
||||
std::map<std::string, ie::Version> versions;
|
||||
std::vector<std::string> deviceNames;
|
||||
|
|
@ -1480,6 +1493,22 @@ void Core::add_extension(const ie::IExtensionPtr& extension) {
|
|||
OV_CORE_CALL_STATEMENT(_impl->AddExtension(extension););
|
||||
}
|
||||
|
||||
void Core::add_extension(const std::string& library_path) {
|
||||
add_extension(ov::detail::load_extensions(library_path));
|
||||
}
|
||||
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
|
||||
void Core::add_extension(const std::wstring& library_path) {
|
||||
add_extension(ov::detail::load_extensions(library_path));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Core::add_extension(const std::shared_ptr<ov::Extension>& extension) {
|
||||
add_extension(std::vector<std::shared_ptr<ov::Extension>>{extension});
|
||||
}
|
||||
void Core::add_extension(const std::vector<std::shared_ptr<ov::Extension>>& extensions) {
|
||||
OV_CORE_CALL_STATEMENT({ _impl->AddOVExtensions(extensions); });
|
||||
}
|
||||
|
||||
ExecutableNetwork Core::import_model(std::istream& modelStream,
|
||||
const std::string& deviceName,
|
||||
const ConfigMap& config) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,42 @@
|
|||
#include "transformations/rt_info/old_api_map_attribute.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
|
||||
/*
|
||||
* @brief Wrapper for old IE extensions to new API
|
||||
*/
|
||||
class ExtensionWrapper : public ov::BaseOpExtension {
|
||||
public:
|
||||
ExtensionWrapper(const InferenceEngine::IExtensionPtr& ext, const std::string& opset, const std::string& name)
|
||||
: m_ext(ext),
|
||||
m_opset_name(opset),
|
||||
m_type(name),
|
||||
m_ext_type(m_type.c_str(), 0, m_opset_name.c_str()) {}
|
||||
|
||||
const ov::DiscreteTypeInfo& get_type_info() const override {
|
||||
return m_ext_type;
|
||||
}
|
||||
|
||||
ngraph::OutputVector create(const ngraph::OutputVector& inputs, ngraph::AttributeVisitor& visitor) const override {
|
||||
std::shared_ptr<ngraph::Node> node(m_ext->getOpSets().at(m_opset_name).create_insensitive(m_ext_type.name));
|
||||
|
||||
node->set_arguments(inputs);
|
||||
if (node->visit_attributes(visitor)) {
|
||||
node->constructor_validate_and_infer_types();
|
||||
}
|
||||
return node->outputs();
|
||||
}
|
||||
|
||||
private:
|
||||
InferenceEngine::IExtensionPtr m_ext;
|
||||
std::string m_opset_name;
|
||||
std::string m_type;
|
||||
ov::DiscreteTypeInfo m_ext_type;
|
||||
};
|
||||
|
||||
} // namespace ov
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
#ifdef ENABLE_IR_V7_READER
|
||||
|
|
@ -391,14 +427,13 @@ ngraph::frontend::FrontEndManager& get_frontend_manager() {
|
|||
return manager;
|
||||
}
|
||||
|
||||
ov::Extensions get_extensions_map(const std::vector<InferenceEngine::IExtensionPtr>& exts) {
|
||||
ov::Extensions extensions;
|
||||
std::vector<ov::Extension::Ptr> wrap_old_extensions(const std::vector<InferenceEngine::IExtensionPtr>& exts) {
|
||||
std::vector<ov::Extension::Ptr> extensions;
|
||||
for (const auto& ext : exts) {
|
||||
for (const auto& item : ext->getOpSets()) {
|
||||
if (extensions.count(item.first)) {
|
||||
IE_THROW() << "Extension with " << item.first << " name already exists";
|
||||
for (const auto& type_info : item.second.get_types_info()) {
|
||||
extensions.emplace_back(std::make_shared<ov::ExtensionWrapper>(ext, item.first, type_info.name));
|
||||
}
|
||||
extensions[item.first] = item.second;
|
||||
}
|
||||
}
|
||||
return extensions;
|
||||
|
|
@ -409,6 +444,7 @@ ov::Extensions get_extensions_map(const std::vector<InferenceEngine::IExtensionP
|
|||
CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
const std::string& binPath,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
const std::vector<ov::Extension::Ptr>& ov_exts,
|
||||
bool newAPI) {
|
||||
#ifdef ENABLE_IR_V7_READER
|
||||
// IR v7 obsolete code
|
||||
|
|
@ -439,9 +475,6 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
|||
ngraph::frontend::InputModel::Ptr inputModel;
|
||||
|
||||
ov::VariantVector params{ov::make_variant(model_path)};
|
||||
if (!exts.empty()) {
|
||||
params.emplace_back(ov::make_variant(get_extensions_map(exts)));
|
||||
}
|
||||
|
||||
if (!binPath.empty()) {
|
||||
#if defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32)
|
||||
|
|
@ -453,8 +486,12 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
|||
}
|
||||
|
||||
FE = manager.load_by_model(params);
|
||||
if (FE)
|
||||
if (FE) {
|
||||
FE->add_extension(ov_exts);
|
||||
if (!exts.empty())
|
||||
FE->add_extension(wrap_old_extensions(exts));
|
||||
inputModel = FE->load(params);
|
||||
}
|
||||
|
||||
if (inputModel) {
|
||||
auto ngFunc = FE->convert(inputModel);
|
||||
|
|
@ -470,6 +507,7 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
|||
CNNNetwork details::ReadNetwork(const std::string& model,
|
||||
const Blob::CPtr& weights,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
const std::vector<ov::Extension::Ptr>& ov_exts,
|
||||
bool newAPI) {
|
||||
std::istringstream modelStringStream(model);
|
||||
std::istream& modelStream = modelStringStream;
|
||||
|
|
@ -501,17 +539,18 @@ CNNNetwork details::ReadNetwork(const std::string& model,
|
|||
ov::VariantVector params{ov::make_variant(&modelStream)};
|
||||
if (weights) {
|
||||
char* data = weights->cbuffer().as<char*>();
|
||||
ov::Weights weights_buffer =
|
||||
std::shared_ptr<ngraph::runtime::AlignedBuffer> weights_buffer =
|
||||
std::make_shared<ngraph::runtime::SharedBuffer<Blob::CPtr>>(data, weights->byteSize(), weights);
|
||||
params.emplace_back(ov::make_variant(weights_buffer));
|
||||
}
|
||||
if (!exts.empty()) {
|
||||
params.emplace_back(ov::make_variant(get_extensions_map(exts)));
|
||||
}
|
||||
|
||||
FE = manager.load_by_model(params);
|
||||
if (FE)
|
||||
if (FE) {
|
||||
FE->add_extension(ov_exts);
|
||||
if (!exts.empty())
|
||||
FE->add_extension(wrap_old_extensions(exts));
|
||||
inputModel = FE->load(params);
|
||||
}
|
||||
if (inputModel) {
|
||||
auto ngFunc = FE->convert(inputModel);
|
||||
return convert_to_cnnnetwork(ngFunc, exts, newAPI);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "cpp/ie_cnn_network.h"
|
||||
#include "ie_blob.h"
|
||||
#include "ie_iextension.h"
|
||||
#include "openvino/core/extension.hpp"
|
||||
|
||||
namespace InferenceEngine {
|
||||
namespace details {
|
||||
|
|
@ -19,27 +20,28 @@ namespace details {
|
|||
* @param binPath path to bin file, if path is empty, will try to read bin file with the same name as xml and
|
||||
* if bin file with the same name was not found, will load IR without weights.
|
||||
* @param exts vector with extensions
|
||||
* @param ov_exts vector with OpenVINO extensions
|
||||
* @param newAPI Whether this function is called from OpenVINO 2.0 API
|
||||
* @return CNNNetwork
|
||||
*/
|
||||
CNNNetwork ReadNetwork(const std::string& modelPath,
|
||||
const std::string& binPath,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
const std::vector<ov::Extension::Ptr>& ov_exts,
|
||||
bool newAPI);
|
||||
/**
|
||||
* @brief Reads IR xml and bin (with the same name) files
|
||||
* @param model string with IR
|
||||
* @param weights shared pointer to constant blob with weights
|
||||
* @param exts vector with extensions
|
||||
* @note Reading ONNX models doesn't support loading weights from data blobs.
|
||||
If you are using an ONNX model with external data files, please use the
|
||||
ReadNetwork function overload which takes a filesystem path to the model.
|
||||
* @param ov_exts vector with OpenVINO extensions
|
||||
* @param newAPI Whether this function is called from OpenVINO 2.0 API
|
||||
* @return CNNNetwork
|
||||
*/
|
||||
CNNNetwork ReadNetwork(const std::string& model,
|
||||
const Blob::CPtr& weights,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
const std::vector<ov::Extension::Ptr>& ov_exts,
|
||||
bool newAPI);
|
||||
|
||||
} // namespace details
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ set(LINK_LIBRARIES
|
|||
set(DEPENDENCIES
|
||||
mock_engine
|
||||
template_extension
|
||||
template_ov_extension
|
||||
lptNgraphFunctions
|
||||
sharedTestClasses
|
||||
test_model_zoo
|
||||
|
|
|
|||
|
|
@ -124,7 +124,13 @@ public:
|
|||
}
|
||||
|
||||
std::map<std::string, ngraph::OpSet> getOpSets() override {
|
||||
return {{"framework_node_ext", ngraph::OpSet()}};
|
||||
static std::map<std::string, ngraph::OpSet> opsets;
|
||||
if (opsets.empty()) {
|
||||
ngraph::OpSet opset;
|
||||
opset.insert<ov::op::util::FrameworkNode>();
|
||||
opsets["util"] = opset;
|
||||
}
|
||||
return opsets;
|
||||
}
|
||||
|
||||
void Unload() noexcept override {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,334 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "common_test_utils/test_common.hpp"
|
||||
#include "file_utils.h"
|
||||
#include "ie_iextension.h"
|
||||
#include "ngraph/op/op.hpp"
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
#include "openvino/runtime/core.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace InferenceEngine;
|
||||
using namespace CommonTestUtils;
|
||||
|
||||
class OVExtensionTests : public TestsCommon {
|
||||
public:
|
||||
ov::runtime::Core core;
|
||||
|
||||
void test() {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Activation" version="10">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset1">
|
||||
<data shape="1,3,22,22" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32" names="in_data">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="activation" id="1" type="Identity" version="extension">
|
||||
<input>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32" names="out_data">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="1"/>
|
||||
<edge from-layer="1" from-port="2" to-layer="2" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
ov::runtime::Tensor weights;
|
||||
ov::PartialShape refBeforeReshape{1, 3, 22, 22};
|
||||
ov::PartialShape refAfterReshape{8, 9, 33, 66};
|
||||
|
||||
auto network = core.read_model(model, weights);
|
||||
std::map<std::string, ov::PartialShape> newShapes;
|
||||
newShapes["in_data"] = refAfterReshape;
|
||||
|
||||
EXPECT_EQ(refBeforeReshape, network->output().get_partial_shape());
|
||||
EXPECT_NO_THROW(network->reshape(newShapes));
|
||||
EXPECT_EQ(refAfterReshape, network->output().get_partial_shape());
|
||||
}
|
||||
|
||||
void test_two_op() {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Activation" version="10">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset1">
|
||||
<data shape="1,3,22,22" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32" names="in_data">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="activation" id="1" type="Identity" version="extension">
|
||||
<input>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32" names="out_data">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="activation2" id="2" type="CustomReLU" version="extension">
|
||||
<input>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32" names="out_relu_data">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="3" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="1"/>
|
||||
<edge from-layer="1" from-port="2" to-layer="2" to-port="1"/>
|
||||
<edge from-layer="2" from-port="2" to-layer="3" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
ov::runtime::Tensor weights;
|
||||
ov::PartialShape refBeforeReshape{1, 3, 22, 22};
|
||||
ov::PartialShape refAfterReshape{8, 9, 33, 66};
|
||||
|
||||
auto network = core.read_model(model, weights);
|
||||
std::map<std::string, ov::PartialShape> newShapes;
|
||||
newShapes["in_data"] = refAfterReshape;
|
||||
|
||||
EXPECT_EQ(refBeforeReshape, network->output().get_partial_shape());
|
||||
EXPECT_NO_THROW(network->reshape(newShapes));
|
||||
EXPECT_EQ(refAfterReshape, network->output().get_partial_shape());
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
std::string getOVExtensionPath() {
|
||||
return FileUtils::makePluginLibraryName<char>({}, std::string("template_ov_extension") + IE_BUILD_POSTFIX);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class CustomOldIdentity : public ngraph::op::Op {
|
||||
public:
|
||||
static constexpr ngraph::NodeTypeInfo type_info{"Identity", 0};
|
||||
const ngraph::NodeTypeInfo& get_type_info() const override {
|
||||
return type_info;
|
||||
}
|
||||
|
||||
CustomOldIdentity() = default;
|
||||
CustomOldIdentity(const ngraph::Output<ngraph::Node>& arg) : Op({arg}) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void validate_and_infer_types() override {
|
||||
set_output_type(0, get_input_element_type(0), get_input_partial_shape(0));
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Node> clone_with_new_inputs(const ngraph::OutputVector& new_args) const override {
|
||||
if (new_args.size() != 1) {
|
||||
throw ngraph::ngraph_error("Incorrect number of new arguments");
|
||||
}
|
||||
|
||||
return std::make_shared<CustomOldIdentity>(new_args.at(0));
|
||||
}
|
||||
|
||||
bool visit_attributes(ngraph::AttributeVisitor& visitor) override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr ngraph::NodeTypeInfo CustomOldIdentity::type_info;
|
||||
|
||||
class TestTileOldExtension : public InferenceEngine::IExtension {
|
||||
public:
|
||||
void GetVersion(const InferenceEngine::Version*& versionInfo) const noexcept override {}
|
||||
|
||||
void Unload() noexcept override {}
|
||||
|
||||
std::map<std::string, ngraph::OpSet> getOpSets() override {
|
||||
static std::map<std::string, ngraph::OpSet> opsets;
|
||||
if (opsets.empty()) {
|
||||
ngraph::OpSet opset;
|
||||
opset.insert<CustomOldIdentity>();
|
||||
opsets["extension"] = opset;
|
||||
}
|
||||
return opsets;
|
||||
}
|
||||
};
|
||||
|
||||
class CustomNewIdentity : public ov::op::Op {
|
||||
public:
|
||||
OPENVINO_OP("Identity")
|
||||
|
||||
CustomNewIdentity() = default;
|
||||
CustomNewIdentity(const ov::Output<ov::Node>& arg) : Op({arg}) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void validate_and_infer_types() override {
|
||||
set_output_type(0, get_input_element_type(0), get_input_partial_shape(0));
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector& new_args) const override {
|
||||
OPENVINO_ASSERT(new_args.size() != 1, "Incorrect number of new arguments");
|
||||
|
||||
return std::make_shared<CustomNewIdentity>(new_args.at(0));
|
||||
}
|
||||
|
||||
bool visit_attributes(ov::AttributeVisitor& visitor) override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CustomReLU : public ov::op::Op {
|
||||
public:
|
||||
OPENVINO_OP("CustomReLU")
|
||||
|
||||
CustomReLU() = default;
|
||||
CustomReLU(const ov::Output<ov::Node>& arg) : Op({arg}) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void validate_and_infer_types() override {
|
||||
set_output_type(0, get_input_element_type(0), get_input_partial_shape(0));
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector& new_args) const override {
|
||||
OPENVINO_ASSERT(new_args.size() != 1, "Incorrect number of new arguments");
|
||||
|
||||
return std::make_shared<CustomReLU>(new_args.at(0));
|
||||
}
|
||||
|
||||
bool visit_attributes(ov::AttributeVisitor& visitor) override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithOldExtension) {
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
core.add_extension(std::make_shared<TestTileOldExtension>());
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
test();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithNewExtensionsLib) {
|
||||
core.add_extension(getOVExtensionPath());
|
||||
test();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithNewExtensionPtr) {
|
||||
core.add_extension(std::make_shared<ov::OpExtension<CustomNewIdentity>>());
|
||||
test();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithNewExtension) {
|
||||
core.add_extension(ov::OpExtension<CustomNewIdentity>());
|
||||
test();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithNewOp) {
|
||||
core.add_extension<CustomNewIdentity>();
|
||||
test();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, IncorrectReshapeIRWithNewExtensionPtr) {
|
||||
core.add_extension(std::make_shared<ov::OpExtension<CustomNewIdentity>>());
|
||||
EXPECT_ANY_THROW(test_two_op());
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, IncorrectReshapeIRWithNewExtension) {
|
||||
core.add_extension(ov::OpExtension<CustomNewIdentity>());
|
||||
EXPECT_ANY_THROW(test_two_op());
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, IncorrectReshapeIRWithNewOp) {
|
||||
core.add_extension<CustomNewIdentity>();
|
||||
EXPECT_ANY_THROW(test_two_op());
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithSeveralNewExtensionPtrs) {
|
||||
core.add_extension(
|
||||
{std::make_shared<ov::OpExtension<CustomNewIdentity>>(), std::make_shared<ov::OpExtension<CustomReLU>>()});
|
||||
test_two_op();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithSeveralNewExtensions) {
|
||||
core.add_extension(ov::OpExtension<CustomNewIdentity>(), ov::OpExtension<CustomReLU>());
|
||||
test_two_op();
|
||||
}
|
||||
|
||||
TEST_F(OVExtensionTests, ReshapeIRWithSeveralNewOps) {
|
||||
core.add_extension<CustomNewIdentity, CustomReLU>();
|
||||
test_two_op();
|
||||
}
|
||||
|
|
@ -11,17 +11,17 @@
|
|||
using namespace ::testing;
|
||||
using namespace std;
|
||||
|
||||
class SharedObjectOVTests: public ::testing::Test {
|
||||
class SharedObjectOVTests : public ::testing::Test {
|
||||
protected:
|
||||
std::string get_mock_engine_name() {
|
||||
return FileUtils::makePluginLibraryName<char>(InferenceEngine::getIELibraryPath(),
|
||||
std::string("mock_engine") + IE_BUILD_POSTFIX);
|
||||
std::string("mock_engine") + IE_BUILD_POSTFIX);
|
||||
}
|
||||
|
||||
void loadDll(const string &libraryName) {
|
||||
shared_object = ov::util::load_shared_object(libraryName.c_str());
|
||||
}
|
||||
std::shared_ptr<void> shared_object;
|
||||
std::shared_ptr<void> shared_object;
|
||||
|
||||
using CreateF = void(std::shared_ptr<InferenceEngine::IInferencePlugin>&);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "openvino/core/core_visibility.hpp"
|
||||
#include "openvino/core/type.hpp"
|
||||
|
||||
// Use extern "C" in order to avoid issues with mangling
|
||||
#if defined(_WIN32) && defined(IMPLEMENT_OPENVINO_EXTENSION_API)
|
||||
# define OPENVINO_EXTENSION_C_API OPENVINO_EXTERN_C OPENVINO_CORE_EXPORTS
|
||||
# define OPENVINO_EXTENSION_API OPENVINO_CORE_EXPORTS
|
||||
#else
|
||||
# define OPENVINO_EXTENSION_C_API OPENVINO_EXTERN_C OPENVINO_API
|
||||
# define OPENVINO_EXTENSION_API OPENVINO_API
|
||||
#endif
|
||||
|
||||
namespace ov {
|
||||
|
||||
class Extension;
|
||||
|
||||
/**
|
||||
* @brief The class provides the base interface for OpenVINO extensions
|
||||
*/
|
||||
class OPENVINO_API Extension : public std::enable_shared_from_this<Extension> {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Extension>;
|
||||
|
||||
virtual ~Extension();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The entry point for library with OpenVINO extensions
|
||||
*
|
||||
* @param vector of extensions
|
||||
*/
|
||||
OPENVINO_EXTENSION_C_API
|
||||
void create_extensions(std::vector<Extension::Ptr>&);
|
||||
|
||||
} // namespace ov
|
||||
|
||||
/**
|
||||
* @brief Macro generates the entry point for the library
|
||||
*
|
||||
* @param vector of extensions
|
||||
*/
|
||||
#define OPENVINO_CREATE_EXTENSIONS(extensions) \
|
||||
OPENVINO_EXTENSION_C_API \
|
||||
void ::ov::create_extensions(std::vector<::ov::Extension::Ptr>& ext) { \
|
||||
ext = extensions; \
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/attribute_visitor.hpp"
|
||||
#include "openvino/core/extension.hpp"
|
||||
#include "openvino/core/node.hpp"
|
||||
#include "openvino/core/node_vector.hpp"
|
||||
|
||||
namespace ov {
|
||||
|
||||
/**
|
||||
* @brief The base interface for OpenVINO operation extensions
|
||||
*/
|
||||
class OPENVINO_EXTENSION_API BaseOpExtension : public Extension {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<BaseOpExtension>;
|
||||
/**
|
||||
* @brief Returns the type info of operation
|
||||
*
|
||||
* @return ov::DiscreteTypeInfo
|
||||
*/
|
||||
virtual const ov::DiscreteTypeInfo& get_type_info() const = 0;
|
||||
/**
|
||||
* @brief Method creates an OpenVINO operation
|
||||
*
|
||||
* @param inputs vector of input ports
|
||||
* @param visitor attribute visitor which allows to read necessaty arguments
|
||||
*
|
||||
* @return vector of output ports
|
||||
*/
|
||||
virtual ov::OutputVector create(const ov::OutputVector& inputs, ov::AttributeVisitor& visitor) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~BaseOpExtension() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The default implementation of OpenVINO operation extensions
|
||||
*/
|
||||
template <class T>
|
||||
class OpExtension : public BaseOpExtension {
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
OpExtension() {
|
||||
const auto& ext_type = get_type_info();
|
||||
OPENVINO_ASSERT(ext_type.name != nullptr && ext_type.version_id != nullptr,
|
||||
"Extension type should have information about operation set and operation type.");
|
||||
}
|
||||
|
||||
const ov::DiscreteTypeInfo& get_type_info() const override {
|
||||
return T::get_type_info_static();
|
||||
}
|
||||
|
||||
ov::OutputVector create(const ov::OutputVector& inputs, ov::AttributeVisitor& visitor) const override {
|
||||
std::shared_ptr<ov::Node> node = std::make_shared<T>();
|
||||
|
||||
node->set_arguments(inputs);
|
||||
if (node->visit_attributes(visitor)) {
|
||||
node->constructor_validate_and_infer_types();
|
||||
}
|
||||
return node->outputs();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/core/extension.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "openvino/core/except.hpp"
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "openvino/util/shared_object.hpp"
|
||||
|
||||
using namespace ov;
|
||||
|
||||
ov::Extension::~Extension() = default;
|
||||
ov::BaseOpExtension::~BaseOpExtension() = default;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "so_extension.hpp"
|
||||
|
||||
const ov::Extension::Ptr& ov::detail::SOExtension::extension() const {
|
||||
return m_ext;
|
||||
}
|
||||
|
||||
const std::shared_ptr<void> ov::detail::SOExtension::shared_object() const {
|
||||
return m_so;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/extension.hpp"
|
||||
#include "openvino/core/visibility.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "openvino/util/shared_object.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace detail {
|
||||
|
||||
class OPENVINO_API SOExtension : public Extension {
|
||||
public:
|
||||
SOExtension(const std::shared_ptr<void>& so, const Extension::Ptr& ext) : m_so(so), m_ext(ext) {}
|
||||
|
||||
const Extension::Ptr& extension() const;
|
||||
|
||||
const std::shared_ptr<void> shared_object() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> m_so;
|
||||
Extension::Ptr m_ext;
|
||||
};
|
||||
|
||||
inline std::vector<Extension::Ptr> load_extensions(const std::string& path) {
|
||||
auto so = ov::util::load_shared_object(path.c_str());
|
||||
using CreateFunction = void(std::vector<Extension::Ptr>&);
|
||||
std::vector<Extension::Ptr> extensions;
|
||||
reinterpret_cast<CreateFunction*>(ov::util::get_symbol(so, "create_extensions"))(extensions);
|
||||
|
||||
std::vector<Extension::Ptr> so_extensions;
|
||||
so_extensions.reserve(extensions.size());
|
||||
|
||||
for (auto&& ex : extensions) {
|
||||
so_extensions.emplace_back(std::make_shared<SOExtension>(so, ex));
|
||||
}
|
||||
return so_extensions;
|
||||
}
|
||||
|
||||
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
|
||||
inline std::vector<Extension::Ptr> load_extensions(const std::wstring& path) {
|
||||
return load_extensions(ov::util::wstring_to_string(path).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ov
|
||||
|
|
@ -12,6 +12,10 @@ file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
|
|||
file(GLOB_RECURSE LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp)
|
||||
file(GLOB_RECURSE LIBRARY_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
|
||||
|
||||
# Add include path to so_extension.hpp
|
||||
set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/frontend_manager.cpp
|
||||
APPEND PROPERTY INCLUDE_DIRECTORIES "${OpenVINO_SOURCE_DIR}/ngraph/core/src/")
|
||||
|
||||
set(FRONTEND_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
source_group("src" FILES ${LIBRARY_SRC})
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include "input_model.hpp"
|
||||
#include "ngraph/function.hpp"
|
||||
#include "ngraph/variant.hpp"
|
||||
#include "openvino/core/extension.hpp"
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace frontend {
|
||||
|
|
@ -88,6 +90,40 @@ public:
|
|||
/// \return Current frontend name. Empty string if not implemented
|
||||
virtual std::string get_name() const;
|
||||
|
||||
/// \brief Register base extension in the FrontEnd
|
||||
/// \param extension base extension
|
||||
virtual void add_extension(const std::shared_ptr<ov::Extension>& extension);
|
||||
/// \brief Register base extensions in the FrontEnd
|
||||
/// \param extensions vector of extensions
|
||||
void add_extension(const std::vector<std::shared_ptr<ov::Extension>>& extensions);
|
||||
/// \brief Registers extension
|
||||
/// \param library_path path to library with ov::Extension
|
||||
void add_extension(const std::string& library_path);
|
||||
|
||||
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
|
||||
/// \brief Registers extension
|
||||
/// \param library_path path to library with ov::Extension
|
||||
void add_extension(const std::wstring& library_path);
|
||||
#endif
|
||||
|
||||
/// @brief Registers extension
|
||||
/// @param extension Extension class which is inherited from ov::BaseExtension class
|
||||
template <class T, typename std::enable_if<std::is_base_of<ov::Extension, T>::value, bool>::type = true>
|
||||
void add_extension(const T& extension) {
|
||||
std::shared_ptr<ov::Extension> ext = std::make_shared<T>(extension);
|
||||
add_extension(ext);
|
||||
}
|
||||
/// @brief Registers extensions
|
||||
/// @param extension Extension class which is inherited from ov::Extension class
|
||||
template <class T,
|
||||
class... Targs,
|
||||
typename std::enable_if<std::is_base_of<ov::Extension, T>::value, bool>::type = true>
|
||||
void add_extension(const T& extension, Targs... args) {
|
||||
std::shared_ptr<ov::Extension> ext = std::make_shared<T>(extension);
|
||||
add_extension(ext);
|
||||
add_extension(args...);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool supported_impl(const std::vector<std::shared_ptr<Variant>>& variants) const;
|
||||
virtual InputModel::Ptr load_impl(const std::vector<std::shared_ptr<Variant>>& variants) const;
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ public:
|
|||
VariantWrapper(const value_type& value) : VariantImpl<value_type>(value) {}
|
||||
};
|
||||
|
||||
using WeightsVariant = VariantWrapper<Weights>;
|
||||
|
||||
using Extensions = std::map<std::string, ngraph::OpSet>;
|
||||
|
||||
template <>
|
||||
|
|
@ -69,6 +67,4 @@ public:
|
|||
VariantWrapper(const value_type& value) : VariantImpl<value_type>(value) {}
|
||||
};
|
||||
|
||||
using ExtensionsVariant = VariantWrapper<Extensions>;
|
||||
|
||||
} // namespace ov
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
#include "frontend_manager/frontend_manager.hpp"
|
||||
|
||||
#include <frontend_manager/place.hpp>
|
||||
#include <ngraph/except.hpp>
|
||||
#include <openvino/util/env_util.hpp>
|
||||
|
||||
#include "frontend_manager/frontend_exceptions.hpp"
|
||||
#include "frontend_manager/place.hpp"
|
||||
#include "ngraph/except.hpp"
|
||||
#include "openvino/util/env_util.hpp"
|
||||
#include "plugin_loader.hpp"
|
||||
#include "so_extension.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace ngraph;
|
||||
|
|
@ -149,6 +149,25 @@ void FrontEnd::normalize(std::shared_ptr<ngraph::Function> function) const {
|
|||
FRONT_END_NOT_IMPLEMENTED(normalize);
|
||||
}
|
||||
|
||||
void FrontEnd::add_extension(const std::shared_ptr<ov::Extension>& extension) {
|
||||
// Each frontend can support own set of extensions, so this method should be implemented on the frontend side
|
||||
}
|
||||
|
||||
void FrontEnd::add_extension(const std::vector<std::shared_ptr<ov::Extension>>& extensions) {
|
||||
for (const auto& ext : extensions)
|
||||
add_extension(ext);
|
||||
}
|
||||
|
||||
void FrontEnd::add_extension(const std::string& library_path) {
|
||||
add_extension(ov::detail::load_extensions(library_path));
|
||||
}
|
||||
|
||||
#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT
|
||||
void FrontEnd::add_extension(const std::wstring& library_path) {
|
||||
add_extension(ov::detail::load_extensions(library_path));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string FrontEnd::get_name() const {
|
||||
return std::string();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ file(GLOB_RECURSE LIBRARY_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h
|
|||
|
||||
set(${TARGET_NAME}_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
# Add include path to so_extension.hpp
|
||||
set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/frontend.cpp
|
||||
APPEND PROPERTY INCLUDE_DIRECTORIES "${OpenVINO_SOURCE_DIR}/ngraph/core/src/")
|
||||
|
||||
# Create named folders for the sources within the .vcproj
|
||||
# Empty name lists them directly under the .vcproj
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ public:
|
|||
/// \return IR frontend name.
|
||||
std::string get_name() const override;
|
||||
|
||||
/// \brief Register extension in the FrontEnd
|
||||
/// \param extension base extension
|
||||
void add_extension(const ov::Extension::Ptr& extension) override;
|
||||
|
||||
protected:
|
||||
/// \brief Check if FrontEndIR can recognize model from given parts
|
||||
/// \param params Can be path to the model file or std::istream
|
||||
|
|
@ -37,6 +41,10 @@ protected:
|
|||
/// \param params Can be path to the model file or std::istream
|
||||
/// \return InputModel::Ptr
|
||||
InputModel::Ptr load_impl(const std::vector<std::shared_ptr<Variant>>& params) const override;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<void>> shared_objects;
|
||||
std::vector<ov::Extension::Ptr> extensions;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <istream>
|
||||
#include <memory>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
#include <openvino/core/op_extension.hpp>
|
||||
|
||||
namespace ngraph {
|
||||
namespace frontend {
|
||||
|
|
@ -18,7 +19,9 @@ class IR_API InputModelIR : public InputModel {
|
|||
std::shared_ptr<InputModelIRImpl> _impl;
|
||||
|
||||
public:
|
||||
InputModelIR(std::istream& stream, const ov::Weights& weights, const ov::Extensions& extensions);
|
||||
InputModelIR(std::istream& stream,
|
||||
const std::shared_ptr<ngraph::runtime::AlignedBuffer>& weights,
|
||||
const std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr>& extensions);
|
||||
|
||||
std::shared_ptr<Function> convert();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,16 +2,20 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <xml_parse_utils.h>
|
||||
#include "ir_frontend/frontend.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <ir_frontend/frontend.hpp>
|
||||
#include <ir_frontend/model.hpp>
|
||||
#include <ir_frontend/utility.hpp>
|
||||
#include <ngraph/variant.hpp>
|
||||
#include <openvino/util/file_util.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "ir_deserializer.hpp"
|
||||
#include "ir_frontend/model.hpp"
|
||||
#include "ir_frontend/utility.hpp"
|
||||
#include "ngraph/variant.hpp"
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "so_extension.hpp"
|
||||
#include "xml_parse_utils.h"
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
namespace ngraph {
|
||||
|
|
@ -95,17 +99,36 @@ bool FrontEndIR::supported_impl(const std::vector<std::shared_ptr<Variant>>& var
|
|||
return version >= 10 && version <= 11;
|
||||
}
|
||||
|
||||
void FrontEndIR::add_extension(const ov::Extension::Ptr& ext) {
|
||||
if (auto so_ext = std::dynamic_pointer_cast<ov::detail::SOExtension>(ext)) {
|
||||
if (std::dynamic_pointer_cast<ov::BaseOpExtension>(so_ext->extension())) {
|
||||
shared_objects.emplace_back(so_ext->shared_object());
|
||||
extensions.emplace_back(so_ext->extension());
|
||||
}
|
||||
}
|
||||
if (std::dynamic_pointer_cast<ov::BaseOpExtension>(ext))
|
||||
extensions.emplace_back(ext);
|
||||
}
|
||||
|
||||
InputModel::Ptr FrontEndIR::load_impl(const std::vector<std::shared_ptr<Variant>>& variants) const {
|
||||
std::ifstream local_model_stream;
|
||||
std::istream* provided_model_stream = nullptr;
|
||||
ov::Weights weights;
|
||||
ov::Extensions extensions;
|
||||
std::shared_ptr<ngraph::runtime::AlignedBuffer> weights;
|
||||
|
||||
auto create_extensions_map = [&]() -> std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr> {
|
||||
std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr> exts;
|
||||
for (const auto& ext : extensions) {
|
||||
if (auto base_ext = std::dynamic_pointer_cast<ov::BaseOpExtension>(ext))
|
||||
exts.insert({base_ext->get_type_info(), base_ext});
|
||||
}
|
||||
return exts;
|
||||
};
|
||||
|
||||
auto create_input_model = [&]() -> std::shared_ptr<InputModelIR> {
|
||||
if (provided_model_stream) {
|
||||
return std::make_shared<InputModelIR>(*provided_model_stream, weights, extensions);
|
||||
return std::make_shared<InputModelIR>(*provided_model_stream, weights, create_extensions_map());
|
||||
} else if (local_model_stream.is_open()) {
|
||||
auto input_model = std::make_shared<InputModelIR>(local_model_stream, weights, extensions);
|
||||
auto input_model = std::make_shared<InputModelIR>(local_model_stream, weights, create_extensions_map());
|
||||
local_model_stream.close();
|
||||
return input_model;
|
||||
}
|
||||
|
|
@ -153,10 +176,8 @@ InputModel::Ptr FrontEndIR::load_impl(const std::vector<std::shared_ptr<Variant>
|
|||
} else if (ov::is_type<ov::VariantWrapper<std::wstring>>(variant)) {
|
||||
weights_path = ov::as_type_ptr<ov::VariantWrapper<std::wstring>>(variant)->get();
|
||||
#endif
|
||||
} else if (ov::is_type<ov::WeightsVariant>(variant)) {
|
||||
weights = ov::as_type_ptr<ov::WeightsVariant>(variant)->get();
|
||||
} else if (ov::is_type<ov::ExtensionsVariant>(variant)) {
|
||||
extensions = ov::as_type_ptr<ov::ExtensionsVariant>(variant)->get();
|
||||
} else if (ov::is_type<VariantWrapper<std::shared_ptr<ngraph::runtime::AlignedBuffer>>>(variant)) {
|
||||
weights = ov::as_type_ptr<VariantWrapper<std::shared_ptr<ngraph::runtime::AlignedBuffer>>>(variant)->get();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,6 +226,7 @@ InputModel::Ptr FrontEndIR::load_impl(const std::vector<std::shared_ptr<Variant>
|
|||
|
||||
std::shared_ptr<ngraph::Function> FrontEndIR::convert(InputModel::Ptr model) const {
|
||||
auto ir_model = std::dynamic_pointer_cast<InputModelIR>(model);
|
||||
OPENVINO_ASSERT(ir_model != nullptr);
|
||||
return ir_model->convert();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -397,8 +397,9 @@ void XmlDeserializer::on_adapter(const std::string& name,
|
|||
adapter.set(ngraph_function);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> XmlDeserializer::parse_function(const pugi::xml_node& root,
|
||||
const ov::Weights& weights) {
|
||||
std::shared_ptr<ngraph::Function> XmlDeserializer::parse_function(
|
||||
const pugi::xml_node& root,
|
||||
const std::shared_ptr<ngraph::runtime::AlignedBuffer>& weights) {
|
||||
// OV_ITT_SCOPE_CHAIN(FIRST_INFERENCE, taskChain, itt::domains::V10Reader_RT, "V10Parser", "Parse");
|
||||
|
||||
struct FunctionNodes {
|
||||
|
|
@ -615,6 +616,13 @@ std::shared_ptr<ngraph::Node> XmlDeserializer::createNode(const std::vector<ngra
|
|||
}
|
||||
|
||||
std::shared_ptr<ngraph::Node> ngraphNode;
|
||||
ov::DiscreteTypeInfo type(params.type.c_str(), 0, params.version.c_str());
|
||||
auto extensionIt = m_extensions.find(type);
|
||||
|
||||
if (extensionIt != m_extensions.end()) {
|
||||
XmlDeserializer visitor(node, weights, m_opsets, m_extensions, m_variables, m_version);
|
||||
ngraphNode = (*extensionIt->second).create(inputs, visitor).at(0).get_node_shared_ptr();
|
||||
}
|
||||
|
||||
// Find registered opset
|
||||
auto opsetIt = m_opsets.find(params.version);
|
||||
|
|
@ -660,7 +668,7 @@ std::shared_ptr<ngraph::Node> XmlDeserializer::createNode(const std::vector<ngra
|
|||
constant->alloc_buffer_on_visit_attributes(false);
|
||||
}
|
||||
ngraphNode->set_arguments(inputs);
|
||||
XmlDeserializer visitor(node, weights, m_opsets, m_variables, m_version);
|
||||
XmlDeserializer visitor(node, weights, m_opsets, m_extensions, m_variables, m_version);
|
||||
|
||||
if (ngraphNode->visit_attributes(visitor)) {
|
||||
ngraphNode->constructor_validate_and_infer_types();
|
||||
|
|
@ -669,10 +677,9 @@ std::shared_ptr<ngraph::Node> XmlDeserializer::createNode(const std::vector<ngra
|
|||
// To be sure that all default values will be initialized:
|
||||
ngraphNode = ngraphNode->clone_with_new_inputs(ngraphNode->input_values());
|
||||
}
|
||||
|
||||
if (!ngraphNode && m_use_framework_node) {
|
||||
ngraphNode = std::make_shared<ngraph::op::FrameworkNode>(inputs);
|
||||
XmlDeserializer visitor(node, weights, m_opsets, m_variables, m_version);
|
||||
if (!ngraphNode && m_extensions.count(ov::op::util::FrameworkNode::get_type_info_static())) {
|
||||
ngraphNode = std::make_shared<ov::op::util::FrameworkNode>(inputs);
|
||||
XmlDeserializer visitor(node, weights, m_opsets, m_extensions, m_variables, m_version);
|
||||
ngraphNode->visit_attributes(visitor);
|
||||
|
||||
size_t index{0};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@
|
|||
#include <pugixml.hpp>
|
||||
#include <utils.hpp>
|
||||
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
|
||||
namespace ov {
|
||||
|
||||
struct GenericLayerParams {
|
||||
struct LayerPortData {
|
||||
size_t portId;
|
||||
|
|
@ -55,13 +58,15 @@ struct GenericLayerParams {
|
|||
class XmlDeserializer : public ngraph::AttributeVisitor {
|
||||
public:
|
||||
explicit XmlDeserializer(const pugi::xml_node& node,
|
||||
const ov::Weights& weights,
|
||||
const std::shared_ptr<ngraph::runtime::AlignedBuffer>& weights,
|
||||
const std::unordered_map<std::string, ngraph::OpSet>& opsets,
|
||||
const std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr>& extensions,
|
||||
std::unordered_map<std::string, std::shared_ptr<ngraph::Variable>>& variables,
|
||||
size_t version)
|
||||
: m_node(node),
|
||||
m_weights(weights),
|
||||
m_opsets(opsets),
|
||||
m_extensions(extensions),
|
||||
m_variables(variables),
|
||||
m_version(version) {}
|
||||
|
||||
|
|
@ -134,10 +139,6 @@ public:
|
|||
adapter.set(value);
|
||||
}
|
||||
|
||||
void use_framework_node(bool flag) {
|
||||
m_use_framework_node = flag;
|
||||
}
|
||||
|
||||
private:
|
||||
struct IoMap {
|
||||
using NodeIdToIoIndex = std::unordered_map<size_t /*xml node id*/, uint64_t /*body io index*/>;
|
||||
|
|
@ -163,7 +164,8 @@ private:
|
|||
/// \param node xml node representation
|
||||
/// \param weights weights attached to current node
|
||||
/// \return shared pointer to function representing input node
|
||||
std::shared_ptr<ngraph::Function> parse_function(const pugi::xml_node& root, const ov::Weights& weights);
|
||||
std::shared_ptr<ngraph::Function> parse_function(const pugi::xml_node& root,
|
||||
const std::shared_ptr<ngraph::runtime::AlignedBuffer>& weights);
|
||||
/// \brief Traverses xml node representation in order to get the purpose attribute of
|
||||
/// inputs/outputs in the body of Loop op. \param node xml node representation \return struct
|
||||
/// with value of purpuse attribute
|
||||
|
|
@ -180,6 +182,7 @@ private:
|
|||
const pugi::xml_node m_node;
|
||||
const ov::Weights& m_weights;
|
||||
const std::unordered_map<std::string, ngraph::OpSet>& m_opsets;
|
||||
const std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr>& m_extensions;
|
||||
std::unordered_map<std::string, std::shared_ptr<ngraph::Variable>>& m_variables;
|
||||
|
||||
///
|
||||
|
|
@ -188,7 +191,6 @@ private:
|
|||
///
|
||||
IoMap io_map;
|
||||
|
||||
bool m_use_framework_node{false};
|
||||
int64_t m_version;
|
||||
};
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ using namespace ngraph;
|
|||
using namespace InferenceEngine;
|
||||
|
||||
namespace {
|
||||
void ParsePreProcess(pugi::xml_node& root, ov::Weights weights, std::shared_ptr<Function> f) {
|
||||
void ParsePreProcess(pugi::xml_node& root,
|
||||
std::shared_ptr<ngraph::runtime::AlignedBuffer> weights,
|
||||
std::shared_ptr<Function> f) {
|
||||
/* Preprocessing block can have two preprocessing types:
|
||||
*
|
||||
* <pre-process mean-precision="FP32" reference-layer-name="data">
|
||||
|
|
@ -183,13 +185,16 @@ void ParsePreProcess(pugi::xml_node& root, ov::Weights weights, std::shared_ptr<
|
|||
namespace ngraph {
|
||||
namespace frontend {
|
||||
class InputModelIR::InputModelIRImpl {
|
||||
ov::Weights m_weights;
|
||||
ov::Extensions m_extensions;
|
||||
std::shared_ptr<ngraph::runtime::AlignedBuffer> m_weights;
|
||||
std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr> m_extensions;
|
||||
std::unordered_map<std::string, ngraph::OpSet> m_opsets;
|
||||
pugi::xml_node m_root;
|
||||
pugi::xml_document m_xml_doc;
|
||||
|
||||
public:
|
||||
InputModelIRImpl(std::istream& stream, const ov::Weights& weights, const ov::Extensions& extensions)
|
||||
InputModelIRImpl(std::istream& stream,
|
||||
const std::shared_ptr<ngraph::runtime::AlignedBuffer>& weights,
|
||||
const std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr>& extensions)
|
||||
: m_weights(weights),
|
||||
m_extensions(extensions) {
|
||||
pugi::xml_parse_result res = m_xml_doc.load(stream);
|
||||
|
|
@ -197,12 +202,22 @@ public:
|
|||
IE_THROW() << res.description() << " at offset " << res.offset;
|
||||
}
|
||||
m_root = m_xml_doc.document_element();
|
||||
m_opsets["opset1"] = ngraph::get_opset1();
|
||||
m_opsets["opset2"] = ngraph::get_opset2();
|
||||
m_opsets["opset3"] = ngraph::get_opset3();
|
||||
m_opsets["opset4"] = ngraph::get_opset4();
|
||||
m_opsets["opset5"] = ngraph::get_opset5();
|
||||
m_opsets["opset6"] = ngraph::get_opset6();
|
||||
m_opsets["opset7"] = ngraph::get_opset7();
|
||||
m_opsets["opset8"] = ngraph::get_opset8();
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> convert();
|
||||
};
|
||||
|
||||
InputModelIR::InputModelIR(std::istream& stream, const ov::Weights& weights, const ov::Extensions& extensions) {
|
||||
InputModelIR::InputModelIR(std::istream& stream,
|
||||
const std::shared_ptr<ngraph::runtime::AlignedBuffer>& weights,
|
||||
const std::unordered_map<ov::DiscreteTypeInfo, ov::BaseOpExtension::Ptr>& extensions) {
|
||||
_impl = std::make_shared<InputModelIRImpl>(stream, weights, extensions);
|
||||
}
|
||||
|
||||
|
|
@ -211,29 +226,11 @@ std::shared_ptr<Function> InputModelIR::convert() {
|
|||
}
|
||||
|
||||
std::shared_ptr<Function> InputModelIR::InputModelIRImpl::convert() {
|
||||
std::unordered_map<std::string, ngraph::OpSet> opsets;
|
||||
std::unordered_map<std::string, std::shared_ptr<ngraph::Variable>> variables;
|
||||
|
||||
// Load default opsets
|
||||
opsets["opset1"] = ngraph::get_opset1();
|
||||
opsets["opset2"] = ngraph::get_opset2();
|
||||
opsets["opset3"] = ngraph::get_opset3();
|
||||
opsets["opset4"] = ngraph::get_opset4();
|
||||
opsets["opset5"] = ngraph::get_opset5();
|
||||
opsets["opset6"] = ngraph::get_opset6();
|
||||
opsets["opset7"] = ngraph::get_opset7();
|
||||
opsets["opset8"] = ngraph::get_opset8();
|
||||
|
||||
// Load custom opsets
|
||||
for (const auto& it : m_extensions) {
|
||||
if (opsets.find(it.first) != opsets.end())
|
||||
IE_THROW() << "Cannot add opset with name: " << it.first << ". Opset with the same name already exists.";
|
||||
opsets[it.first] = it.second;
|
||||
}
|
||||
|
||||
size_t version = XMLParseUtils::GetUIntAttr(m_root, "version", 0);
|
||||
ov::XmlDeserializer visitor(m_root, m_weights, opsets, variables, version);
|
||||
visitor.use_framework_node(opsets.count("framework_node_ext"));
|
||||
ov::XmlDeserializer visitor(m_root, m_weights, m_opsets, m_extensions, variables, version);
|
||||
std::shared_ptr<ngraph::Function> function;
|
||||
visitor.on_attribute("net", function);
|
||||
function->get_rt_info()["version"] = std::make_shared<ngraph::VariantWrapper<int64_t>>(version);
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ set(SRC
|
|||
copy.cpp
|
||||
element_type.cpp
|
||||
eval.cpp
|
||||
extension.cpp
|
||||
file_util.cpp
|
||||
float16.cpp
|
||||
framework_node.cpp
|
||||
function.cpp
|
||||
graph_rewrite.cpp
|
||||
includes.cpp
|
||||
input_output_assign.cpp
|
||||
int4.cpp
|
||||
intervals.cpp
|
||||
|
|
@ -402,13 +402,16 @@ set(SRC
|
|||
util.cpp
|
||||
)
|
||||
|
||||
# Add include path to so_extension.hpp
|
||||
set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/extension.cpp
|
||||
APPEND PROPERTY INCLUDE_DIRECTORIES "${OpenVINO_SOURCE_DIR}/ngraph/core/src/")
|
||||
|
||||
if(SUGGEST_OVERRIDE_SUPPORTED)
|
||||
set_source_files_properties(ov_tensor_test.cpp
|
||||
PROPERTIES COMPILE_OPTIONS -Wno-suggest-override)
|
||||
endif()
|
||||
|
||||
set_source_files_properties(includes.cpp PROPERTIES COMPILE_DEFINITIONS
|
||||
NGRAPH_INCLUDES="${PROJECT_SOURCE_DIR}/src/ngraph")
|
||||
list(APPEND UNIT_TESTS_DEPENDENCIES template_ov_extension)
|
||||
|
||||
if (ENABLE_MKL_DNN AND NGRAPH_UNIT_TEST_BACKENDS_ENABLE)
|
||||
message(STATUS "NGRAPH_TESTS: IE:CPU enabled")
|
||||
|
|
@ -570,8 +573,10 @@ target_include_directories(unit-test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/runtime
|
|||
get_target_property(NGRAPH_SRC_DIR openvino::core SOURCE_DIR)
|
||||
target_include_directories(unit-test PRIVATE ${NGRAPH_SRC_DIR}/src)
|
||||
|
||||
add_definitions("-DCURDIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"")
|
||||
add_definitions("-DJSON_INCLUDES=\"${JSON_INCLUDE_DIR}\"")
|
||||
target_compile_definitions(unit-test
|
||||
PRIVATE
|
||||
SHARED_LIB_PREFIX="${CMAKE_SHARED_LIBRARY_PREFIX}"
|
||||
SHARED_LIB_SUFFIX="${IE_BUILD_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
|
||||
if(UNIT_TESTS_DEPENDENCIES)
|
||||
add_dependencies(unit-test ${UNIT_TESTS_DEPENDENCIES})
|
||||
|
|
@ -587,6 +592,7 @@ target_link_libraries(unit-test PRIVATE ngraph_test_util
|
|||
interpreter_backend
|
||||
Threads::Threads
|
||||
openvino::conditional_compilation
|
||||
openvino::util
|
||||
frontend_manager)
|
||||
|
||||
# Protobuf-lite does not support parsing files from prototxt format
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/core/extension.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "openvino/core/graph_util.hpp"
|
||||
#include "openvino/core/op_extension.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "so_extension.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# if defined(WINAPI_FAMILY) && !WINAPI_PARTITION_DESKTOP
|
||||
# error "Only WINAPI_PARTITION_DESKTOP is supported, because of LoadLibrary[A|W]"
|
||||
# endif
|
||||
#elif defined(__linux) || defined(__APPLE__)
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
static std::string find_my_pathname() {
|
||||
#ifdef _WIN32
|
||||
HMODULE hModule = GetModuleHandleW(SHARED_LIB_PREFIX L"ngraph" SHARED_LIB_SUFFIX);
|
||||
WCHAR wpath[MAX_PATH];
|
||||
GetModuleFileNameW(hModule, wpath, MAX_PATH);
|
||||
std::wstring ws(wpath);
|
||||
std::string path(ws.begin(), ws.end());
|
||||
replace(path.begin(), path.end(), '\\', '/');
|
||||
path = ov::util::get_directory(path);
|
||||
path += "/";
|
||||
return path;
|
||||
#elif defined(__linux) || defined(__APPLE__)
|
||||
Dl_info dl_info;
|
||||
dladdr(reinterpret_cast<void*>(ov::replace_output_update_name), &dl_info);
|
||||
return ov::util::get_directory(dl_info.dli_fname);
|
||||
#else
|
||||
# error "Unsupported OS"
|
||||
#endif
|
||||
}
|
||||
std::string get_extension_path() {
|
||||
return ov::util::make_plugin_library_name<char>(find_my_pathname(),
|
||||
std::string("template_ov_extension") + IE_BUILD_POSTFIX);
|
||||
}
|
||||
|
||||
TEST(extension, load_extension) {
|
||||
EXPECT_NO_THROW(ov::detail::load_extensions(get_extension_path()));
|
||||
}
|
||||
|
||||
TEST(extension, load_extension_and_cast) {
|
||||
std::vector<ov::Extension::Ptr> so_extensions;
|
||||
EXPECT_NO_THROW(so_extensions = ov::detail::load_extensions(get_extension_path()));
|
||||
EXPECT_EQ(1, so_extensions.size());
|
||||
std::vector<ov::Extension::Ptr> extensions;
|
||||
std::vector<std::shared_ptr<void>> so;
|
||||
for (const auto& ext : so_extensions) {
|
||||
if (auto so_ext = std::dynamic_pointer_cast<ov::detail::SOExtension>(ext)) {
|
||||
extensions.emplace_back(so_ext->extension());
|
||||
so.emplace_back(so_ext->shared_object());
|
||||
}
|
||||
}
|
||||
so_extensions.clear();
|
||||
EXPECT_EQ(1, extensions.size());
|
||||
EXPECT_NE(nullptr, dynamic_cast<ov::BaseOpExtension*>(extensions[0].get()));
|
||||
EXPECT_NE(nullptr, std::dynamic_pointer_cast<ov::BaseOpExtension>(extensions[0]));
|
||||
extensions.clear();
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// #include "ngraph/codegen/compiler.hpp"
|
||||
// #include "ngraph/file_util.hpp"
|
||||
// #include "ngraph/log.hpp"
|
||||
// #include "ngraph/util.hpp"
|
||||
|
||||
// using namespace std;
|
||||
// using namespace ngraph;
|
||||
|
||||
// TEST(DISABLED_include, complete)
|
||||
// {
|
||||
// vector<string> include_files;
|
||||
// set<string> ext_list{".hpp"};
|
||||
// set<string> exclude{"onnx_import", "onnxifi", "intelgpu", "op_tbl.hpp"};
|
||||
// auto func = [&](const std::string& file, bool is_dir) {
|
||||
// if (!is_dir && file.size() > 4)
|
||||
// {
|
||||
// for (const string& x : exclude)
|
||||
// {
|
||||
// if (file.find(x) != file.npos)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// string ext = file.substr(file.size() - 4);
|
||||
// if (ext_list.find(ext) != ext_list.end())
|
||||
// {
|
||||
// include_files.push_back(file);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// file_util::iterate_files(NGRAPH_INCLUDES, func, true);
|
||||
|
||||
// for (const string& include : include_files)
|
||||
// {
|
||||
// string source = "#include <" + include + ">\n ";
|
||||
|
||||
// codegen::Compiler compiler;
|
||||
// compiler.add_header_search_path(JSON_INCLUDES);
|
||||
// auto module = compiler.compile(source);
|
||||
// if (!module)
|
||||
// {
|
||||
// cout << "fail " << include << endl;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Loading…
Reference in New Issue