Add docs for OPENVINO_FRAMEWORK_MAP macro (#14928)

* Add docs for OPENVINO_FRAMEWORK_MAP macro

Ticket: 98762

* Apply suggestions from code review

Co-authored-by: Piotr Krzemiński <piotrkrzeminski1234@gmail.com>

---------

Co-authored-by: Piotr Krzemiński <piotrkrzeminski1234@gmail.com>
This commit is contained in:
Mateusz Tabaka 2023-03-26 20:00:43 +02:00 committed by GitHub
parent 6eb8f4b2b7
commit 1df14c6a6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 1 deletions

View File

@ -116,6 +116,33 @@ So the conclusion is that each attribute of target OpenVINO operation should be
This is achieved by specifying maps as arguments for `OpExtension` constructor. This is achieved by specifying maps as arguments for `OpExtension` constructor.
### Mapping custom operations to frontends with OPENVINO_FRAMEWORK_MAP macro
> **NOTE**: Below solution works only for ONNX and Tensorflow frontends.
`OPENVINO_FRAMEWORK_MAP` is a macro that should be used inside OpenVINO operation's class definition and that lets you specify the mapping between this operation to a frontend operation.
Let's consider the following example. Imagine you have an ONNX model with `CustomOp` operation (and this operation has `mode` attribute) and a Tensorflow model with `CustomOpV3` operation (this operation has `axis` attribute) and both of them can be implemented with a single OpenVINO operation `CustomOp` like follows:
@snippet ov_extensions.cpp frontend_extension_framework_map_macro_headers
@snippet ov_extensions.cpp frontend_extension_framework_map_macro_CustomOp
Let's take a closer look at the parameters this macro takes:
```cpp
OPENVINO_FRAMEWORK_MAP(framework, name, attributes_map, attributes_values)
```
- `framework` - framework name.
- `name` - the framework operation name. It's optional if the OpenVINO custom operation name (that is the name that is passed as the first parameter to `OPENVINO_OP` macro) is the same as the framework operation name and both `attributes_map` and `attributes_values` are not provided.
- `attributes_map` - used to provide a mapping between OpenVINO operation attribute and framework operation attribute. Contains key-value pairs, where key is an OpenVINO operation attribute name and value is its corresponding framework operation attribute name. This parameter is optional if the number of OpenVINO operation attributes and their names match one-to-one with framework operation attributes.
- `attributes_values` - used to provide default values for OpenVINO operation attributes that are not specified in `attributes_map`. Contains key-value pairs, where key is an OpenVINO operation attribute name and the value is this attribute value. This parameter cannot be provided if `attributes_map` contains all of OpenVINO operation attributes or if `attributes_map` is not provided.
In the example above, `OPENVINO_FRAMEWORK_MAP` is used twice.
First, OpenVINO `CustomOp` is mapped to ONNX `CustomOp` operation, `m_mode` attribute is mapped to `mode` attribute, while `m_axis` attribute gets the default value `-1`.
Secondly, OpenVINO `CustomOp` is mapped to Tensorflow `CustomOpV3` operation, `m_axis` attribute is mapped to `axis` attribute, while `m_mode` attribute gets the default value `"linear"`.
The last step is to register this custom operation by following:
@snippet ov_extensions.cpp frontend_extension_framework_map_macro_add_extension
Mapping to Multiple Operations with ConversionExtension Mapping to Multiple Operations with ConversionExtension
####################################################### #######################################################

View File

@ -60,7 +60,10 @@ target_include_directories(${TARGET_NAME} PRIVATE "${OpenVINO_SOURCE_DIR}/src/in
"${OpenVINO_SOURCE_DIR}/src/common/util/include" "${OpenVINO_SOURCE_DIR}/src/common/util/include"
"${OpenVINO_SOURCE_DIR}/src/common/low_precision_transformations/include" "${OpenVINO_SOURCE_DIR}/src/common/low_precision_transformations/include"
"${OpenVINO_SOURCE_DIR}/src/frontends/common/include" "${OpenVINO_SOURCE_DIR}/src/frontends/common/include"
"${OpenVINO_SOURCE_DIR}/src/core/template_extension/new/") "${OpenVINO_SOURCE_DIR}/src/core/template_extension/new"
"${OpenVINO_SOURCE_DIR}/src/frontends/onnx/frontend/include"
"${OpenVINO_SOURCE_DIR}/src/frontends/tensorflow/include")
ov_mark_target_as_cc(${TARGET_NAME}) ov_mark_target_as_cc(${TARGET_NAME})
if(TARGET OpenCL::OpenCL) if(TARGET OpenCL::OpenCL)

View File

@ -17,6 +17,12 @@
#include <openvino/opsets/opset8.hpp> #include <openvino/opsets/opset8.hpp>
//! [frontend_extension_ThresholdedReLU_header] //! [frontend_extension_ThresholdedReLU_header]
//! [frontend_extension_framework_map_macro_headers]
#include <openvino/frontend/extension/op.hpp>
#include <openvino/frontend/onnx/extension/op.hpp>
#include <openvino/frontend/tensorflow/extension/op.hpp>
//! [frontend_extension_framework_map_macro_headers]
#include <identity.hpp> #include <identity.hpp>
//! [frontend_extension_CustomOperation] //! [frontend_extension_CustomOperation]
@ -40,6 +46,27 @@ public:
std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector&) const override { return nullptr; } std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector&) const override { return nullptr; }
}; };
//! [frontend_extension_framework_map_macro_CustomOp]
class CustomOp : public ov::op::Op {
std::string m_mode;
int m_axis;
public:
OPENVINO_OP("CustomOp");
OPENVINO_FRAMEWORK_MAP(onnx, "CustomOp", { {"m_mode", "mode"} }, { {"m_axis", -1} });
OPENVINO_FRAMEWORK_MAP(tensorflow, "CustomOpV3", { {"m_axis", "axis"} }, { {"m_mode", "linear"} });
bool visit_attributes(ov::AttributeVisitor& visitor) override {
visitor.on_attribute("m_mode", m_mode);
visitor.on_attribute("m_axis", m_axis);
return true;
}
// ... implement other required methods
//! [frontend_extension_framework_map_macro_CustomOp]
std::shared_ptr<ov::Node> clone_with_new_inputs(const ov::OutputVector&) const override { return nullptr; }
};
int main() { int main() {
{ {
//! [add_extension] //! [add_extension]
@ -125,5 +152,12 @@ ov::Core core;
core.add_extension("openvino_template_extension.so"); core.add_extension("openvino_template_extension.so");
//! [add_extension_lib] //! [add_extension_lib]
} }
{
//! [frontend_extension_framework_map_macro_add_extension]
ov::Core core;
core.add_extension(ov::frontend::OpExtension<CustomOp>());
//! [frontend_extension_framework_map_macro_add_extension]
}
return 0; return 0;
} }