diff --git a/docs/articles_en/documentation/openvino-extensibility/openvino-plugin-library/transformation-python-api/matcher-pass.rst b/docs/articles_en/documentation/openvino-extensibility/openvino-plugin-library/transformation-python-api/matcher-pass.rst new file mode 100644 index 00000000000000..ef00ccaa05376a --- /dev/null +++ b/docs/articles_en/documentation/openvino-extensibility/openvino-plugin-library/transformation-python-api/matcher-pass.rst @@ -0,0 +1,46 @@ +.. {#openvino_docs_Extensibility_UG_matcher_pass} + +OpenVINO Model Pass Python API +============================== + + +.. meta:: + :description: Learn how to create a pattern, implement a callback, register + the pattern and Matcher to execute MatcherPass transformation + on a model. + +``MatcherPass`` is used for pattern-based transformations. +To create transformation you need: + +1. Create a pattern +2. Implement a callback +3. Register the pattern and Matcher + +In the next example we define transformation that searches for ``Relu`` layer and inserts after it another +``Relu`` layer. + +.. doxygensnippet:: docs/snippets/ov_matcher_pass.py + :language: py + :fragment: [matcher_pass:ov_matcher_pass_py] + +The next example shows MatcherPass-based transformation usage. + +.. doxygensnippet:: docs/snippets/ov_matcher_pass.py + :language: py + :fragment: [matcher_pass_full_example:ov_matcher_pass_py] + +After running this code you will see the next: text +``` +model ops : +parameter +result +relu + +model ops : +parameter +result +relu +new_relu +``` + +In oder to run this script you need to export PYTHONPATH as the path to binary OpenVINO python models. diff --git a/docs/articles_en/documentation/openvino-extensibility/openvino-plugin-library/transformation-python-api/model-pass.rst b/docs/articles_en/documentation/openvino-extensibility/openvino-plugin-library/transformation-python-api/model-pass.rst new file mode 100644 index 00000000000000..e133fa7f3d5fc4 --- /dev/null +++ b/docs/articles_en/documentation/openvino-extensibility/openvino-plugin-library/transformation-python-api/model-pass.rst @@ -0,0 +1,30 @@ +.. {#openvino_docs_Extensibility_UG_model_pass} + +OpenVINO Model Pass Python API +============================== + + +.. meta:: + :description: Learn how to use Model Pass transformation class to take entire + ov::Model as input and process it. + +``ModelPass`` can be used as base class for transformation classes that take entire ``Model`` and proceed it. +To create transformation you need: + +1. Define class with ``ModelPass`` as a parent +2. Redefine run_on_model method that will receive ``Model`` as an argument + +.. doxygensnippet:: docs/snippets/ov_model_pass.py + :language: py + :fragment: [model_pass:ov_model_pass_py] + +In this example we define transformation that prints all model operation names. + +The next example shows ModelPass-based transformation usage. + +.. doxygensnippet:: docs/snippets/ov_model_pass.py + :language: py + :fragment: [model_pass_full_example:ov_model_pass_py] + +We create Model with Relu, Parameter and Result nodes. After running this code you will see names of these three nodes. +In oder to run this script you need to export PYTHONPATH as the path to binary OpenVINO python models. diff --git a/docs/snippets/ov_model_pass.py b/docs/snippets/ov_model_pass.py new file mode 100644 index 00000000000000..1042f92c524945 --- /dev/null +++ b/docs/snippets/ov_model_pass.py @@ -0,0 +1,40 @@ +// ! [model_pass:ov_model_pass_py] +from openvino.runtime.passes import ModelPass + +class MyModelPass(ModelPass): + def __init__(self): + super().__init__() + + def run_on_model(self, model): + for op in model.get_ops(): + print(op.get_friendly_name()) +// ! [model_pass:ov_model_pass_py] + +// ! [model_pass_full_example:ov_model_pass_py] +from openvino.runtime.passes import Manager, GraphRewrite, BackwardGraphRewrite, Serialize +from openvino import Model, PartialShape +from openvino.runtime import opset13 as ops +from openvino.runtime.passes import ModelPass, Matcher, MatcherPass, WrapType + + +def get_relu_model(): + # Parameter->Relu->Result + param = ops.parameter(PartialShape([1, 3, 22, 22]), name="parameter") + relu = ops.relu(param.output(0)) + res = ops.result(relu.output(0), name="result") + return Model([res], [param], "test") + + +class MyModelPass(ModelPass): + def __init__(self): + super().__init__() + + def run_on_model(self, model): + for op in model.get_ops(): + print(op.get_friendly_name()) + + +manager = Manager() +manager.register_pass(MyModelPass()) +manager.run_passes(get_relu_model()) +// ! [model_pass_full_example:ov_model_pass_py] diff --git a/docs/snippets/src/ov_matcher_pass.py b/docs/snippets/src/ov_matcher_pass.py new file mode 100644 index 00000000000000..57f760b275ccfb --- /dev/null +++ b/docs/snippets/src/ov_matcher_pass.py @@ -0,0 +1,76 @@ +// ! [matcher_pass:ov_matcher_pass_py] +from openvino.runtime.passes import MatcherPass + +class PatternReplacement(MatcherPass): + def __init__(self): + MatcherPass.__init__(self) + relu = WrapType("opset13::Relu") + + def callback(matcher: Matcher) -> bool: + root = matcher.get_match_root() + new_relu = ops.relu(root.input(0).get_source_output()) + + """Use new operation for additional matching + self.register_new_node(new_relu) + + Input->Relu->Result => Input->Relu->Relu->Result + """ + root.input(0).replace_source_output(new_relu.output(0)) + return True + + self.register_matcher(Matcher(relu, "PatternReplacement"), callback) +// ! [matcher_pass:ov_matcher_pass_py] + +// ! [matcher_pass_full_example:ov_matcher_pass_py] +from openvino.runtime.passes import Manager, GraphRewrite, BackwardGraphRewrite, Serialize +from openvino import Model, PartialShape +from openvino.runtime import opset13 as ops +from openvino.runtime.passes import ModelPass, Matcher, MatcherPass, WrapType + +class PatternReplacement(MatcherPass): + def __init__(self): + MatcherPass.__init__(self) + relu = WrapType("opset13::Relu") + + def callback(matcher: Matcher) -> bool: + root = matcher.get_match_root() + new_relu = ops.relu(root.input(0).get_source_output()) + new_relu.set_friendly_name('new_relu') + + """Use new operation for additional matching + self.register_new_node(new_relu) + + Input->Relu->Result => Input->Relu->Relu->Result + """ + root.input(0).replace_source_output(new_relu.output(0)) + return True + + self.register_matcher(Matcher(relu, "PatternReplacement"), callback) + + +def get_relu_model(): + # Parameter->Relu->Result + param = ops.parameter(PartialShape([1, 3, 22, 22]), name="parameter") + relu = ops.relu(param.output(0)) + relu.set_friendly_name('relu') + res = ops.result(relu.output(0), name="result") + return Model([res], [param], "test") + + +def print_model_ops(model): + print('model ops : ') + for op in model.get_ops(): + print(op.get_friendly_name()) + print('') + + +manager = Manager() +manager.register_pass(PatternReplacement()) + + +model = get_relu_model() +print_model_ops(model) +manager.run_passes(model) +print_model_ops(model) + +// ! [matcher_pass_full_example:ov_matcher_pass_py]