diff --git a/src/bindings/python/src/openvino/runtime/opset15/__init__.py b/src/bindings/python/src/openvino/runtime/opset15/__init__.py index 3cecb6e5e03540..d7040d974c1ab9 100644 --- a/src/bindings/python/src/openvino/runtime/opset15/__init__.py +++ b/src/bindings/python/src/openvino/runtime/opset15/__init__.py @@ -7,4 +7,6 @@ # TODO (ticket 138273): Add previous opset operators at the end of opset15 development from openvino.runtime.opset1.ops import parameter from openvino.runtime.opset15.ops import col2im +from openvino.runtime.opset15.ops import embedding_bag_offsets +from openvino.runtime.opset15.ops import embedding_bag_packed from openvino.runtime.opset15.ops import scatter_nd_update diff --git a/src/bindings/python/src/openvino/runtime/opset15/ops.py b/src/bindings/python/src/openvino/runtime/opset15/ops.py index 2b7406099c71ba..5613de6bd8267a 100644 --- a/src/bindings/python/src/openvino/runtime/opset15/ops.py +++ b/src/bindings/python/src/openvino/runtime/opset15/ops.py @@ -4,9 +4,12 @@ """Factory functions for ops added to openvino opset15.""" from functools import partial -from typing import Optional, Literal, List +from typing import List, Literal, Optional +import numpy as np from openvino.runtime import Node, Type +from openvino.runtime.opset1 import convert_like +from openvino.runtime.opset14 import constant from openvino.runtime.opset_utils import _get_node_factory from openvino.runtime.utils.decorators import nameable_op from openvino.runtime.utils.types import NodeInput, as_nodes @@ -83,3 +86,61 @@ def col2im( "pads_end": pads_end, }, ) + + +@nameable_op +def embedding_bag_offsets( + emb_table: NodeInput, + indices: NodeInput, + offsets: NodeInput, + default_index: Optional[NodeInput] = None, + per_sample_weights: Optional[NodeInput] = None, + reduction: Literal["sum", "mean"] = "sum", + name: Optional[str] = None, +) -> Node: + """Return a node which performs sums or means of bags of embeddings without the intermediate embeddings. + + :param emb_table: Tensor containing the embedding lookup table. + :param indices: 1D Tensor with indices. + :param offsets: 1D Tensor containing the starting index positions of each bag in indices. + :param per_sample_weights: Tensor with weights for each sample. + :param default_index: Scalar containing default index in embedding table to fill empty bags. + If unset or set to -1, empty bags will be filled with 0. + Reverse indexing using negative indices is not supported. + :param reduction: String to select algorithm used to perform reduction of elements in bag. + :param name: Optional name for output node. + :return: The new node performing EmbeddingBagOffsets operation. + """ + inputs = [emb_table, indices, offsets] + if default_index is not None: + inputs.append(default_index) + elif per_sample_weights is not None: + inputs.append(convert_like(constant(np.array(-1, np.int32)), inputs[1])) + if per_sample_weights is not None: + inputs.append(per_sample_weights) + + return _get_node_factory_opset15().create("EmbeddingBagOffsets", as_nodes(*inputs, name=name), {"reduction": reduction}) + + +@nameable_op +def embedding_bag_packed( + emb_table: NodeInput, + indices: NodeInput, + per_sample_weights: Optional[NodeInput] = None, + reduction: Literal["sum", "mean"] = "sum", + name: Optional[str] = None, +) -> Node: + """Return a node which performs sums or means of "bags" of embeddings, without the intermediate embeddings. + + :param emb_table: Tensor containing the embedding lookup table. + :param indices: 2D Tensor of shape [batch, indices_per_bag] with indices. + :param per_sample_weights: Tensor of weights to be multiplied with embedding table with same shape as indices. + :param reduction: Operator to perform reduction of elements in bag. + :param name: Optional name for output node. + :return: The new node performing EmbeddingBagPacked operation. + """ + inputs = [emb_table, indices] + if per_sample_weights is not None: + inputs.append(per_sample_weights) + + return _get_node_factory_opset15().create("EmbeddingBagPacked", as_nodes(*inputs, name=name), {"reduction": reduction}) diff --git a/src/bindings/python/tests/test_graph/test_ops_embedding.py b/src/bindings/python/tests/test_graph/test_ops_embedding.py new file mode 100644 index 00000000000000..4560506df4f3b7 --- /dev/null +++ b/src/bindings/python/tests/test_graph/test_ops_embedding.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2018-2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import numpy as np +import pytest + +from openvino import Type +from openvino.runtime import opset15 + + +def test_embedding_bag_offsets_15(): + emb_table = opset15.parameter([5, 2], name="emb_table", dtype=np.float32) + indices = opset15.parameter([4], name="indices", dtype=np.int64) + offsets = opset15.parameter([3], name="offsets", dtype=np.int64) + + node = opset15.embedding_bag_offsets(emb_table, indices, offsets) + + assert node.get_type_name() == "EmbeddingBagOffsets" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [3, 2] + assert node.get_output_element_type(0) == Type.f32 + assert node.get_attributes()["reduction"] == "sum" + + +def test_embedding_bag_offsets_15_default_index(): + emb_table = opset15.parameter([5, 2], name="emb_table", dtype=np.float32) + indices = opset15.parameter([4], name="indices", dtype=np.int64) + offsets = opset15.parameter([3], name="offsets", dtype=np.int64) + default_index = opset15.parameter([], name="default_index", dtype=np.int64) + + node = opset15.embedding_bag_offsets(emb_table, indices, offsets, default_index, reduction="MeAn") + + assert node.get_type_name() == "EmbeddingBagOffsets" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [3, 2] + assert node.get_output_element_type(0) == Type.f32 + assert node.get_attributes()["reduction"] == "mean" + + +def test_embedding_bag_offsets_15_per_sample_weights(): + emb_table = opset15.parameter([5, 2], name="emb_table", dtype=np.float32) + indices = opset15.parameter([4], name="indices", dtype=np.int64) + offsets = opset15.parameter([3], name="offsets", dtype=np.int64) + per_sample_weights = opset15.parameter([4], name="per_sample_weights", dtype=np.float32) + + node = opset15.embedding_bag_offsets(emb_table, indices, offsets, per_sample_weights=per_sample_weights, reduction="SUM") + + assert node.get_type_name() == "EmbeddingBagOffsets" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [3, 2] + assert node.get_output_element_type(0) == Type.f32 + assert node.get_attributes()["reduction"] == "sum" + + +def test_embedding_bag_offsets_15_default_index_per_sample_weights(): + emb_table = opset15.parameter([5, 2], name="emb_table", dtype=np.float32) + indices = opset15.parameter([4], name="indices", dtype=np.int64) + offsets = opset15.parameter([3], name="offsets", dtype=np.int64) + default_index = opset15.parameter([], name="default_index", dtype=np.int64) + per_sample_weights = opset15.parameter([4], name="per_sample_weights", dtype=np.float32) + + node = opset15.embedding_bag_offsets(emb_table, indices, offsets, default_index, per_sample_weights, "sum") + + assert node.get_type_name() == "EmbeddingBagOffsets" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [3, 2] + assert node.get_output_element_type(0) == Type.f32 + assert node.get_attributes()["reduction"] == "sum" + + +def test_embedding_bag_packed_15(): + emb_table = opset15.parameter([5, 2], name="emb_table", dtype=np.float32) + indices = opset15.parameter([3, 3], name="indices", dtype=np.int64) + + node = opset15.embedding_bag_packed(emb_table, indices, reduction="mEaN") + + assert node.get_type_name() == "EmbeddingBagPacked" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [3, 2] + assert node.get_output_element_type(0) == Type.f32 + assert node.get_attributes()["reduction"] == "mean" + + +def test_embedding_bag_packed_15_per_sample_weights(): + emb_table = opset15.parameter([5, 2], name="emb_table", dtype=np.float32) + indices = opset15.parameter([3, 3], name="indices", dtype=np.int64) + per_sample_weights = opset15.parameter([3, 3], name="per_sample_weights", dtype=np.float32) + + node = opset15.embedding_bag_packed(emb_table, indices, per_sample_weights) + + assert node.get_type_name() == "EmbeddingBagPacked" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [3, 2] + assert node.get_output_element_type(0) == Type.f32 + assert node.get_attributes()["reduction"] == "sum" diff --git a/src/common/snippets/src/lowered/pass/insert_load_store.cpp b/src/common/snippets/src/lowered/pass/insert_load_store.cpp index 27a2b6e2d36174..309708966de01d 100644 --- a/src/common/snippets/src/lowered/pass/insert_load_store.cpp +++ b/src/common/snippets/src/lowered/pass/insert_load_store.cpp @@ -58,7 +58,9 @@ bool InsertLoadStore::insert_store(LinearIR& linear_ir, const LinearIR::constExp const auto& loop_ids = parent_expr->get_loop_ids(); const auto store = std::make_shared(parent->output(port), get_count(data_expr->get_input_port(0))); - const auto& insertion_pos = linear_ir.find_after(std::reverse_iterator(data_expr_it), parent_expr).base(); + const auto insertion_it = + linear_ir.find_after(std::reverse_iterator(data_expr_it), parent_expr); + const auto& insertion_pos = insertion_it.base(); linear_ir.insert_node(store, std::vector{ parent_output }, loop_ids, true, insertion_pos, { data_expr->get_input_port(0) }); return true; } diff --git a/src/core/include/openvino/core/node_input.hpp b/src/core/include/openvino/core/node_input.hpp index b151a92a7353f0..884ff85bebb9d7 100644 --- a/src/core/include/openvino/core/node_input.hpp +++ b/src/core/include/openvino/core/node_input.hpp @@ -38,15 +38,15 @@ class OPENVINO_API Input { /// \return The index of the input referred to by this input handle. size_t get_index() const; /// \return The element type of the input referred to by this input handle. - const element::Type& get_element_type() const; + OV_NO_DANGLING const element::Type& get_element_type() const; /// \return The shape of the input referred to by this input handle. - const Shape& get_shape() const; + OV_NO_DANGLING const Shape& get_shape() const; /// \return The partial shape of the input referred to by this input handle. - const PartialShape& get_partial_shape() const; + OV_NO_DANGLING const PartialShape& get_partial_shape() const; /// \return A handle to the output that is connected to this input. Output get_source_output() const; /// \return A reference to the tensor descriptor for this input. - descriptor::Tensor& get_tensor() const; + OV_NO_DANGLING descriptor::Tensor& get_tensor() const; /// \return A shared pointer to the tensor descriptor for this input. std::shared_ptr get_tensor_ptr() const; /// \return true if this input is relevant to its node's output shapes; else false. @@ -61,7 +61,7 @@ class OPENVINO_API Input { /// \return The reference to runtime info map RTMap& get_rt_info(); /// \return The constant reference to runtime info map - const RTMap& get_rt_info() const; + OV_NO_DANGLING const RTMap& get_rt_info() const; bool operator==(const Input& other) const; bool operator!=(const Input& other) const; @@ -90,15 +90,15 @@ class OPENVINO_API Input { /// \return The index of the input referred to by this input handle. size_t get_index() const; /// \return The element type of the input referred to by this input handle. - const element::Type& get_element_type() const; + OV_NO_DANGLING const element::Type& get_element_type() const; /// \return The shape of the input referred to by this input handle. - const Shape& get_shape() const; + OV_NO_DANGLING const Shape& get_shape() const; /// \return The partial shape of the input referred to by this input handle. - const PartialShape& get_partial_shape() const; + OV_NO_DANGLING const PartialShape& get_partial_shape() const; /// \return A handle to the output that is connected to this input. Output get_source_output() const; /// \return A reference to the tensor descriptor for this input. - descriptor::Tensor& get_tensor() const; + OV_NO_DANGLING descriptor::Tensor& get_tensor() const; /// \return A shared pointer to the tensor descriptor for this input. std::shared_ptr get_tensor_ptr() const; /// \return true if this input is relevant to its node's output shapes; else false. @@ -107,7 +107,7 @@ class OPENVINO_API Input { bool get_is_relevant_to_values() const; /// \return The constant reference to runtime info map - const RTMap& get_rt_info() const; + OV_NO_DANGLING const RTMap& get_rt_info() const; bool operator==(const Input& other) const; bool operator!=(const Input& other) const; diff --git a/src/core/include/openvino/core/node_output.hpp b/src/core/include/openvino/core/node_output.hpp index d377d6a424cac2..90722efa5b57bc 100644 --- a/src/core/include/openvino/core/node_output.hpp +++ b/src/core/include/openvino/core/node_output.hpp @@ -61,25 +61,25 @@ class OPENVINO_API Output { /// \return The index of the output referred to by this output handle. size_t get_index() const; /// \return A reference to the tensor descriptor for this output. - descriptor::Tensor& get_tensor() const; + OV_NO_DANGLING descriptor::Tensor& get_tensor() const; /// \return A shared point to the tensor ptr for this output. std::shared_ptr get_tensor_ptr() const; /// \return Set new tensor desc shared pointer to this output void set_tensor_ptr(std::shared_ptr tensor_ptr); /// \return The element type of the output referred to by this output handle. - const element::Type& get_element_type() const; + OV_NO_DANGLING const element::Type& get_element_type() const; /// \return The shape of the output referred to by this output handle. - const Shape& get_shape() const; + OV_NO_DANGLING const Shape& get_shape() const; /// \return The partial shape of the output referred to by this output handle. - const PartialShape& get_partial_shape() const; + OV_NO_DANGLING const PartialShape& get_partial_shape() const; /// \return The reference to runtime info map RTMap& get_rt_info(); /// \return The constant reference to runtime info map - const RTMap& get_rt_info() const; + OV_NO_DANGLING const RTMap& get_rt_info() const; /// \return The tensor names associated with this output - const std::unordered_set& get_names() const; + OV_NO_DANGLING const std::unordered_set& get_names() const; /// \return Any tensor names associated with this output std::string get_any_name() const; /// \return Set tensor names associated with this output @@ -149,20 +149,20 @@ class OPENVINO_API Output { /// \return The index of the output referred to by this output handle. size_t get_index() const; /// \return A reference to the tensor descriptor for this output. - descriptor::Tensor& get_tensor() const; + OV_NO_DANGLING descriptor::Tensor& get_tensor() const; /// \return A shared point to the tensor ptr for this output. std::shared_ptr get_tensor_ptr() const; /// \return The element type of the output referred to by this output handle. - const element::Type& get_element_type() const; + OV_NO_DANGLING const element::Type& get_element_type() const; /// \return The shape of the output referred to by this output handle. - const Shape& get_shape() const; + OV_NO_DANGLING const Shape& get_shape() const; /// \return The partial shape of the output referred to by this output handle. - const PartialShape& get_partial_shape() const; + OV_NO_DANGLING const PartialShape& get_partial_shape() const; /// \return The constant reference to runtime info map - const RTMap& get_rt_info() const; + OV_NO_DANGLING const RTMap& get_rt_info() const; /// \return The tensor names associated with this output - const std::unordered_set& get_names() const; + OV_NO_DANGLING const std::unordered_set& get_names() const; /// \return Any tensor name associated with this output std::string get_any_name() const; /// \return A set containing handles for all inputs targeted by the output referenced by diff --git a/src/core/include/openvino/core/visibility.hpp b/src/core/include/openvino/core/visibility.hpp index dd1723a98b5948..bcce8a0736bdc1 100644 --- a/src/core/include/openvino/core/visibility.hpp +++ b/src/core/include/openvino/core/visibility.hpp @@ -67,3 +67,13 @@ # define OPENVINO_ARCH_RISCV64 # define OPENVINO_ARCH_64_BIT #endif + +/** + * @brief Define no dangling attribute. + * Use it as C++ attribute e.g. OV_NO_DANGLING void my_func(); + */ +#if defined(__GNUC__) && (__GNUC__ >= 14) +# define OV_NO_DANGLING [[gnu::no_dangling]] +#else +# define OV_NO_DANGLING +#endif diff --git a/src/core/tests/type_prop/interpolate.cpp b/src/core/tests/type_prop/interpolate.cpp index 50c4cf789e5b2d..95cdbfc265e835 100644 --- a/src/core/tests/type_prop/interpolate.cpp +++ b/src/core/tests/type_prop/interpolate.cpp @@ -119,8 +119,8 @@ TEST(type_prop, interpolate_v4_default_ctor) { attrs.coordinate_transformation_mode = CoordinateTransformMode::HALF_PIXEL; attrs.nearest_mode = Nearest_mode::ROUND_PREFER_FLOOR; attrs.antialias = false; - attrs.pads_begin = {0, 0, 0, 0}; - attrs.pads_end = {0, 0, 0, 0}; + attrs.pads_begin = std::vector{0, 0, 0, 0}; + attrs.pads_end = std::vector{0, 0, 0, 0}; attrs.cube_coeff = -0.75; auto interp = std::make_shared(); diff --git a/src/frontends/tensorflow/src/variables_index.cpp b/src/frontends/tensorflow/src/variables_index.cpp index 746604e1567c06..778f8b2f94bb7c 100644 --- a/src/frontends/tensorflow/src/variables_index.cpp +++ b/src/frontends/tensorflow/src/variables_index.cpp @@ -190,7 +190,7 @@ bool VariablesIndex::read_variables(std::ifstream& vi_stream, const std::string& read_variables_index(vi_stream, m_variables_index); read_bundle_header(); - std::vector suffix(20); + std::vector suffix(32); for (int32_t shard = 0; shard < m_total_shards; ++shard) { std::snprintf(suffix.data(), suffix.size(), "data-%05d-of-%05d", shard, m_total_shards); std::string fullPath; diff --git a/src/plugins/intel_gpu/src/plugin/transformations/swiglu_fusion.cpp b/src/plugins/intel_gpu/src/plugin/transformations/swiglu_fusion.cpp index 7da7e74a0aac6f..a8aeff17a8a25b 100644 --- a/src/plugins/intel_gpu/src/plugin/transformations/swiglu_fusion.cpp +++ b/src/plugins/intel_gpu/src/plugin/transformations/swiglu_fusion.cpp @@ -79,6 +79,8 @@ SwiGLUFusion::SwiGLUFusion() { size_t split_in_idx = ov::is_type(mul->get_input_node_shared_ptr(0)) ? 1 : 0; if (mul->input_value(split_in_idx).get_index() == split_to_glu_idx) return false; + } else { + OPENVINO_THROW("'glu_type' not initialized"); } auto variadic_split = std::dynamic_pointer_cast(pattern_map.at(variadic_split_m).get_node_shared_ptr()); diff --git a/src/tests/functional/plugin/shared/include/behavior/ov_plugin/core_integration_sw.hpp b/src/tests/functional/plugin/shared/include/behavior/ov_plugin/core_integration_sw.hpp index f66946fee69e0d..3ef772c8bc12f5 100644 --- a/src/tests/functional/plugin/shared/include/behavior/ov_plugin/core_integration_sw.hpp +++ b/src/tests/functional/plugin/shared/include/behavior/ov_plugin/core_integration_sw.hpp @@ -116,7 +116,8 @@ TEST(OVClassBasicPropsTest, smoke_SetConfigAutoNoThrows) { ov::Core core; // priority config test - ov::hint::Priority value; + // initialize, gcc 14.1 reports maybe-uninitialized at line 123 because of test macro at line 122 + ov::hint::Priority value{}; OV_ASSERT_NO_THROW(core.set_property(ov::test::utils::DEVICE_AUTO, ov::hint::model_priority(ov::hint::Priority::LOW))); OV_ASSERT_NO_THROW(value = core.get_property(ov::test::utils::DEVICE_AUTO, ov::hint::model_priority)); EXPECT_EQ(value, ov::hint::Priority::LOW); @@ -151,4 +152,4 @@ TEST_P(OVClassModelOptionalTestP, getVersionsNonEmpty) { } // namespace behavior } // namespace test -} // namespace ov \ No newline at end of file +} // namespace ov