|
13 | 13 |
|
14 | 14 | import numpy as np
|
15 | 15 | import openvino.runtime as ov
|
| 16 | +import openvino.runtime.op as op |
16 | 17 | import openvino.runtime.opset13 as opset
|
17 | 18 |
|
18 | 19 | import nncf
|
|
41 | 42 | from nncf.openvino.graph.metatypes.openvino_metatypes import OVMatMulMetatype
|
42 | 43 | from nncf.openvino.graph.metatypes.openvino_metatypes import OVOpMetatype
|
43 | 44 | from nncf.openvino.graph.metatypes.openvino_metatypes import get_node_metatype
|
| 45 | +from nncf.tensor import Tensor |
| 46 | +from nncf.tensor import TensorBackend |
44 | 47 |
|
45 | 48 | InplaceInsertionFnType = Callable[[ov.Node, int, str], ov.Node]
|
46 | 49 |
|
@@ -97,26 +100,27 @@ def get_number_if_op(model: ov.Model) -> int:
|
97 | 100 | """
|
98 | 101 |
|
99 | 102 | def cnt_if_op(model: ov.Model, cnt: int) -> int:
|
100 |
| - for op in model.get_ops(): |
101 |
| - if get_node_metatype(op) == OVIfMetatype: |
| 103 | + for model_op in model.get_ops(): |
| 104 | + if get_node_metatype(model_op) == OVIfMetatype: |
102 | 105 | cnt += 1
|
103 |
| - cnt = cnt_if_op(op.get_function(0), cnt) |
104 |
| - cnt = cnt_if_op(op.get_function(1), cnt) |
| 106 | + cnt = cnt_if_op(model_op.get_function(0), cnt) |
| 107 | + cnt = cnt_if_op(model_op.get_function(1), cnt) |
105 | 108 | return cnt
|
106 | 109 |
|
107 | 110 | return cnt_if_op(model, 0)
|
108 | 111 |
|
109 | 112 |
|
110 |
| -def get_const_value(const_node: ov.Node) -> np.ndarray: |
| 113 | +def get_const_value(const_node: ov.Node, cast_bf16_to_fp32: bool = True) -> np.ndarray: |
111 | 114 | """
|
112 | 115 | Returns the constant tensor for the node.
|
113 | 116 | This method is applicable only for the floating-point constant data.
|
114 | 117 |
|
115 | 118 | :param const_node: OpenVINO node.
|
| 119 | + :param cast_bf16_to_fp32: Whether to cast bf16 node data to fp32 or not. If False and the node contains bf16 data, |
| 120 | + the resulting bf16 value will be returned encoded inside a numpy.float16 array. |
116 | 121 | :return: The constant value.
|
117 | 122 | """
|
118 |
| - if const_node.get_element_type() == ov.Type.bf16: |
119 |
| - # Fixed FP32 data type as the result for BF16 constant |
| 123 | + if const_node.get_element_type() == ov.Type.bf16 and cast_bf16_to_fp32: |
120 | 124 | return const_node.get_data(dtype=np.float32)
|
121 | 125 | return const_node.data
|
122 | 126 |
|
@@ -635,3 +639,42 @@ def get_activation_channel_axis(node: NNCFNode, port_id: int, input_shape: Tuple
|
635 | 639 | channel_axis = activations_layout.index(OVLayoutElem.C_IN)
|
636 | 640 |
|
637 | 641 | return channel_axis
|
| 642 | + |
| 643 | + |
| 644 | +def convert_op(node: ov.Node, target_dtype: ov.Type) -> ov.Node: |
| 645 | + """ |
| 646 | + Return a subgraph which converts the given node output to the target data type. If the output is already in the |
| 647 | + target data type then the given node is returned. |
| 648 | +
|
| 649 | + :param node: The input node to convert. |
| 650 | + :param target_dtype: The target data type to convert the input node to. |
| 651 | + :return: The converted node. |
| 652 | + """ |
| 653 | + if node.get_element_type() == target_dtype: |
| 654 | + return node |
| 655 | + return opset.convert(node, target_dtype) |
| 656 | + |
| 657 | + |
| 658 | +def non_convertable_divide_op(a: ov.Node, b: ov.Node) -> ov.Node: |
| 659 | + """ |
| 660 | + Creates a "non-convertable" divide operation. It won't be converted to a*(1/b). |
| 661 | + """ |
| 662 | + divide_node = a / b |
| 663 | + divide_node.get_rt_info()["nonconvertable_divide_0"] = True |
| 664 | + return divide_node |
| 665 | + |
| 666 | + |
| 667 | +def create_ov_const_from_tensor(x: Tensor, dtype: ov.Type, name: Optional[str] = None) -> op.Constant: |
| 668 | + """ |
| 669 | + Create an OpenVINO Constant node from the given tensor. |
| 670 | + :param x: Data tensor. Supports NumPy and OV tensor backends. If x backend is OV, the constant node is created |
| 671 | + directly from underlying OV tensor. |
| 672 | + :param dtype: Data type of the constant. |
| 673 | + :param name: Optional name of the constant. |
| 674 | + :return: OpenVINO Constant node. |
| 675 | + """ |
| 676 | + if x.backend == TensorBackend.ov: |
| 677 | + assert x.data.get_element_type() == dtype |
| 678 | + return opset.constant(x.data, name=name, shared_memory=True) |
| 679 | + const = opset.constant(x.data, dtype=dtype, name=name) |
| 680 | + return const |
0 commit comments