From 9479779394cbefd5931f6bb065f24470d4b05d89 Mon Sep 17 00:00:00 2001 From: Andrey Churkin Date: Thu, 23 Nov 2023 15:13:29 +0000 Subject: [PATCH] OVWeightUpdateCommand copies a constant (#2277) ### Changes - Update an implementation of `get_const_value()` method. This method was initially implemented as a workaround in [PR 1654](https://github.com/openvinotoolkit/nncf/pull/1654), but it is no longer needed and can be replaced with `const_op.data`. - Replace `const_op.get_data()` with `const_op.data` because the `const_op.get_data()` legacy method and `.data` property should be used. - Set the `shared_memory` parameter to `True` during constant creation to avoid copying the constant. ### Reason for changes - The `const_od.get_data()` method copies constant. - Do not copy the constant value during constant creation in `opset.constant(...)`. ### Related tickets Ref: 122922 ### Tests N/A --------- Co-authored-by: Nikita Malinin --- nncf/openvino/graph/model_transformer.py | 9 ++++++--- nncf/openvino/graph/node_utils.py | 2 +- .../native/quantization/test_fq_params_calculation.py | 8 ++++---- tests/openvino/native/test_model_transformer.py | 10 +++++----- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/nncf/openvino/graph/model_transformer.py b/nncf/openvino/graph/model_transformer.py index 4c9850738ff..bfb7bc1b258 100644 --- a/nncf/openvino/graph/model_transformer.py +++ b/nncf/openvino/graph/model_transformer.py @@ -354,9 +354,12 @@ def _set_const_value(node_with_const: ov.Node, const_port_id: int, const_value: if const_node is None: raise RuntimeError("Constant node was expected but could not find it.") - const_shape = const_node.get_data().shape - const_value = np.reshape(const_value, const_shape) - new_const_node = opset.constant(const_value, dtype=const_node.get_element_type()) + const_shape = const_node.data.shape + const_dtype = const_node.data.dtype + const_value = np.reshape(const_value, const_shape).astype(const_dtype) + + # TODO(andrey-churkin): Replace on opset13.constant() in a future release + new_const_node = ov.op.Constant(const_value, shared_memory=True) new_const_node.set_friendly_name(const_node.get_friendly_name()) const_port.replace_source_output(new_const_node.output(0)) diff --git a/nncf/openvino/graph/node_utils.py b/nncf/openvino/graph/node_utils.py index 33efa0e1de2..6905e80f9c5 100644 --- a/nncf/openvino/graph/node_utils.py +++ b/nncf/openvino/graph/node_utils.py @@ -78,7 +78,7 @@ def get_const_value(const_node: ov.Node) -> np.ndarray: :param const_node: OpenVINO node. :return: The constant value. """ - return const_node.get_vector().reshape(const_node.get_output_shape(0)) + return const_node.data def get_bias_value(node_with_bias: NNCFNode, nncf_graph: NNCFGraph, model: ov.Model) -> np.ndarray: diff --git a/tests/openvino/native/quantization/test_fq_params_calculation.py b/tests/openvino/native/quantization/test_fq_params_calculation.py index 7d6358f5402..09ba5841051 100644 --- a/tests/openvino/native/quantization/test_fq_params_calculation.py +++ b/tests/openvino/native/quantization/test_fq_params_calculation.py @@ -42,10 +42,10 @@ def get_fq_nodes_stats_algo(model): nodes = {} for op in model.get_ops(): if op.get_type_name() == "FakeQuantize": - input_low = op.input_value(1).get_node().get_data() - input_high = op.input_value(2).get_node().get_data() - output_low = op.input_value(3).get_node().get_data() - output_high = op.input_value(4).get_node().get_data() + input_low = op.input_value(1).get_node().data + input_high = op.input_value(2).get_node().data + output_low = op.input_value(3).get_node().data + output_high = op.input_value(4).get_node().data nodes[op.get_friendly_name()] = { "input_low": input_low, diff --git a/tests/openvino/native/test_model_transformer.py b/tests/openvino/native/test_model_transformer.py index febcb0a3036..3fd9aa57004 100644 --- a/tests/openvino/native/test_model_transformer.py +++ b/tests/openvino/native/test_model_transformer.py @@ -182,13 +182,13 @@ def check_inplace_op(target_node, ref_types, ref_vals, inplace_branches_num, out if ref_val is not None: const = get_prev_node(node, 1) if ref_val == []: - assert const.get_data().shape == (0,) + assert const.data.shape == (0,) elif not isinstance(ref_val, tuple): - assert const.get_data() == ref_val + assert const.data == ref_val else: - res = np.equal(const.get_data(), np.array(ref_val)) + res = np.equal(const.data, np.array(ref_val)) assert all(res) - assert const.get_data().shape == np.array(ref_val).shape + assert const.data.shape == np.array(ref_val).shape nodes = get_next_nodes(node, 0) assert len(nodes) == 1 @@ -296,7 +296,7 @@ def test_inplace_reduce_fn_dynamic_shapes(input_shape, raise_error): op = fn(input_1, 0) # check_const ref_const = np.array([0, 1, 2, 3]) - assert all(np.equal(get_prev_node(op, 1).get_data(), ref_const)) + assert all(np.equal(get_prev_node(op, 1).data, ref_const)) @pytest.mark.parametrize("reduction_axes", [None, np.array([], dtype=np.int64)])