[Opset15] Implementation for EmbeddingBagPacked and EmbeddingBagOffsets ops (#24541)
### Details: - *Create PoC implementation for EmbeddingBag Offsets and Packed that introduce mode 'mean'* - *Add Core, Reference and CPU implementation for both ops* Specification will be added in separate PR ### Tickets: - *138229* --------- Co-authored-by: Michal Lukaszewski <michal.lukaszewski@intel.com>
This commit is contained in:
parent
6556567bdd
commit
23b54736e4
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/pass/graph_rewrite.hpp"
|
||||
#include "transformations_visibility.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace pass {
|
||||
/**
|
||||
* @ingroup ov_transformation_common_api
|
||||
* @brief Converts EmbeddingBagOffsets v15 to EmbeddingBagOffsets v3.
|
||||
*/
|
||||
class TRANSFORMATIONS_API ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3 : public MatcherPass {
|
||||
public:
|
||||
OPENVINO_RTTI("ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3", "0");
|
||||
ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3();
|
||||
};
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/pass/graph_rewrite.hpp"
|
||||
#include "transformations_visibility.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace pass {
|
||||
/**
|
||||
* @ingroup ov_transformation_common_api
|
||||
* @brief Converts EmbeddingBagPacked v15 to EmbeddingBagPacked v3.
|
||||
*/
|
||||
class TRANSFORMATIONS_API ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3 : public MatcherPass {
|
||||
public:
|
||||
OPENVINO_RTTI("ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3", "0");
|
||||
ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3();
|
||||
};
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ov
|
||||
|
|
@ -73,6 +73,8 @@
|
|||
#include "transformations/op_conversions/convert_deformable_conv_v8_to_v1.hpp"
|
||||
#include "transformations/op_conversions/convert_depth_to_space.hpp"
|
||||
#include "transformations/op_conversions/convert_divide.hpp"
|
||||
#include "transformations/op_conversions/convert_embedding_bag_offsets15_downgrade.hpp"
|
||||
#include "transformations/op_conversions/convert_embedding_bag_packed15_downgrade.hpp"
|
||||
#include "transformations/op_conversions/convert_gather_downgrade.hpp"
|
||||
#include "transformations/op_conversions/convert_gather_upgrade.hpp"
|
||||
#include "transformations/op_conversions/convert_gelu.hpp"
|
||||
|
|
@ -224,6 +226,8 @@ bool ov::pass::CommonOptimizations::run_on_model(const std::shared_ptr<ov::Model
|
|||
REGISTER_PASS(manager, ConvertScatterElementsUpdate12ToScatterElementsUpdate3)
|
||||
REGISTER_PASS(manager, ConcatFusion)
|
||||
REGISTER_PASS(manager, ConvertAvgPool14ToAvgPool1)
|
||||
REGISTER_PASS(manager, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3)
|
||||
REGISTER_PASS(manager, ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3)
|
||||
|
||||
auto fq_fusions = manager.register_pass<GraphRewrite>();
|
||||
ADD_MATCHER(fq_fusions, FakeQuantizeMulFusion)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_embedding_bag_offsets15_downgrade.hpp"
|
||||
|
||||
#include "itt.hpp"
|
||||
#include "openvino/core/rt_info.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets_sum.hpp"
|
||||
#include "openvino/pass/pattern/op/wrap_type.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3::
|
||||
ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3() {
|
||||
MATCHER_SCOPE(ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3);
|
||||
|
||||
const auto emb_v15_pattern = pattern::wrap_type<ov::op::v15::EmbeddingBagOffsets>();
|
||||
|
||||
const matcher_pass_callback callback = [OV_CAPTURE_CPY_AND_THIS](pattern::Matcher& m) {
|
||||
const auto emb_v15 = std::dynamic_pointer_cast<ov::op::v15::EmbeddingBagOffsets>(m.get_match_root());
|
||||
if (!emb_v15 || transformation_callback(emb_v15) ||
|
||||
emb_v15->get_reduction() != ov::op::v15::EmbeddingBagOffsets::Reduction::SUM) {
|
||||
return false;
|
||||
}
|
||||
std::shared_ptr<ov::op::v3::EmbeddingBagOffsetsSum> emb_v3;
|
||||
if (emb_v15->get_input_size() == 3) {
|
||||
emb_v3 = std::make_shared<op::v3::EmbeddingBagOffsetsSum>(emb_v15->input_value(0),
|
||||
emb_v15->input_value(1),
|
||||
emb_v15->input_value(2));
|
||||
} else if (emb_v15->get_input_size() == 4) {
|
||||
emb_v3 = std::make_shared<op::v3::EmbeddingBagOffsetsSum>(emb_v15->input_value(0),
|
||||
emb_v15->input_value(1),
|
||||
emb_v15->input_value(2),
|
||||
emb_v15->input_value(3));
|
||||
} else if (emb_v15->get_input_size() == 5) {
|
||||
emb_v3 = std::make_shared<op::v3::EmbeddingBagOffsetsSum>(emb_v15->input_value(0),
|
||||
emb_v15->input_value(1),
|
||||
emb_v15->input_value(2),
|
||||
emb_v15->input_value(3),
|
||||
emb_v15->input_value(4));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
emb_v3->set_friendly_name(emb_v15->get_friendly_name());
|
||||
copy_runtime_info(emb_v15, emb_v3);
|
||||
replace_node(emb_v15, emb_v3);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<pattern::Matcher>(emb_v15_pattern, matcher_name);
|
||||
register_matcher(m, callback);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_embedding_bag_packed15_downgrade.hpp"
|
||||
|
||||
#include "itt.hpp"
|
||||
#include "openvino/core/rt_info.hpp"
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
#include "openvino/op/embeddingbag_packedsum.hpp"
|
||||
#include "openvino/pass/pattern/op/wrap_type.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
ov::pass::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3() {
|
||||
MATCHER_SCOPE(ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3);
|
||||
|
||||
const auto emb_v15_pattern = pattern::wrap_type<ov::op::v15::EmbeddingBagPacked>();
|
||||
|
||||
const matcher_pass_callback callback = [OV_CAPTURE_CPY_AND_THIS](pattern::Matcher& m) {
|
||||
const auto emb_v15 = std::dynamic_pointer_cast<ov::op::v15::EmbeddingBagPacked>(m.get_match_root());
|
||||
if (!emb_v15 || transformation_callback(emb_v15) ||
|
||||
emb_v15->get_reduction() != ov::op::v15::EmbeddingBagPacked::Reduction::SUM) {
|
||||
return false;
|
||||
}
|
||||
std::shared_ptr<ov::op::v3::EmbeddingBagPackedSum> emb_v3;
|
||||
if (emb_v15->get_input_size() == 2) {
|
||||
emb_v3 = std::make_shared<op::v3::EmbeddingBagPackedSum>(emb_v15->input_value(0), emb_v15->input_value(1));
|
||||
} else if (emb_v15->get_input_size() == 3) {
|
||||
emb_v3 = std::make_shared<op::v3::EmbeddingBagPackedSum>(emb_v15->input_value(0),
|
||||
emb_v15->input_value(1),
|
||||
emb_v15->input_value(2));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
emb_v3->set_friendly_name(emb_v15->get_friendly_name());
|
||||
copy_runtime_info(emb_v15, emb_v3);
|
||||
replace_node(emb_v15, emb_v3);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<pattern::Matcher>(emb_v15_pattern, matcher_name);
|
||||
register_matcher(m, callback);
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_embedding_bag_offsets15_downgrade.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "common_test_utils/ov_test_utils.hpp"
|
||||
#include "openvino/opsets/opset15.hpp"
|
||||
#include "openvino/opsets/opset3.hpp"
|
||||
#include "openvino/pass/manager.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
using namespace ov;
|
||||
using namespace testing;
|
||||
|
||||
namespace {
|
||||
|
||||
std::shared_ptr<ov::Model> create_v15_model(const op::v15::EmbeddingBagOffsets::Reduction reduction_type,
|
||||
const size_t num_inputs) {
|
||||
const auto emb_table = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{5, 2});
|
||||
const auto indices = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{4});
|
||||
const auto offsets = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{3});
|
||||
const auto default_index = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{});
|
||||
const auto per_sample_weights = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{4});
|
||||
std::shared_ptr<ov::op::v15::EmbeddingBagOffsets> emb;
|
||||
ov::ParameterVector params;
|
||||
switch (num_inputs) {
|
||||
case 0:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagOffsets>();
|
||||
params = {};
|
||||
break;
|
||||
case 3:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagOffsets>(emb_table, indices, offsets, reduction_type);
|
||||
params = {emb_table, indices, offsets};
|
||||
break;
|
||||
case 4:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
reduction_type);
|
||||
params = {emb_table, indices, offsets, default_index};
|
||||
break;
|
||||
case 5:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights,
|
||||
reduction_type);
|
||||
params = {emb_table, indices, offsets, default_index, per_sample_weights};
|
||||
break;
|
||||
}
|
||||
|
||||
emb->set_friendly_name("emb15");
|
||||
|
||||
return std::make_shared<ov::Model>(emb->outputs(), params);
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> create_v3_model(const size_t num_inputs) {
|
||||
const auto emb_table = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{5, 2});
|
||||
const auto indices = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{4});
|
||||
const auto offsets = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{3});
|
||||
const auto default_index = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{});
|
||||
const auto per_sample_weights = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{4});
|
||||
std::shared_ptr<ov::op::v3::EmbeddingBagOffsetsSum> emb;
|
||||
ov::ParameterVector params;
|
||||
switch (num_inputs) {
|
||||
case 0:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagOffsetsSum>();
|
||||
params = {};
|
||||
break;
|
||||
case 3:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagOffsetsSum>(emb_table, indices, offsets);
|
||||
params = {emb_table, indices, offsets};
|
||||
break;
|
||||
case 4:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagOffsetsSum>(emb_table, indices, offsets, default_index);
|
||||
params = {emb_table, indices, offsets, default_index};
|
||||
break;
|
||||
case 5:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagOffsetsSum>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights);
|
||||
params = {emb_table, indices, offsets, default_index, per_sample_weights};
|
||||
break;
|
||||
}
|
||||
|
||||
emb->set_friendly_name("emb3");
|
||||
|
||||
return std::make_shared<ov::Model>(emb->outputs(), params);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_sum_0) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::SUM, 0);
|
||||
model_ref = create_v3_model(0);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_sum_3) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::SUM, 3);
|
||||
model_ref = create_v3_model(3);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_sum_4) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::SUM, 4);
|
||||
model_ref = create_v3_model(4);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_sum_5) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::SUM, 5);
|
||||
model_ref = create_v3_model(5);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_mean_0) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::MEAN, 0);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_mean_3) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::MEAN, 3);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3_mean_4) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagOffsets15ToEmbeddingBagOffsetsSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagOffsets::Reduction::MEAN, 4);
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_embedding_bag_packed15_downgrade.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "common_test_utils/ov_test_utils.hpp"
|
||||
#include "openvino/opsets/opset15.hpp"
|
||||
#include "openvino/opsets/opset3.hpp"
|
||||
#include "openvino/pass/manager.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
using namespace ov;
|
||||
using namespace testing;
|
||||
|
||||
namespace {
|
||||
|
||||
std::shared_ptr<ov::Model> create_v15_model(const op::v15::EmbeddingBagPacked::Reduction reduction_type,
|
||||
const size_t num_inputs) {
|
||||
const auto emb_table = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{5, 2});
|
||||
const auto indices = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{3, 2});
|
||||
const auto per_sample_weights = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{3, 2});
|
||||
std::shared_ptr<ov::op::v15::EmbeddingBagPacked> emb;
|
||||
ov::ParameterVector params;
|
||||
switch (num_inputs) {
|
||||
case 0:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagPacked>();
|
||||
params = {};
|
||||
break;
|
||||
case 2:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagPacked>(emb_table, indices, reduction_type);
|
||||
params = {emb_table, indices};
|
||||
break;
|
||||
case 3:
|
||||
emb = std::make_shared<ov::opset15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights, reduction_type);
|
||||
params = {emb_table, indices, per_sample_weights};
|
||||
break;
|
||||
}
|
||||
|
||||
emb->set_friendly_name("emb15");
|
||||
|
||||
return std::make_shared<ov::Model>(emb->outputs(), params);
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> create_v3_model(const size_t num_inputs) {
|
||||
const auto emb_table = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{5, 2});
|
||||
const auto indices = std::make_shared<ov::opset15::Parameter>(ov::element::i32, ov::Shape{3, 2});
|
||||
const auto per_sample_weights = std::make_shared<ov::opset15::Parameter>(ov::element::f32, ov::Shape{3, 2});
|
||||
std::shared_ptr<ov::op::v3::EmbeddingBagPackedSum> emb;
|
||||
ov::ParameterVector params;
|
||||
switch (num_inputs) {
|
||||
case 0:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagPackedSum>();
|
||||
params = {};
|
||||
break;
|
||||
case 2:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagPackedSum>(emb_table, indices);
|
||||
params = {emb_table, indices};
|
||||
break;
|
||||
case 3:
|
||||
emb = std::make_shared<ov::opset3::EmbeddingBagPackedSum>(emb_table, indices, per_sample_weights);
|
||||
params = {emb_table, indices, per_sample_weights};
|
||||
break;
|
||||
}
|
||||
|
||||
emb->set_friendly_name("emb3");
|
||||
|
||||
return std::make_shared<ov::Model>(emb->outputs(), params);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3_sum_0) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagPacked::Reduction::SUM, 0);
|
||||
model_ref = create_v3_model(0);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3_sum_2) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagPacked::Reduction::SUM, 2);
|
||||
model_ref = create_v3_model(2);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3_sum_3) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagPacked::Reduction::SUM, 3);
|
||||
model_ref = create_v3_model(3);
|
||||
comparator.enable(FunctionsComparator::CmpValues::CONST_VALUES);
|
||||
comparator.enable(FunctionsComparator::CmpValues::ATTRIBUTES);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3_mean_0) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagPacked::Reduction::MEAN, 0);
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3_mean_2) {
|
||||
manager.register_pass<ov::pass::ConvertEmbeddingBagPacked15ToEmbeddingBagPackedSum3>();
|
||||
model = create_v15_model(op::v15::EmbeddingBagPacked::Reduction::MEAN, 2);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/axis_set.hpp"
|
||||
#include "openvino/op/util/embeddingbag_offsets_base.hpp"
|
||||
#include "openvino/op/util/index_reduction.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v15 {
|
||||
/// \brief Returns embeddings for given indices
|
||||
/// \ingroup ov_ops_cpp_api
|
||||
class OPENVINO_API EmbeddingBagOffsets : public util::EmbeddingBagOffsetsBase {
|
||||
public:
|
||||
OPENVINO_OP("EmbeddingBagOffsets", "opset15", util::EmbeddingBagOffsetsBase);
|
||||
/// \brief Constructs a EmbeddingBagOffsets operation.
|
||||
EmbeddingBagOffsets() = default;
|
||||
/// \brief Constructs a EmbeddingBagOffsets operation.
|
||||
///
|
||||
/// EmbeddingBagOffsets constructs an output tensor by replacing every index in a
|
||||
/// given
|
||||
/// input tensor with a row (from the weights matrix) at that index
|
||||
///
|
||||
/// \param emb_table tensor containing the embedding lookup table of the module of
|
||||
/// shape [num_emb, emb_dim1, emb_dim2, ...] and of type T
|
||||
/// \param indices tensor of shape [num_indices] and of type T_IND. Required
|
||||
/// \param offsets tensor of shape [batch] and of type T_IND containing the starting
|
||||
/// index positions of each "bag" in indices. Required.
|
||||
/// \param default_index scalar of type T_IND containing default index in embedding
|
||||
/// table to fill empty "bags". If not provided empty "bags"
|
||||
/// are filled with zeros. Optional.
|
||||
/// \param per_sample_weigths tensor of the same shape as indices and of type T.
|
||||
/// Each value in this tensor are multiplied with each
|
||||
/// value pooled from embedding table for each index. Optional.
|
||||
|
||||
EmbeddingBagOffsets(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction = Reduction::SUM);
|
||||
|
||||
EmbeddingBagOffsets(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Reduction& reduction = Reduction::SUM);
|
||||
|
||||
EmbeddingBagOffsets(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Reduction& reduction = Reduction::SUM);
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
};
|
||||
} // namespace v15
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
|
|
@ -32,7 +32,7 @@ public:
|
|||
/// \param default_index scalar of type T_IND containing default index in embedding
|
||||
/// table to fill empty "bags". If not provided empty "bags"
|
||||
/// are filled with zeros. Optional.
|
||||
/// \param per_sample_weigths tensor of the same shape as indices and of type T.
|
||||
/// \param per_sample_weights tensor of the same shape as indices and of type T.
|
||||
/// Each value in this tensor are multiplied with each
|
||||
/// value pooled from embedding table for each index. Optional.
|
||||
|
||||
|
|
@ -50,6 +50,8 @@ public:
|
|||
EmbeddingBagOffsetsSum(const Output<Node>& emb_table, const Output<Node>& indices, const Output<Node>& offsets);
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
};
|
||||
} // namespace v3
|
||||
} // namespace op
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/axis_set.hpp"
|
||||
#include "openvino/op/util/embeddingbag_packed_base.hpp"
|
||||
#include "openvino/op/util/index_reduction.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v15 {
|
||||
/// \brief Returns embeddings for given indices
|
||||
/// \ingroup ov_ops_cpp_api
|
||||
class OPENVINO_API EmbeddingBagPacked : public util::EmbeddingBagPackedBase {
|
||||
public:
|
||||
OPENVINO_OP("EmbeddingBagPacked", "opset15", util::EmbeddingBagPackedBase);
|
||||
/// \brief Constructs a EmbeddingBagPacked operation.
|
||||
EmbeddingBagPacked() = default;
|
||||
/// \brief Constructs a EmbeddingBagPacked operation.
|
||||
///
|
||||
/// EmbeddingBagPacked constructs an output tensor by replacing every index in a
|
||||
/// given
|
||||
/// input tensor with a row (from the weights matrix) at that index
|
||||
///
|
||||
/// \param emb_table Tensor containing the embedding lookup table of the module of
|
||||
/// shape [num_emb, emb_dim1, emb_dim2, ...] and of type T
|
||||
/// \param indices Tensor of shape `[batch, indices_per_bag]` and of type *T_IND*.
|
||||
/// Required.
|
||||
/// \param per_sample_weigths tensor of the same shape as indices and of type T.
|
||||
/// Each value in this tensor are multiplied with each
|
||||
/// value pooled from embedding table for each index. Optional.
|
||||
|
||||
EmbeddingBagPacked(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction = Reduction::SUM);
|
||||
|
||||
EmbeddingBagPacked(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Reduction& reduction = Reduction::SUM);
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
};
|
||||
} // namespace v15
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
|
|
@ -39,6 +39,8 @@ public:
|
|||
EmbeddingBagPackedSum(const Output<Node>& emb_table, const Output<Node>& indices);
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
};
|
||||
} // namespace v3
|
||||
} // namespace op
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@
|
|||
#include "openvino/op/einsum.hpp"
|
||||
#include "openvino/op/elu.hpp"
|
||||
#include "openvino/op/embedding_segments_sum.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets_sum.hpp"
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
#include "openvino/op/embeddingbag_packedsum.hpp"
|
||||
#include "openvino/op/equal.hpp"
|
||||
#include "openvino/op/erf.hpp"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ namespace util {
|
|||
class OPENVINO_API EmbeddingBagOffsetsBase : public Op {
|
||||
public:
|
||||
OPENVINO_OP("EmbeddingBagOffsetsBase", "util");
|
||||
|
||||
enum class Reduction { SUM, MEAN };
|
||||
|
||||
/// \brief Constructs a EmbeddingBagOffsetsBase operation.
|
||||
EmbeddingBagOffsetsBase() = default;
|
||||
/// \brief Constructs a EmbeddingBagOffsetsBase operation.
|
||||
|
|
@ -28,13 +31,12 @@ public:
|
|||
/// \param indices tensor of shape [num_indices] and of type T_IND. Required
|
||||
/// \param offsets tensor of shape [batch] and of type T_IND containing the starting
|
||||
/// index positions of each "bag" in indices. Required.
|
||||
/// \param per_sample_weigths tensor of the same shape as indices and of type T.
|
||||
/// \param per_sample_weights tensor of the same shape as indices and of type T.
|
||||
/// Each value in this tensor are multiplied with each
|
||||
/// value pooled from embedding table for each index. Optional.
|
||||
/// \param default_index scalar of type T_IND containing default index in embedding
|
||||
/// table to fill empty "bags". If not provided empty "bags"
|
||||
/// are filled with zeros. Optional.
|
||||
|
||||
EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
|
|
@ -48,16 +50,53 @@ public:
|
|||
|
||||
EmbeddingBagOffsetsBase(const Output<Node>& emb_table, const Output<Node>& indices, const Output<Node>& offsets);
|
||||
|
||||
EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction);
|
||||
|
||||
EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Reduction& reduction);
|
||||
|
||||
EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Reduction& reduction);
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
const Reduction& get_reduction() {
|
||||
return m_reduction;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int EMB_TABLE = 0;
|
||||
static constexpr int INDICES = 1;
|
||||
static constexpr int OFFSETS = 2;
|
||||
static constexpr int DEFAULT_INDEX = 3;
|
||||
static constexpr int PER_SAMPLE_WEIGHTS = 4;
|
||||
|
||||
protected:
|
||||
Reduction m_reduction = Reduction::SUM;
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace op
|
||||
template <>
|
||||
class OPENVINO_API AttributeAdapter<op::util::EmbeddingBagOffsetsBase::Reduction>
|
||||
: public EnumAttributeAdapterBase<op::util::EmbeddingBagOffsetsBase::Reduction> {
|
||||
public:
|
||||
AttributeAdapter(op::util::EmbeddingBagOffsetsBase::Reduction& value)
|
||||
: EnumAttributeAdapterBase<op::util::EmbeddingBagOffsetsBase::Reduction>(value) {}
|
||||
|
||||
OPENVINO_RTTI("AttributeAdapter<ov::op::util::EmbeddingBagOffsetsBase::Reduction>");
|
||||
};
|
||||
|
||||
OPENVINO_API
|
||||
std::ostream& operator<<(std::ostream& s, const op::util::EmbeddingBagOffsetsBase::Reduction& reduction);
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace util {
|
|||
/// \brief Returns embeddings for given indices
|
||||
class OPENVINO_API EmbeddingBagPackedBase : public Op {
|
||||
public:
|
||||
enum class Reduction { SUM, MEAN };
|
||||
OPENVINO_OP("EmbeddingBagPackedBase", "util");
|
||||
/// \brief Constructs a EmbeddingBagPackedBase operation.
|
||||
EmbeddingBagPackedBase() = default;
|
||||
|
|
@ -26,24 +27,49 @@ public:
|
|||
/// shape [num_emb, emb_dim1, emb_dim2, ...] and of type T
|
||||
/// \param indices Tensor of shape `[batch, indices_per_bag]` and of type *T_IND*.
|
||||
/// Required.
|
||||
/// \param per_sample_weigths tensor of the same shape as indices and of type T.
|
||||
/// \param per_sample_weights tensor of the same shape as indices and of type T.
|
||||
/// Each value in this tensor are multiplied with each
|
||||
/// value pooled from embedding table for each index. Optional.
|
||||
|
||||
EmbeddingBagPackedBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& per_sample_weights);
|
||||
|
||||
EmbeddingBagPackedBase(const Output<Node>& emb_table, const Output<Node>& indices);
|
||||
|
||||
EmbeddingBagPackedBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction);
|
||||
|
||||
EmbeddingBagPackedBase(const Output<Node>& emb_table, const Output<Node>& indices, const Reduction& reduction);
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
const Reduction& get_reduction() {
|
||||
return m_reduction;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int EMB_TABLE = 0;
|
||||
static constexpr int INDICES = 1;
|
||||
static constexpr int PER_SAMPLE_WEIGHTS = 2;
|
||||
|
||||
protected:
|
||||
Reduction m_reduction = Reduction::SUM;
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace op
|
||||
template <>
|
||||
class OPENVINO_API AttributeAdapter<op::util::EmbeddingBagPackedBase::Reduction>
|
||||
: public EnumAttributeAdapterBase<op::util::EmbeddingBagPackedBase::Reduction> {
|
||||
public:
|
||||
AttributeAdapter(op::util::EmbeddingBagPackedBase::Reduction& value)
|
||||
: EnumAttributeAdapterBase<op::util::EmbeddingBagPackedBase::Reduction>(value) {}
|
||||
|
||||
OPENVINO_RTTI("AttributeAdapter<ov::op::util::EmbeddingBagPackedBase::Reduction>");
|
||||
};
|
||||
|
||||
OPENVINO_API
|
||||
std::ostream& operator<<(std::ostream& s, const op::util::EmbeddingBagPackedBase::Reduction& reduction);
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -14,3 +14,5 @@ _OPENVINO_OP_REG(ShapeOf, ov::op::v3)
|
|||
|
||||
// New operations added in opset15
|
||||
_OPENVINO_OP_REG(ScatterNDUpdate, ov::op::v15)
|
||||
_OPENVINO_OP_REG(EmbeddingBagPacked, ov::op::v15)
|
||||
_OPENVINO_OP_REG(EmbeddingBagOffsets, ov::op::v15)
|
||||
|
|
|
|||
|
|
@ -5,18 +5,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "openvino/core/shape.hpp"
|
||||
#include "openvino/op/util/embeddingbag_offsets_base.hpp"
|
||||
#include "openvino/reference/divide.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace reference {
|
||||
template <typename T, typename U>
|
||||
void embeddingBagOffsetsSum(const T* emb_table,
|
||||
const U* indices,
|
||||
const U* offsets,
|
||||
const U* default_index,
|
||||
const T* weights,
|
||||
T* out,
|
||||
const size_t indices_count,
|
||||
const Shape& outShape) {
|
||||
void embeddingBagOffsets(const T* emb_table,
|
||||
const U* indices,
|
||||
const U* offsets,
|
||||
const U* default_index,
|
||||
const T* weights,
|
||||
T* out,
|
||||
const size_t indices_count,
|
||||
const Shape& outShape,
|
||||
ov::op::util::EmbeddingBagOffsetsBase::Reduction reduction) {
|
||||
using Reduction = ov::op::util::EmbeddingBagOffsetsBase::Reduction;
|
||||
const size_t offsets_size = outShape[0];
|
||||
std::vector<U> default_indices;
|
||||
if (default_index)
|
||||
|
|
@ -27,7 +31,6 @@ void embeddingBagOffsetsSum(const T* emb_table,
|
|||
embDepth *= outShape[i];
|
||||
}
|
||||
std::fill(out, out + shape_size(outShape), T{0});
|
||||
|
||||
auto get_indices =
|
||||
[&](size_t emb_index, const U*& indices_ref, size_t& indices_num, size_t& weights_idx, bool& with_weights) {
|
||||
if (emb_index >= offsets_size)
|
||||
|
|
@ -86,6 +89,11 @@ void embeddingBagOffsetsSum(const T* emb_table,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (reduction == Reduction::MEAN) {
|
||||
for (size_t i = 0lu; i < embDepth; i++) {
|
||||
out[dst_index + i] /= (T)indices_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5,16 +5,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "openvino/core/shape.hpp"
|
||||
#include "openvino/op/util/embeddingbag_packed_base.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace reference {
|
||||
template <typename T, typename U>
|
||||
void embeddingBagPackedSum(const T* emb_table,
|
||||
const U* indices,
|
||||
const T* weights,
|
||||
T* out,
|
||||
const Shape& indicesShape,
|
||||
const Shape& outShape) {
|
||||
void embeddingBagPacked(const T* emb_table,
|
||||
const U* indices,
|
||||
const T* weights,
|
||||
T* out,
|
||||
const Shape& indicesShape,
|
||||
const Shape& outShape,
|
||||
const ov::op::util::EmbeddingBagPackedBase::Reduction reduction) {
|
||||
using Reduction = ov::op::util::EmbeddingBagPackedBase::Reduction;
|
||||
const size_t indices_per_bag = indicesShape[1];
|
||||
|
||||
size_t embDepth = 1lu;
|
||||
|
|
@ -42,6 +45,11 @@ void embeddingBagPackedSum(const T* emb_table,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (reduction == Reduction::MEAN) {
|
||||
for (size_t i = 0lu; i < shape_size(outShape); i++) {
|
||||
out[i] /= (T)indices_per_bag;
|
||||
}
|
||||
}
|
||||
|
||||
} // embeddingBagPackedSum
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
|
||||
#include "itt.hpp"
|
||||
|
||||
namespace ov {
|
||||
|
||||
op::v15::EmbeddingBagOffsets::EmbeddingBagOffsets(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction)
|
||||
: util::EmbeddingBagOffsetsBase(emb_table, indices, offsets, default_index, per_sample_weights, reduction) {}
|
||||
|
||||
op::v15::EmbeddingBagOffsets::EmbeddingBagOffsets(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Reduction& reduction)
|
||||
: util::EmbeddingBagOffsetsBase(emb_table, indices, offsets, default_index, reduction) {}
|
||||
|
||||
op::v15::EmbeddingBagOffsets::EmbeddingBagOffsets(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Reduction& reduction)
|
||||
: util::EmbeddingBagOffsetsBase(emb_table, indices, offsets, reduction) {}
|
||||
|
||||
std::shared_ptr<Node> op::v15::EmbeddingBagOffsets::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
OV_OP_SCOPE(v15_EmbeddingBagOffsets_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
if (new_args.size() == 3) {
|
||||
return std::make_shared<op::v15::EmbeddingBagOffsets>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
m_reduction);
|
||||
} else if (new_args.size() == 4) {
|
||||
return std::make_shared<op::v15::EmbeddingBagOffsets>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
new_args.at(3),
|
||||
m_reduction);
|
||||
} else if (new_args.size() == 5) {
|
||||
return std::make_shared<op::v15::EmbeddingBagOffsets>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
new_args.at(3),
|
||||
new_args.at(4),
|
||||
m_reduction);
|
||||
} else {
|
||||
OPENVINO_THROW("Incorrect number of arguments");
|
||||
}
|
||||
}
|
||||
} // namespace ov
|
||||
|
|
@ -46,4 +46,8 @@ std::shared_ptr<Node> op::v3::EmbeddingBagOffsetsSum::clone_with_new_inputs(cons
|
|||
OPENVINO_THROW("Incorrect number of arguments");
|
||||
}
|
||||
}
|
||||
bool op::v3::EmbeddingBagOffsetsSum::visit_attributes(AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(v3_EmbeddingBagOffsetsSum_visit_attributes);
|
||||
return true;
|
||||
}
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
|
||||
#include "itt.hpp"
|
||||
|
||||
namespace ov {
|
||||
|
||||
op::v15::EmbeddingBagPacked::EmbeddingBagPacked(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction)
|
||||
: util::EmbeddingBagPackedBase(emb_table, indices, per_sample_weights, reduction) {}
|
||||
|
||||
op::v15::EmbeddingBagPacked::EmbeddingBagPacked(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Reduction& reduction)
|
||||
: util::EmbeddingBagPackedBase(emb_table, indices, reduction) {}
|
||||
|
||||
std::shared_ptr<Node> op::v15::EmbeddingBagPacked::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
OV_OP_SCOPE(v15_EmbeddingBagPacked_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
if (new_args.size() == 2) {
|
||||
return std::make_shared<op::v15::EmbeddingBagPacked>(new_args.at(0), new_args.at(1), m_reduction);
|
||||
} else if (new_args.size() == 3) {
|
||||
return std::make_shared<op::v15::EmbeddingBagPacked>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
m_reduction);
|
||||
} else {
|
||||
OPENVINO_THROW("Incorrect number of arguments");
|
||||
}
|
||||
}
|
||||
} // namespace ov
|
||||
|
|
@ -27,4 +27,8 @@ std::shared_ptr<Node> op::v3::EmbeddingBagPackedSum::clone_with_new_inputs(const
|
|||
OPENVINO_THROW("Incorrect number of arguments");
|
||||
}
|
||||
}
|
||||
bool op::v3::EmbeddingBagPackedSum::visit_attributes(AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(v3_EmbeddingBagPackedSum_visit_attributes);
|
||||
return true;
|
||||
}
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ ov::op::util::EmbeddingBagOffsetsBase::EmbeddingBagOffsetsBase(const Output<Node
|
|||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Output<Node>& per_sample_weights)
|
||||
: Op({emb_table, indices, offsets, default_index, per_sample_weights}) {
|
||||
: Op({emb_table, indices, offsets, default_index, per_sample_weights}),
|
||||
m_reduction{Reduction::SUM} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
|
|
@ -20,14 +21,46 @@ ov::op::util::EmbeddingBagOffsetsBase::EmbeddingBagOffsetsBase(const Output<Node
|
|||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index)
|
||||
: Op({emb_table, indices, offsets, default_index}) {
|
||||
: Op({emb_table, indices, offsets, default_index}),
|
||||
m_reduction{Reduction::SUM} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
ov::op::util::EmbeddingBagOffsetsBase::EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets)
|
||||
: Op({emb_table, indices, offsets}) {
|
||||
: Op({emb_table, indices, offsets}),
|
||||
m_reduction{Reduction::SUM} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
ov::op::util::EmbeddingBagOffsetsBase::EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const Reduction& reduction)
|
||||
: Op({emb_table, indices, offsets, default_index, per_sample_weights}),
|
||||
m_reduction{reduction} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
ov::op::util::EmbeddingBagOffsetsBase::EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Output<Node>& default_index,
|
||||
const Reduction& reduction)
|
||||
: Op({emb_table, indices, offsets, default_index}),
|
||||
m_reduction{reduction} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
ov::op::util::EmbeddingBagOffsetsBase::EmbeddingBagOffsetsBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& offsets,
|
||||
const Reduction& reduction)
|
||||
: Op({emb_table, indices, offsets}),
|
||||
m_reduction{reduction} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +100,9 @@ void ov::op::util::EmbeddingBagOffsetsBase::validate_and_infer_types() {
|
|||
}
|
||||
|
||||
if (get_input_size() == 5) {
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
m_reduction == Reduction::SUM,
|
||||
"Per sample weights can only be used in Reduction::SUM mode.");
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(EMB_TABLE).compatible(get_input_element_type(PER_SAMPLE_WEIGHTS)),
|
||||
"Per sample weight element type (",
|
||||
|
|
@ -83,5 +119,20 @@ void ov::op::util::EmbeddingBagOffsetsBase::validate_and_infer_types() {
|
|||
|
||||
bool ov::op::util::EmbeddingBagOffsetsBase::visit_attributes(AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(util_EmbeddingBagOffsetsBase_visit_attributes);
|
||||
visitor.on_attribute("reduction", m_reduction);
|
||||
return true;
|
||||
}
|
||||
namespace ov {
|
||||
template <>
|
||||
OPENVINO_API EnumNames<op::util::EmbeddingBagOffsetsBase::Reduction>&
|
||||
EnumNames<op::util::EmbeddingBagOffsetsBase::Reduction>::get() {
|
||||
static auto enum_names = EnumNames<op::util::EmbeddingBagOffsetsBase::Reduction>(
|
||||
"op::util::EmbeddingBagOffsetsBase::Reduction",
|
||||
{{"sum", op::util::EmbeddingBagOffsetsBase::Reduction::SUM},
|
||||
{"mean", op::util::EmbeddingBagOffsetsBase::Reduction::MEAN}});
|
||||
return enum_names;
|
||||
}
|
||||
std::ostream& operator<<(std::ostream& s, const op::util::EmbeddingBagOffsetsBase::Reduction& reduction) {
|
||||
return s << as_string(reduction);
|
||||
}
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -7,17 +7,35 @@
|
|||
#include "embeddingbag_packed_shape_inference.hpp"
|
||||
#include "itt.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ov::op::util::EmbeddingBagPackedBase::EmbeddingBagPackedBase(const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& per_sample_weights)
|
||||
: Op({emb_table, indices, per_sample_weights}) {
|
||||
: Op({emb_table, indices, per_sample_weights}),
|
||||
m_reduction{Reduction::SUM} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
ov::op::util::EmbeddingBagPackedBase::EmbeddingBagPackedBase(const Output<Node>& emb_table, const Output<Node>& indices)
|
||||
: Op({emb_table, indices}) {
|
||||
: Op({emb_table, indices}),
|
||||
m_reduction{Reduction::SUM} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
ov::op::util::EmbeddingBagPackedBase::EmbeddingBagPackedBase(
|
||||
const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& per_sample_weights,
|
||||
const ov::op::util::EmbeddingBagPackedBase::Reduction& reduction)
|
||||
: Op({emb_table, indices, per_sample_weights}),
|
||||
m_reduction{reduction} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
ov::op::util::EmbeddingBagPackedBase::EmbeddingBagPackedBase(
|
||||
const Output<Node>& emb_table,
|
||||
const Output<Node>& indices,
|
||||
const ov::op::util::EmbeddingBagPackedBase::Reduction& reduction)
|
||||
: Op({emb_table, indices}),
|
||||
m_reduction{reduction} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
|
|
@ -29,6 +47,9 @@ void ov::op::util::EmbeddingBagPackedBase::validate_and_infer_types() {
|
|||
"INDICES type must be i32 or i64");
|
||||
|
||||
if (get_input_size() == 3) {
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
m_reduction == Reduction::SUM,
|
||||
"Per sample weights can only be used in Reduction::SUM mode.");
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(EMB_TABLE).compatible(get_input_element_type(PER_SAMPLE_WEIGHTS)),
|
||||
"Per sample weight element type (",
|
||||
|
|
@ -45,5 +66,22 @@ void ov::op::util::EmbeddingBagPackedBase::validate_and_infer_types() {
|
|||
|
||||
bool ov::op::util::EmbeddingBagPackedBase::visit_attributes(AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(util_EmbeddingBagPackedBase_visit_attributes);
|
||||
visitor.on_attribute("reduction", m_reduction);
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace ov {
|
||||
std::ostream& operator<<(std::ostream& s, const op::util::EmbeddingBagPackedBase::Reduction& reduction) {
|
||||
return s << as_string(reduction);
|
||||
}
|
||||
template <>
|
||||
OPENVINO_API EnumNames<op::util::EmbeddingBagPackedBase::Reduction>&
|
||||
EnumNames<op::util::EmbeddingBagPackedBase::Reduction>::get() {
|
||||
static auto enum_names = EnumNames<op::util::EmbeddingBagPackedBase::Reduction>(
|
||||
"op::util::EmbeddingBagPackedBase::Reduction",
|
||||
{{"sum", op::util::EmbeddingBagPackedBase::Reduction::SUM},
|
||||
{"mean", op::util::EmbeddingBagPackedBase::Reduction::MEAN}});
|
||||
return enum_names;
|
||||
}
|
||||
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ INSTANTIATE_TEST_SUITE_P(opset,
|
|||
OpsetTestParams{ov::get_opset12, 178},
|
||||
OpsetTestParams{ov::get_opset13, 186},
|
||||
OpsetTestParams{ov::get_opset14, 189},
|
||||
OpsetTestParams{ov::get_opset15, 4}),
|
||||
OpsetTestParams{ov::get_opset15, 6}),
|
||||
OpsetTestNameGenerator{});
|
||||
|
||||
class MyOpOld : public ov::op::Op {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,380 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common_test_utils/test_assertions.hpp"
|
||||
#include "common_test_utils/type_prop.hpp"
|
||||
|
||||
using namespace ov;
|
||||
using namespace testing;
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_default_ctor) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2, 6});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
auto op = std::make_shared<op::v15::EmbeddingBagOffsets>();
|
||||
op->set_arguments(OutputVector{emb_table, indices, offsets, default_index, per_sample_weights});
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{3, 2, 6}));
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_reduction_mean) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto reduction = op::v15::EmbeddingBagOffsets::Reduction::MEAN;
|
||||
|
||||
auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, reduction);
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(PartialShape{3, 2}));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(indices->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(offsets->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::MEAN);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_reduction_mean_index) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
auto reduction = op::v15::EmbeddingBagOffsets::Reduction::MEAN;
|
||||
|
||||
auto embedding_bag_offsets =
|
||||
std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, default_index, reduction);
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(PartialShape{3, 2}));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(indices->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(offsets->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::MEAN);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_labeled_interval_dims) {
|
||||
auto emb_shape = PartialShape{{5, 10}, {2, 4}, {1, 3}};
|
||||
auto emb_symbols = set_shape_symbols(emb_shape);
|
||||
auto off_shape = PartialShape{{6, 8}};
|
||||
auto off_symbols = set_shape_symbols(off_shape);
|
||||
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, emb_shape);
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, PartialShape{{3, 4}});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, off_shape);
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{{3, 4}});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
auto op =
|
||||
std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, default_index, per_sample_weights);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{{6, 8}, {2, 4}, {1, 3}}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)),
|
||||
ElementsAre(off_symbols[0], emb_symbols[1], emb_symbols[2]));
|
||||
EXPECT_EQ(op->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
auto embedding_bag_offsets =
|
||||
std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, default_index, per_sample_weights);
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(PartialShape{3, 2}));
|
||||
EXPECT_TRUE(indices->get_partial_shape().same_scheme(per_sample_weights->get_partial_shape()));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(indices->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(offsets->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_dynamic_emb_table) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{5, Dimension::dynamic()});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
auto embedding_bag_offsets =
|
||||
std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, default_index, per_sample_weights);
|
||||
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(PartialShape{3, Dimension::dynamic()}));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_dynamic_offsets) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, PartialShape{Dimension::dynamic()});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
auto embedding_bag_offsets =
|
||||
std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, default_index, per_sample_weights);
|
||||
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(PartialShape{Dimension::dynamic(), 2}));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_dynamic_emb_table_offsets) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{5, Dimension::dynamic()});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, PartialShape{Dimension::dynamic()});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
auto reduction = op::v15::EmbeddingBagOffsets::Reduction::SUM;
|
||||
|
||||
auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights,
|
||||
reduction);
|
||||
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(
|
||||
PartialShape{Dimension::dynamic(), Dimension::dynamic()}));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_indices_element_type) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES type must be i32 or i64"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_offsets_element_type) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("OFFSETS type must be i32 or i64"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_default_index_element_type) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("DEFAULT_INDEX type must be i32 or i64"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_mismatch_element_type) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i32, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("Offsets element type (i64) must match indices element type (i32)"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_mismatch_element_type_1) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i32, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("Default_index element type (i32) must match indices element type (i64)"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_mismatch_element_type_2) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("Per sample weight element type (i64) must "
|
||||
"match embedding table element type (f32)"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_mismatch_shape) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES and PER_SAMPLE_WEIGHTS shape must be same"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_default_index_scalar) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{2});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("DEFAULT_INDEX must be a scalar"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_indices_1d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4, 2});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES must be 1D"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_emb_table_0d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto op = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("EMB_TABLE can't be a scalar"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_offsets_1d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 2});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("OFFSETS must be 1D"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_per_sample_weights_1d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 2});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("PER_SAMPLE_WEIGHTS must be 1D"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_per_sample_weights_reduction_mean) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 2});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
auto reduction = op::v15::EmbeddingBagOffsets::Reduction::MEAN;
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights,
|
||||
reduction),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("Per sample weights can only be used in Reduction::SUM mode"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_3_args_api) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
|
||||
auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets);
|
||||
EXPECT_TRUE(embedding_bag_offsets->get_output_partial_shape(0).same_scheme(PartialShape{3, 2}));
|
||||
EXPECT_EQ(embedding_bag_offsets->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(indices->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(offsets->get_partial_shape().rank().get_length(), 1);
|
||||
EXPECT_EQ(embedding_bag_offsets->get_reduction(), op::v15::EmbeddingBagOffsets::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_offsets_fail_indices_element_type_3_args_api) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto offsets = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3});
|
||||
|
||||
OV_EXPECT_THROW(
|
||||
auto embedding_bag_offsets = std::make_shared<op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES type must be i32 or i64"));
|
||||
}
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common_test_utils/test_assertions.hpp"
|
||||
#include "common_test_utils/type_prop.hpp"
|
||||
|
||||
using namespace ov;
|
||||
using namespace testing;
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_default_ctor) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2, 6});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
|
||||
auto op = std::make_shared<op::v15::EmbeddingBagPacked>();
|
||||
op->set_arguments(OutputVector{emb_table, indices, per_sample_weights});
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{3, 2, 6}));
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_labeled_interval_dims_2in) {
|
||||
auto emb_shape = PartialShape{{5, 10}, {2, 4}, {1, 3}};
|
||||
auto emb_symbols = set_shape_symbols(emb_shape);
|
||||
auto ind_shape = PartialShape{{6, 8}, 4};
|
||||
auto ind_symbols = set_shape_symbols(ind_shape);
|
||||
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, emb_shape);
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, ind_shape);
|
||||
|
||||
auto op = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{{6, 8}, {2, 4}, {1, 3}}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)),
|
||||
ElementsAre(ind_symbols[0], emb_symbols[1], emb_symbols[2]));
|
||||
EXPECT_EQ(op->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_labeled_interval_dims_2in_reduction) {
|
||||
auto emb_shape = PartialShape{{5, 10}, {2, 4}, {1, 3}};
|
||||
auto emb_symbols = set_shape_symbols(emb_shape);
|
||||
auto ind_shape = PartialShape{{6, 8}, 4};
|
||||
auto ind_symbols = set_shape_symbols(ind_shape);
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, emb_shape);
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, ind_shape);
|
||||
auto reduction = op::v15::EmbeddingBagPacked::Reduction::MEAN;
|
||||
|
||||
auto op = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, reduction);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{{6, 8}, {2, 4}, {1, 3}}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)),
|
||||
ElementsAre(ind_symbols[0], emb_symbols[1], emb_symbols[2]));
|
||||
EXPECT_EQ(op->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::MEAN);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_labeled_interval_dims_3in) {
|
||||
auto emb_shape = PartialShape{{5, 10}, {2, 4}, {1, 3}};
|
||||
auto emb_symbols = set_shape_symbols(emb_shape);
|
||||
auto ind_shape = PartialShape{{2, 6}, 4};
|
||||
auto ind_symbols = set_shape_symbols(ind_shape);
|
||||
auto sample_shape = PartialShape{{4, 8}, 4};
|
||||
auto sample_symbols = set_shape_symbols(sample_shape);
|
||||
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, emb_shape);
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, ind_shape);
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, sample_shape);
|
||||
|
||||
auto op = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), (PartialShape{{4, 6}, {2, 4}, {1, 3}}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)),
|
||||
ElementsAre(ind_symbols[0], emb_symbols[1], emb_symbols[2]));
|
||||
EXPECT_EQ(op->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
|
||||
auto embedding_bag_packed = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights);
|
||||
EXPECT_TRUE(embedding_bag_packed->get_output_partial_shape(0).same_scheme(PartialShape{3, 2}));
|
||||
EXPECT_TRUE(indices->get_partial_shape().same_scheme(per_sample_weights->get_partial_shape()));
|
||||
EXPECT_EQ(embedding_bag_packed->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(indices->get_partial_shape().rank().get_length(), 2);
|
||||
EXPECT_EQ(embedding_bag_packed->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_dynamic_emb_table) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{5, Dimension::dynamic()});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
auto default_index = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
|
||||
auto embedding_bag_packed = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights);
|
||||
|
||||
EXPECT_TRUE(embedding_bag_packed->get_output_partial_shape(0).same_scheme(PartialShape{3, Dimension::dynamic()}));
|
||||
EXPECT_EQ(embedding_bag_packed->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_dynamic_indices) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, PartialShape{Dimension::dynamic(), 4});
|
||||
auto per_sample_weights =
|
||||
std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{Dimension::dynamic(), 4});
|
||||
|
||||
auto embedding_bag_packed = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights);
|
||||
|
||||
EXPECT_TRUE(embedding_bag_packed->get_output_partial_shape(0).same_scheme(PartialShape{Dimension::dynamic(), 2}));
|
||||
EXPECT_EQ(embedding_bag_packed->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_dynamic_emb_table_indices) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{5, Dimension::dynamic()});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, PartialShape{Dimension::dynamic(), 4});
|
||||
auto per_sample_weights =
|
||||
std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{Dimension::dynamic(), 4});
|
||||
auto reduction = op::v15::EmbeddingBagPacked::Reduction::SUM;
|
||||
auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights, reduction);
|
||||
|
||||
EXPECT_TRUE(embedding_bag_packed->get_output_partial_shape(0).same_scheme(
|
||||
PartialShape{Dimension::dynamic(), Dimension::dynamic()}));
|
||||
EXPECT_EQ(embedding_bag_packed->get_reduction(), op::v15::EmbeddingBagPacked::Reduction::SUM);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_indices_element_type) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES type must be i32 or i64"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_mismatch_element_type) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("Per sample weight element type (i64) must "
|
||||
"match embedding table element type (f32)"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_mismatch_shape) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4, 3});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES and PER_SAMPLE_WEIGHTS shape must be same"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_indices_1d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES must be 2D"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_emb_table_0d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
|
||||
OV_EXPECT_THROW(auto op = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("EMB_TABLE can't be a scalar"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_per_sample_weights_1d) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("PER_SAMPLE_WEIGHTS must be 2D"));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_per_sample_weights_reduction_mean) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto reduction = op::v15::EmbeddingBagPacked::Reduction::MEAN;
|
||||
OV_EXPECT_THROW(
|
||||
auto embedding_bag_packed =
|
||||
std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights, reduction),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("Per sample weights can only be used in Reduction::SUM mode."));
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_2_args_api) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
|
||||
auto embedding_bag_packed = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices);
|
||||
EXPECT_TRUE(embedding_bag_packed->get_output_partial_shape(0).same_scheme(PartialShape{3, 2}));
|
||||
EXPECT_EQ(embedding_bag_packed->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(indices->get_partial_shape().rank().get_length(), 2);
|
||||
}
|
||||
|
||||
TEST(type_prop, embedding_bag_packed_fail_indices_element_type_2_args_api) {
|
||||
auto emb_table = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
|
||||
OV_EXPECT_THROW(auto embedding_bag_packed = std::make_shared<op::v15::EmbeddingBagPacked>(emb_table, indices),
|
||||
NodeValidationFailure,
|
||||
HasSubstr("INDICES type must be i32 or i64"));
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "visitors/visitors.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ov;
|
||||
using ov::test::NodeBuilder;
|
||||
|
||||
TEST(visitor_without_attribute, embedding_bag_offsets_op) {
|
||||
NodeBuilder::opset().insert<ov::op::v15::EmbeddingBagOffsets>();
|
||||
auto emb_table = make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2, 3});
|
||||
|
||||
auto indices = make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto default_index = make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
auto per_sample_weights = make_shared<ov::op::v0::Parameter>(element::f32, Shape{4});
|
||||
auto reduction = ov::op::v15::EmbeddingBagOffsets::Reduction::SUM;
|
||||
|
||||
auto ebos = make_shared<ov::op::v15::EmbeddingBagOffsets>(emb_table,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights,
|
||||
reduction);
|
||||
NodeBuilder builder(ebos, {emb_table, indices, offsets, default_index, per_sample_weights});
|
||||
EXPECT_NO_THROW(auto g_ebos = ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(builder.create()));
|
||||
|
||||
const auto expected_attr_count = 1;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
|
||||
TEST(visitor_without_attribute, embedding_bag_offsets_op2) {
|
||||
NodeBuilder::opset().insert<ov::op::v15::EmbeddingBagOffsets>();
|
||||
auto emb_table = make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2, 3});
|
||||
|
||||
auto indices = make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto default_index = make_shared<ov::op::v0::Parameter>(element::i64, Shape{});
|
||||
auto reduction = ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN;
|
||||
|
||||
auto ebos = make_shared<ov::op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets, default_index, reduction);
|
||||
NodeBuilder builder(ebos, {emb_table, indices, offsets, default_index});
|
||||
EXPECT_NO_THROW(auto g_ebos = ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(builder.create()));
|
||||
|
||||
const auto expected_attr_count = 1;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
|
||||
TEST(visitor_without_attribute, embedding_bag_offsets_op3) {
|
||||
NodeBuilder::opset().insert<ov::op::v15::EmbeddingBagOffsets>();
|
||||
auto emb_table = make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2, 3});
|
||||
|
||||
auto indices = make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
auto offsets = make_shared<ov::op::v0::Parameter>(element::i64, Shape{4});
|
||||
|
||||
auto ebos = make_shared<ov::op::v15::EmbeddingBagOffsets>(emb_table, indices, offsets);
|
||||
NodeBuilder builder(ebos, {emb_table, indices, offsets});
|
||||
EXPECT_NO_THROW(auto g_ebos = ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(builder.create()));
|
||||
|
||||
const auto expected_attr_count = 1;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "visitors/visitors.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ov;
|
||||
using ov::test::NodeBuilder;
|
||||
|
||||
TEST(visitor_without_attribute, embedding_bag_packed_op) {
|
||||
NodeBuilder::opset().insert<ov::op::v15::EmbeddingBagPacked>();
|
||||
auto emb_table = make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto per_sample_weights = make_shared<ov::op::v0::Parameter>(element::f32, Shape{3, 4});
|
||||
auto reduction = ov::op::v15::EmbeddingBagPacked::Reduction::SUM;
|
||||
|
||||
auto ebps = make_shared<ov::op::v15::EmbeddingBagPacked>(emb_table, indices, per_sample_weights, reduction);
|
||||
NodeBuilder builder(ebps, {emb_table, indices, per_sample_weights});
|
||||
EXPECT_NO_THROW(auto g_ebps = ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(builder.create()));
|
||||
|
||||
const auto expected_attr_count = 1;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
|
||||
TEST(visitor_without_attribute, embedding_bag_packed_op2) {
|
||||
NodeBuilder::opset().insert<ov::op::v15::EmbeddingBagPacked>();
|
||||
auto emb_table = make_shared<ov::op::v0::Parameter>(element::f32, Shape{5, 2});
|
||||
auto indices = make_shared<ov::op::v0::Parameter>(element::i64, Shape{3, 4});
|
||||
auto reduction = ov::op::v15::EmbeddingBagPacked::Reduction::MEAN;
|
||||
|
||||
auto ebps = make_shared<ov::op::v15::EmbeddingBagPacked>(emb_table, indices, reduction);
|
||||
NodeBuilder builder(ebps, {emb_table, indices});
|
||||
EXPECT_NO_THROW(auto g_ebps = ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(builder.create()));
|
||||
|
||||
const auto expected_attr_count = 1;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
#include "openvino/op/constant.hpp"
|
||||
#include "openvino/op/convert.hpp"
|
||||
#include "openvino/op/convert_like.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets_sum.hpp"
|
||||
#include "openvino/op/embeddingbag_packedsum.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
|
|
@ -18,9 +18,10 @@ namespace op {
|
|||
OutputVector translate_embedding_bag_common(const NodeContext& context) {
|
||||
// aten::embedding_bag(weight, input, offsets=None, scale_grad_by_freq=False, mode_enum=1, sparse=False,
|
||||
// per_sample_weights=None, include_last_offset=False, padding_idx=None)
|
||||
// we have only EmbeddingBagSum case support, check it before translation
|
||||
// we have only EmbeddingBag case support, check it before translation
|
||||
|
||||
auto mode = context.const_input<int64_t>(4);
|
||||
PYTORCH_OP_CONVERSION_CHECK(mode == 0, "Only sum mode supported for aten::embedding_bag translation");
|
||||
PYTORCH_OP_CONVERSION_CHECK(mode <= 1, "Only sum and mean mode supported for aten::embedding_bag translation");
|
||||
auto weight = context.get_input(0);
|
||||
auto indices = context.get_input(1);
|
||||
indices = context.mark_node(std::make_shared<ov::op::v0::Convert>(indices, element::i32));
|
||||
|
|
@ -29,17 +30,21 @@ OutputVector translate_embedding_bag_common(const NodeContext& context) {
|
|||
// parameters scale_grad_by_freq, sparse, padding_idx have relation to gradient calculation for training, skip them
|
||||
// no offsets case
|
||||
if (context.input_is_none(2)) {
|
||||
using Reduction = ov::op::v15::EmbeddingBagPacked::Reduction;
|
||||
Reduction reduction = Reduction(mode);
|
||||
// no per_sample_weights
|
||||
if (context.input_is_none(6)) {
|
||||
result = context.mark_node(std::make_shared<ov::op::v3::EmbeddingBagPackedSum>(weight, indices));
|
||||
result = context.mark_node(std::make_shared<ov::op::v15::EmbeddingBagPacked>(weight, indices, reduction));
|
||||
} else {
|
||||
auto per_sample_weight = context.get_input(6);
|
||||
per_sample_weight = context.mark_node(std::make_shared<ov::op::v1::ConvertLike>(per_sample_weight, weight));
|
||||
result = context.mark_node(
|
||||
std::make_shared<ov::op::v3::EmbeddingBagPackedSum>(weight, indices, per_sample_weight));
|
||||
std::make_shared<ov::op::v15::EmbeddingBagPacked>(weight, indices, per_sample_weight, reduction));
|
||||
}
|
||||
} else {
|
||||
// with offsets case
|
||||
using Reduction = ov::op::v15::EmbeddingBagOffsets::Reduction;
|
||||
Reduction reduction = Reduction(mode);
|
||||
auto offsets = context.get_input(2);
|
||||
offsets = context.mark_node(std::make_shared<ov::op::v0::Convert>(offsets, element::i32));
|
||||
bool include_last_offset = false;
|
||||
|
|
@ -48,15 +53,17 @@ OutputVector translate_embedding_bag_common(const NodeContext& context) {
|
|||
PYTORCH_OP_CONVERSION_CHECK(!include_last_offset, "Inclusion last offset is not supported");
|
||||
// no per_sample_wights
|
||||
if (context.input_is_none(6)) {
|
||||
result = context.mark_node(std::make_shared<ov::op::v3::EmbeddingBagOffsetsSum>(weight, indices, offsets));
|
||||
result = context.mark_node(
|
||||
std::make_shared<ov::op::v15::EmbeddingBagOffsets>(weight, indices, offsets, reduction));
|
||||
} else {
|
||||
auto per_sample_weight = context.get_input(6);
|
||||
per_sample_weight = context.mark_node(std::make_shared<ov::op::v1::ConvertLike>(per_sample_weight, weight));
|
||||
result = context.mark_node(std::make_shared<ov::op::v3::EmbeddingBagOffsetsSum>(weight,
|
||||
indices,
|
||||
offsets,
|
||||
zero,
|
||||
per_sample_weight));
|
||||
result = context.mark_node(std::make_shared<ov::op::v15::EmbeddingBagOffsets>(weight,
|
||||
indices,
|
||||
offsets,
|
||||
zero,
|
||||
per_sample_weight,
|
||||
reduction));
|
||||
}
|
||||
// aten::embedding_bag returns a tuple of 4 elements: output, offset2bag, bag_size, max_indices.
|
||||
// But the last three outputs are not used in torch.nn.EmbeddingBag or torch.nn.functional.embedding_bag.
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ static const TypeToNameMap& get_type_to_name_tbl() {
|
|||
{"ReduceSumSquare", Type::Reduce},
|
||||
{"Broadcast", Type::Broadcast},
|
||||
{"EmbeddingSegmentsSum", Type::EmbeddingSegmentsSum},
|
||||
{"EmbeddingBagPackedSum", Type::EmbeddingBagPackedSum},
|
||||
{"EmbeddingBagOffsetsSum", Type::EmbeddingBagOffsetsSum},
|
||||
{"EmbeddingBagPackedSum", Type::EmbeddingBagPacked},
|
||||
{"EmbeddingBagOffsetsSum", Type::EmbeddingBagOffsets},
|
||||
{"Gather", Type::Gather},
|
||||
{"GatherElements", Type::GatherElements},
|
||||
{"GatherND", Type::GatherND},
|
||||
|
|
@ -242,6 +242,8 @@ static const TypeToNameMap& get_type_to_name_tbl() {
|
|||
{"RoPE", Type::RoPE},
|
||||
{"GatherCompressed", Type::Gather},
|
||||
{"CausalMaskPreprocess", Type::CausalMaskPreprocess},
|
||||
{"EmbeddingBagPacked", Type::EmbeddingBagPacked},
|
||||
{"EmbeddingBagOffsets", Type::EmbeddingBagOffsets},
|
||||
};
|
||||
return type_to_name_tbl;
|
||||
}
|
||||
|
|
@ -311,6 +313,8 @@ std::string NameFromType(const Type type) {
|
|||
CASE(Reduce);
|
||||
CASE(Broadcast);
|
||||
CASE(EmbeddingSegmentsSum);
|
||||
CASE(EmbeddingBagPacked);
|
||||
CASE(EmbeddingBagOffsets);
|
||||
CASE(EmbeddingBagPackedSum);
|
||||
CASE(EmbeddingBagOffsetsSum);
|
||||
CASE(Gather);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ enum class Type {
|
|||
Interpolate,
|
||||
Reduce,
|
||||
Broadcast,
|
||||
EmbeddingBagPacked,
|
||||
EmbeddingBagOffsets,
|
||||
EmbeddingSegmentsSum,
|
||||
EmbeddingBagPackedSum,
|
||||
EmbeddingBagOffsetsSum,
|
||||
|
|
|
|||
|
|
@ -2,57 +2,60 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "embedding_bag.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/cpu_memcpy.h"
|
||||
#include "dnnl_types.h"
|
||||
#include "openvino/core/parallel.hpp"
|
||||
#include "embedding_bag_sum.h"
|
||||
#include "openvino/opsets/opset1.hpp"
|
||||
#include "common/cpu_memcpy.h"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
EmbeddingBagSum::EmbeddingBagSum(
|
||||
const std::shared_ptr<ov::Node>& op,
|
||||
size_t requiredInputNum,
|
||||
size_t indicesIdx,
|
||||
size_t perSampleWeightsIdx,
|
||||
size_t defaultIndexIdx) :
|
||||
INDICES_IDX(indicesIdx),
|
||||
PER_SAMPLE_WEIGHTS_IDX(perSampleWeightsIdx),
|
||||
DEFAULT_INDEX_IDX(defaultIndexIdx) {
|
||||
EmbeddingBag::EmbeddingBag(const std::shared_ptr<ov::Node>& op,
|
||||
size_t requiredInputNum,
|
||||
size_t indicesIdx,
|
||||
size_t perSampleWeightsIdx,
|
||||
size_t defaultIndexIdx)
|
||||
: INDICES_IDX(indicesIdx),
|
||||
PER_SAMPLE_WEIGHTS_IDX(perSampleWeightsIdx),
|
||||
DEFAULT_INDEX_IDX(defaultIndexIdx) {
|
||||
_layerName = op->get_friendly_name();
|
||||
std::string logPrefix = std::string("Layer EmbeddingBagSum with name '") + _layerName + "' ";
|
||||
std::string logPrefix = std::string("Layer EmbeddingBag with name '") + _layerName + "' ";
|
||||
if (op->get_input_size() < requiredInputNum || op->get_output_size() != 1)
|
||||
OPENVINO_THROW(logPrefix, "has incorrect number of input or output edges!");
|
||||
|
||||
if (op->get_input_size() > PER_SAMPLE_WEIGHTS_IDX)
|
||||
if ((op->get_input_size() > PER_SAMPLE_WEIGHTS_IDX)) {
|
||||
_withWeights = true;
|
||||
}
|
||||
if (_withWeights) {
|
||||
if (op->get_input_shape(PER_SAMPLE_WEIGHTS_IDX) != op->get_input_shape(INDICES_IDX))
|
||||
OPENVINO_THROW(logPrefix, "must have equal shapes for indices and per_sample_weights inputs.");
|
||||
}
|
||||
}
|
||||
|
||||
void EmbeddingBagSum::prepareParams(const VectorDims& indexStaticShape) {
|
||||
void EmbeddingBag::prepareParams(const VectorDims& indexStaticShape) {
|
||||
_embDepth = 1lu;
|
||||
for (size_t i = 1lu; i < indexStaticShape.size(); i++) {
|
||||
_embDepth *= indexStaticShape[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void EmbeddingBagSum::processData(const T* srcData, const T* weightsData,
|
||||
const VectorDims& inDataDims, const MemoryPtr& outMemory) {
|
||||
std::string msgPrefix = std::string("Node EmbeddingBagSum with name '") + _layerName + "' ";
|
||||
template <typename T>
|
||||
void EmbeddingBag::processData(const T* srcData,
|
||||
const T* weightsData,
|
||||
const VectorDims& inDataDims,
|
||||
const MemoryPtr& outMemory) {
|
||||
std::string msgPrefix = std::string("Node EmbeddingBag with name '") + _layerName + "' ";
|
||||
|
||||
initFromInputs();
|
||||
|
||||
const size_t outputBagsNum = outMemory->getShape().getStaticDims()[0];
|
||||
auto *dstData = outMemory->getDataAs<T>();
|
||||
auto* dstData = outMemory->getDataAs<T>();
|
||||
|
||||
auto threadBody = [&](const int ithr, const int nthr) {
|
||||
size_t start(0lu), end(0lu);
|
||||
|
|
@ -91,7 +94,8 @@ void EmbeddingBagSum::processData(const T* srcData, const T* weightsData,
|
|||
|
||||
for (inIdx = 1lu; inIdx < indicesSize; inIdx++) {
|
||||
if (static_cast<size_t>(indices[inIdx]) >= inDataDims[0]) {
|
||||
OPENVINO_THROW(msgPrefix + "' has invalid embedding bag index: " + std::to_string(indices[inIdx]));
|
||||
OPENVINO_THROW(msgPrefix +
|
||||
"' has invalid embedding bag index: " + std::to_string(indices[inIdx]));
|
||||
}
|
||||
size_t srcIndex = indices[inIdx] * _embDepth;
|
||||
|
||||
|
|
@ -106,6 +110,11 @@ void EmbeddingBagSum::processData(const T* srcData, const T* weightsData,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (_reduction == Reduction::MEAN) {
|
||||
for (size_t i = 0lu; i < _embDepth; i++) {
|
||||
dstData[dstIndex + i] /= indicesSize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0lu; i < _embDepth; i++) {
|
||||
dstData[dstIndex + i] = 0;
|
||||
|
|
@ -117,30 +126,43 @@ void EmbeddingBagSum::processData(const T* srcData, const T* weightsData,
|
|||
parallel_nt(0, threadBody);
|
||||
}
|
||||
|
||||
void EmbeddingBagSum::execute(const uint8_t* srcData, const uint8_t* weightsData, const ov::element::Type &srcPrc,
|
||||
const VectorDims& inDims, const MemoryPtr& outMemory) {
|
||||
void EmbeddingBag::execute(const uint8_t* srcData,
|
||||
const uint8_t* weightsData,
|
||||
const ov::element::Type& srcPrc,
|
||||
const VectorDims& inDims,
|
||||
const MemoryPtr& outMemory) {
|
||||
switch (srcPrc) {
|
||||
case ov::element::f32: {
|
||||
return processData<element_type_traits<ov::element::f32>::value_type>(reinterpret_cast<const float*>(srcData),
|
||||
reinterpret_cast<const float*>(weightsData), inDims, outMemory);
|
||||
}
|
||||
case ov::element::i8: {
|
||||
return processData<element_type_traits<ov::element::i8>::value_type>(reinterpret_cast<const int8_t*>(srcData),
|
||||
reinterpret_cast<const int8_t*>(weightsData), inDims, outMemory);
|
||||
}
|
||||
case ov::element::u8: {
|
||||
return processData<element_type_traits<ov::element::u8>::value_type>(srcData, weightsData, inDims, outMemory);
|
||||
}
|
||||
case ov::element::i32: {
|
||||
return processData<element_type_traits<ov::element::i32>::value_type>(reinterpret_cast<const int32_t*>(srcData),
|
||||
reinterpret_cast<const int32_t*>(weightsData), inDims, outMemory);
|
||||
}
|
||||
default: {
|
||||
OPENVINO_THROW("EmbeddingBagSum layer does not support precision '" + std::string(srcPrc.get_type_name()) + "'");
|
||||
}
|
||||
case ov::element::f32: {
|
||||
return processData<element_type_traits<ov::element::f32>::value_type>(
|
||||
reinterpret_cast<const float*>(srcData),
|
||||
reinterpret_cast<const float*>(weightsData),
|
||||
inDims,
|
||||
outMemory);
|
||||
}
|
||||
case ov::element::i8: {
|
||||
return processData<element_type_traits<ov::element::i8>::value_type>(
|
||||
reinterpret_cast<const int8_t*>(srcData),
|
||||
reinterpret_cast<const int8_t*>(weightsData),
|
||||
inDims,
|
||||
outMemory);
|
||||
}
|
||||
case ov::element::u8: {
|
||||
return processData<element_type_traits<ov::element::u8>::value_type>(srcData, weightsData, inDims, outMemory);
|
||||
}
|
||||
case ov::element::i32: {
|
||||
return processData<element_type_traits<ov::element::i32>::value_type>(
|
||||
reinterpret_cast<const int32_t*>(srcData),
|
||||
reinterpret_cast<const int32_t*>(weightsData),
|
||||
inDims,
|
||||
outMemory);
|
||||
}
|
||||
default: {
|
||||
OPENVINO_THROW("EmbeddingBag layer does not support precision '" + std::string(srcPrc.get_type_name()) +
|
||||
"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
} // namespace intel_cpu
|
||||
} // namespace ov
|
||||
} // namespace node
|
||||
} // namespace intel_cpu
|
||||
} // namespace ov
|
||||
|
|
@ -10,9 +10,10 @@ namespace ov {
|
|||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
class EmbeddingBagSum {
|
||||
class EmbeddingBag {
|
||||
public:
|
||||
EmbeddingBagSum(
|
||||
enum class Reduction { SUM, MEAN };
|
||||
EmbeddingBag(
|
||||
const std::shared_ptr<ov::Node>&,
|
||||
size_t requiredInputsNum,
|
||||
size_t indicesIdx,
|
||||
|
|
@ -22,7 +23,7 @@ public:
|
|||
void execute(const uint8_t* srcData, const uint8_t* weightsData, const ov::element::Type &srcPrc,
|
||||
const VectorDims& inDims, const MemoryPtr& outMemory);
|
||||
|
||||
~EmbeddingBagSum() = default;
|
||||
~EmbeddingBag() = default;
|
||||
|
||||
protected:
|
||||
virtual void initFromInputs() = 0;
|
||||
|
|
@ -44,6 +45,7 @@ protected:
|
|||
const size_t PER_SAMPLE_WEIGHTS_IDX;
|
||||
const size_t DEFAULT_INDEX_IDX;
|
||||
|
||||
Reduction _reduction = Reduction::SUM;
|
||||
bool _withWeights = false;
|
||||
size_t _embDepth = 0;
|
||||
std::string _layerName;
|
||||
|
|
@ -5,20 +5,21 @@
|
|||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "embedding_bag_offset_sum.h"
|
||||
#include "openvino/opsets/opset3.hpp"
|
||||
|
||||
#include "embedding_bag_offsets.h"
|
||||
#include "openvino/op/embeddingbag_offsets_sum.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
bool EmbeddingBagOffsetSum::isSupportedOperation(const std::shared_ptr<const ov::Node>& op, std::string& errorMessage) noexcept {
|
||||
bool EmbeddingBagOffset::isSupportedOperation(const std::shared_ptr<const ov::Node>& op, std::string& errorMessage) noexcept {
|
||||
try {
|
||||
const auto embBagOffsetSumOp = ov::as_type_ptr<const ov::op::v3::EmbeddingBagOffsetsSum>(op);
|
||||
if (!embBagOffsetSumOp) {
|
||||
errorMessage = "Node is not an instance of the EmbeddingBagOffsetsSum operation from opset v3.";
|
||||
const auto embBagOffsetOp = ov::as_type_ptr<const ov::op::v15::EmbeddingBagOffsets>(op);
|
||||
if (!embBagOffsetSumOp && !embBagOffsetOp) {
|
||||
errorMessage = "Node is not an instance of the v3::EmbeddingBagOffsetsSum or v15::EmbeddingBagOffsets operation.";
|
||||
return false;
|
||||
}
|
||||
} catch (...) {
|
||||
|
|
@ -27,14 +28,27 @@ bool EmbeddingBagOffsetSum::isSupportedOperation(const std::shared_ptr<const ov:
|
|||
return true;
|
||||
}
|
||||
|
||||
EmbeddingBagOffsetSum::EmbeddingBagOffsetSum(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context)
|
||||
EmbeddingBagOffset::EmbeddingBagOffset(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context)
|
||||
: Node(op, context, NgraphShapeInferFactory(op, EMPTY_PORT_MASK)),
|
||||
EmbeddingBagSum(op, 3lu, 1lu, 4lu, 3lu) {
|
||||
EmbeddingBag(op, 3lu, 1lu, 4lu, 3lu) {
|
||||
std::string errorMessage;
|
||||
if (!isSupportedOperation(op, errorMessage)) {
|
||||
OPENVINO_THROW_NOT_IMPLEMENTED(errorMessage);
|
||||
}
|
||||
|
||||
auto offsets_op = ov::as_type_ptr<ov::op::util::EmbeddingBagOffsetsBase>(op);
|
||||
if (offsets_op) {
|
||||
using OpReduction = ov::op::util::EmbeddingBagOffsetsBase::Reduction;
|
||||
switch (offsets_op->get_reduction()) {
|
||||
case OpReduction::SUM:
|
||||
_reduction = Reduction::SUM;
|
||||
break;
|
||||
case OpReduction::MEAN:
|
||||
_reduction = Reduction::MEAN;
|
||||
break;
|
||||
default:
|
||||
THROW_CPU_NODE_ERR("EmbeddingBagOffsets does not support reduction mode: ", ov::as_string(offsets_op->get_reduction()));
|
||||
}
|
||||
}
|
||||
if (getInputShapeAtPort(INDICES_IDX).getRank() != 1ul)
|
||||
OPENVINO_THROW("'", _layerName, "' layer has indices data with invalid rank.");
|
||||
|
||||
|
|
@ -42,11 +56,11 @@ EmbeddingBagOffsetSum::EmbeddingBagOffsetSum(const std::shared_ptr<ov::Node>& op
|
|||
OPENVINO_THROW("'", _layerName, "' layer's offsets data has invalid rank.");
|
||||
}
|
||||
|
||||
void EmbeddingBagOffsetSum::initSupportedPrimitiveDescriptors() {
|
||||
void EmbeddingBagOffset::initSupportedPrimitiveDescriptors() {
|
||||
if (!supportedPrimitiveDescriptors.empty())
|
||||
return;
|
||||
|
||||
std::string logPrefix = std::string("Layer EmbeddingBagSum with name '") + _layerName + "' ";
|
||||
std::string logPrefix = std::string("Layer EmbeddingBag with name '") + _layerName + "' ";
|
||||
static const std::set<ov::element::Type > supportedPrecisions =
|
||||
{ov::element::f32, ov::element::i8, ov::element::u8, ov::element::i32};
|
||||
|
||||
|
|
@ -74,13 +88,13 @@ void EmbeddingBagOffsetSum::initSupportedPrimitiveDescriptors() {
|
|||
addSupportedPrimDesc(inDataConfigurators, {{LayoutType::ncsp, inDataPrecision}}, impl_desc_type::ref_any);
|
||||
}
|
||||
|
||||
void EmbeddingBagOffsetSum::prepareParams() {
|
||||
void EmbeddingBagOffset::prepareParams() {
|
||||
_indicesLen = getParentEdgeAt(INDICES_IDX)->getMemory().getStaticDims()[0];
|
||||
_offsetsLen = getParentEdgeAt(OFFSETS_IDX)->getMemory().getStaticDims()[0];
|
||||
EmbeddingBagSum::prepareParams(getParentEdgeAt(EMB_TABLE_IDX)->getMemory().getStaticDims());
|
||||
EmbeddingBag::prepareParams(getParentEdgeAt(EMB_TABLE_IDX)->getMemory().getStaticDims());
|
||||
}
|
||||
|
||||
void EmbeddingBagOffsetSum::initFromInputs() {
|
||||
void EmbeddingBagOffset::initFromInputs() {
|
||||
indicesData_ = getSrcDataAtPortAs<const int>(INDICES_IDX);
|
||||
offsetsData_ = getSrcDataAtPortAs<const int>(OFFSETS_IDX);
|
||||
|
||||
|
|
@ -89,7 +103,7 @@ void EmbeddingBagOffsetSum::initFromInputs() {
|
|||
}
|
||||
}
|
||||
|
||||
void EmbeddingBagOffsetSum::getIndices(size_t embIndex, const int*& indices, size_t& size, int& weightsIdx, bool& withWeight) {
|
||||
void EmbeddingBagOffset::getIndices(size_t embIndex, const int*& indices, size_t& size, int& weightsIdx, bool& withWeight) {
|
||||
if (static_cast<size_t>(embIndex) >= _offsetsLen) {
|
||||
OPENVINO_THROW("Invalid embedding bag index.");
|
||||
}
|
||||
|
|
@ -122,27 +136,27 @@ void EmbeddingBagOffsetSum::getIndices(size_t embIndex, const int*& indices, siz
|
|||
weightsIdx = offsetsData_[embIndex];
|
||||
}
|
||||
|
||||
void EmbeddingBagOffsetSum::executeDynamicImpl(dnnl::stream strm) {
|
||||
void EmbeddingBagOffset::executeDynamicImpl(dnnl::stream strm) {
|
||||
execute(strm);
|
||||
}
|
||||
|
||||
bool EmbeddingBagOffsetSum::isExecutable() const {
|
||||
bool EmbeddingBagOffset::isExecutable() const {
|
||||
return !isInputTensorAtPortEmpty(0);
|
||||
}
|
||||
|
||||
void EmbeddingBagOffsetSum::execute(dnnl::stream strm) {
|
||||
void EmbeddingBagOffset::execute(dnnl::stream strm) {
|
||||
const auto *srcData = getSrcDataAtPortAs<const uint8_t>(0);
|
||||
const uint8_t* weightsData = nullptr;
|
||||
if (_withWeights)
|
||||
weightsData = getSrcDataAtPortAs<const uint8_t>(PER_SAMPLE_WEIGHTS_IDX);
|
||||
|
||||
const auto &inputMem = getParentEdgeAt(0)->getMemory();
|
||||
EmbeddingBagSum::execute(srcData, weightsData, inputMem.getDesc().getPrecision(),
|
||||
EmbeddingBag::execute(srcData, weightsData, inputMem.getDesc().getPrecision(),
|
||||
inputMem.getStaticDims(), getDstMemoryAtPort(0));
|
||||
}
|
||||
|
||||
bool EmbeddingBagOffsetSum::created() const {
|
||||
return getType() == Type::EmbeddingBagOffsetsSum;
|
||||
bool EmbeddingBagOffset::created() const {
|
||||
return getType() == Type::EmbeddingBagOffsets;
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
|
@ -4,16 +4,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "embedding_bag_sum.h"
|
||||
#include "embedding_bag.h"
|
||||
#include "node.h"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
class EmbeddingBagOffsetSum : public Node, public EmbeddingBagSum {
|
||||
class EmbeddingBagOffset : public Node, public EmbeddingBag {
|
||||
public:
|
||||
EmbeddingBagOffsetSum(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context);
|
||||
EmbeddingBagOffset(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context);
|
||||
|
||||
void getSupportedDescriptors() override {};
|
||||
void initSupportedPrimitiveDescriptors() override;
|
||||
|
|
@ -5,18 +5,20 @@
|
|||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "embedding_bag_packed_sum.h"
|
||||
#include "openvino/opsets/opset3.hpp"
|
||||
#include "embedding_bag_packed.h"
|
||||
#include "openvino/op/embeddingbag_packedsum.hpp"
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
bool EmbeddingBagPackedSum::isSupportedOperation(const std::shared_ptr<const ov::Node>& op, std::string& errorMessage) noexcept {
|
||||
bool EmbeddingBagPacked::isSupportedOperation(const std::shared_ptr<const ov::Node>& op, std::string& errorMessage) noexcept {
|
||||
try {
|
||||
const auto embBagPackedSumOp = ov::as_type_ptr<const ov::op::v3::EmbeddingBagPackedSum>(op);
|
||||
if (!embBagPackedSumOp) {
|
||||
errorMessage = "Node is not an instance of the EmbeddingBagPackedSum operation from opset v3.";
|
||||
const auto embBagPackedOp = ov::as_type_ptr<const ov::op::v15::EmbeddingBagPacked>(op);
|
||||
if (!embBagPackedSumOp && !embBagPackedOp) {
|
||||
errorMessage = "Node is not an instance of the v3::EmbeddingBagPackedSum or v15::EmbeddingBagPacked operations.";
|
||||
return false;
|
||||
}
|
||||
} catch (...) {
|
||||
|
|
@ -25,23 +27,36 @@ bool EmbeddingBagPackedSum::isSupportedOperation(const std::shared_ptr<const ov:
|
|||
return true;
|
||||
}
|
||||
|
||||
EmbeddingBagPackedSum::EmbeddingBagPackedSum(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context)
|
||||
EmbeddingBagPacked::EmbeddingBagPacked(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context)
|
||||
: Node(op, context, NgraphShapeInferFactory(op, EMPTY_PORT_MASK)),
|
||||
EmbeddingBagSum(op, 2lu, 1lu, 2lu, 3lu) {
|
||||
EmbeddingBag(op, 2lu, 1lu, 2lu, 3lu) {
|
||||
std::string errorMessage;
|
||||
if (!isSupportedOperation(op, errorMessage)) {
|
||||
OPENVINO_THROW_NOT_IMPLEMENTED(errorMessage);
|
||||
}
|
||||
|
||||
auto packed_op = ov::as_type_ptr<ov::op::util::EmbeddingBagPackedBase>(op);
|
||||
if (packed_op) {
|
||||
using OpReduction = ov::op::util::EmbeddingBagPackedBase::Reduction;
|
||||
switch (packed_op->get_reduction()) {
|
||||
case OpReduction::SUM:
|
||||
_reduction = Reduction::SUM;
|
||||
break;
|
||||
case OpReduction::MEAN:
|
||||
_reduction = Reduction::MEAN;
|
||||
break;
|
||||
default:
|
||||
THROW_CPU_NODE_ERR("EmbeddingBagPacked does not support reduction mode: ", ov::as_string(packed_op->get_reduction()));
|
||||
}
|
||||
}
|
||||
if (getInputShapeAtPort(INDICES_IDX).getRank() != 2ul)
|
||||
OPENVINO_THROW("'", _layerName, "' layer has indices data with invalid rank.");
|
||||
}
|
||||
|
||||
void EmbeddingBagPackedSum::initSupportedPrimitiveDescriptors() {
|
||||
void EmbeddingBagPacked::initSupportedPrimitiveDescriptors() {
|
||||
if (!supportedPrimitiveDescriptors.empty())
|
||||
return;
|
||||
|
||||
std::string logPrefix = std::string("Layer EmbeddingBagSum with name '") + _layerName + "' ";
|
||||
std::string logPrefix = std::string("Layer EmbeddingBag with name '") + _layerName + "' ";
|
||||
static const std::set<ov::element::Type> supportedPrecisions =
|
||||
{ov::element::f32, ov::element::i8, ov::element::u8, ov::element::i32};
|
||||
|
||||
|
|
@ -66,17 +81,17 @@ void EmbeddingBagPackedSum::initSupportedPrimitiveDescriptors() {
|
|||
addSupportedPrimDesc(inDataConfigurators, {{LayoutType::ncsp, inDataPrecision}}, impl_desc_type::ref_any);
|
||||
}
|
||||
|
||||
void EmbeddingBagPackedSum::prepareParams() {
|
||||
void EmbeddingBagPacked::prepareParams() {
|
||||
_batch = getParentEdgeAt(INDICES_IDX)->getMemory().getStaticDims()[0];
|
||||
_indicesPerBag = getParentEdgeAt(INDICES_IDX)->getMemory().getStaticDims()[1];
|
||||
EmbeddingBagSum::prepareParams(getParentEdgeAt(EMB_TABLE_IDX)->getMemory().getStaticDims());
|
||||
EmbeddingBag::prepareParams(getParentEdgeAt(EMB_TABLE_IDX)->getMemory().getStaticDims());
|
||||
}
|
||||
|
||||
void EmbeddingBagPackedSum::initFromInputs() {
|
||||
void EmbeddingBagPacked::initFromInputs() {
|
||||
_indices = getSrcDataAtPortAs<const int>(INDICES_IDX);
|
||||
}
|
||||
|
||||
void EmbeddingBagPackedSum::getIndices(size_t embIndex, const int*& indices, size_t& size, int& weightsIdx, bool& withWeight) {
|
||||
void EmbeddingBagPacked::getIndices(size_t embIndex, const int*& indices, size_t& size, int& weightsIdx, bool& withWeight) {
|
||||
if (static_cast<size_t>(embIndex) >= _batch * _indicesPerBag)
|
||||
OPENVINO_THROW("Invalid embedding bag index.");
|
||||
|
||||
|
|
@ -88,27 +103,27 @@ void EmbeddingBagPackedSum::getIndices(size_t embIndex, const int*& indices, siz
|
|||
weightsIdx = embIndex * _indicesPerBag;
|
||||
}
|
||||
|
||||
void EmbeddingBagPackedSum::executeDynamicImpl(dnnl::stream strm) {
|
||||
void EmbeddingBagPacked::executeDynamicImpl(dnnl::stream strm) {
|
||||
execute(strm);
|
||||
}
|
||||
|
||||
bool EmbeddingBagPackedSum::isExecutable() const {
|
||||
bool EmbeddingBagPacked::isExecutable() const {
|
||||
return !isInputTensorAtPortEmpty(0);
|
||||
}
|
||||
|
||||
void EmbeddingBagPackedSum::execute(dnnl::stream strm) {
|
||||
void EmbeddingBagPacked::execute(dnnl::stream strm) {
|
||||
const auto *srcData = getSrcDataAtPortAs<const uint8_t>(0);
|
||||
const uint8_t* weightsData = nullptr;
|
||||
if (_withWeights)
|
||||
weightsData = getSrcDataAtPortAs<const uint8_t>(PER_SAMPLE_WEIGHTS_IDX);
|
||||
|
||||
const auto &inputMem = getParentEdgeAt(0)->getMemory();
|
||||
EmbeddingBagSum::execute(srcData, weightsData, inputMem.getDesc().getPrecision(),
|
||||
EmbeddingBag::execute(srcData, weightsData, inputMem.getDesc().getPrecision(),
|
||||
inputMem.getStaticDims(), getDstMemoryAtPort(0));
|
||||
}
|
||||
|
||||
bool EmbeddingBagPackedSum::created() const {
|
||||
return getType() == Type::EmbeddingBagPackedSum;
|
||||
bool EmbeddingBagPacked::created() const {
|
||||
return getType() == Type::EmbeddingBagPacked;
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
|
@ -4,16 +4,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "embedding_bag_sum.h"
|
||||
#include "embedding_bag.h"
|
||||
#include "node.h"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
class EmbeddingBagPackedSum : public Node, public EmbeddingBagSum {
|
||||
class EmbeddingBagPacked : public Node, public EmbeddingBag {
|
||||
public:
|
||||
EmbeddingBagPackedSum(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context);
|
||||
EmbeddingBagPacked(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context);
|
||||
|
||||
void getSupportedDescriptors() override {};
|
||||
void initSupportedPrimitiveDescriptors() override;
|
||||
|
|
@ -27,12 +27,12 @@ bool EmbeddingSegmentsSum::isSupportedOperation(const std::shared_ptr<const ov::
|
|||
|
||||
EmbeddingSegmentsSum::EmbeddingSegmentsSum(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context)
|
||||
: Node(op, context, NgraphShapeInferFactory(op, PortMask(NUM_SEGMENTS_IDX))),
|
||||
EmbeddingBagSum(op, 4lu, 1lu, 5lu, 4lu) {
|
||||
EmbeddingBag(op, 4lu, 1lu, 5lu, 4lu) {
|
||||
std::string errorMessage;
|
||||
if (!isSupportedOperation(op, errorMessage)) {
|
||||
OPENVINO_THROW_NOT_IMPLEMENTED(errorMessage);
|
||||
}
|
||||
|
||||
_reduction = Reduction::SUM;
|
||||
std::string errPrefix = std::string("EmbeddingSegmentsSum layer with name '") + _layerName + "' ";
|
||||
if (getInputShapeAtPort(INDICES_IDX).getRank() != 1ul)
|
||||
OPENVINO_THROW(errPrefix, "has indices data with invalid rank: ", getInputShapeAtPort(INDICES_IDX).getRank());
|
||||
|
|
@ -45,7 +45,7 @@ void EmbeddingSegmentsSum::initSupportedPrimitiveDescriptors() {
|
|||
if (!supportedPrimitiveDescriptors.empty())
|
||||
return;
|
||||
|
||||
std::string logPrefix = std::string("Layer EmbeddingBagSum with name '") + _layerName + "' ";
|
||||
std::string logPrefix = std::string("Layer EmbeddingBag with name '") + _layerName + "' ";
|
||||
static const std::set<ov::element::Type> supportedPrecisions =
|
||||
{ov::element::f32, ov::element::i8, ov::element::u8, ov::element::i32};
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ void EmbeddingSegmentsSum::initSupportedPrimitiveDescriptors() {
|
|||
}
|
||||
|
||||
void EmbeddingSegmentsSum::prepareParams() {
|
||||
EmbeddingBagSum::prepareParams(getParentEdgeAt(EMB_TABLE_IDX)->getMemory().getStaticDims());
|
||||
EmbeddingBag::prepareParams(getParentEdgeAt(EMB_TABLE_IDX)->getMemory().getStaticDims());
|
||||
}
|
||||
|
||||
void EmbeddingSegmentsSum::initFromInputs() {
|
||||
|
|
@ -149,7 +149,7 @@ void EmbeddingSegmentsSum::execute(dnnl::stream strm) {
|
|||
weightsData = getSrcDataAtPortAs<const uint8_t>(PER_SAMPLE_WEIGHTS_IDX);
|
||||
|
||||
const auto &inputMem = getParentEdgeAt(0)->getMemory();
|
||||
EmbeddingBagSum::execute(srcData, weightsData, inputMem.getDesc().getPrecision(),
|
||||
EmbeddingBag::execute(srcData, weightsData, inputMem.getDesc().getPrecision(),
|
||||
inputMem.getStaticDims(), getDstMemoryAtPort(0));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "embedding_bag_sum.h"
|
||||
#include "embedding_bag.h"
|
||||
#include "node.h"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
class EmbeddingSegmentsSum : public Node, public EmbeddingBagSum {
|
||||
class EmbeddingSegmentsSum : public Node, public EmbeddingBag {
|
||||
public:
|
||||
EmbeddingSegmentsSum(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
#include "nodes/detection_output.h"
|
||||
#include "nodes/dft.h"
|
||||
#include "nodes/eltwise.h"
|
||||
#include "nodes/embedding_bag_offset_sum.h"
|
||||
#include "nodes/embedding_bag_packed_sum.h"
|
||||
#include "nodes/embedding_bag_offsets.h"
|
||||
#include "nodes/embedding_bag_packed.h"
|
||||
#include "nodes/embedding_segments_sum.h"
|
||||
#include "nodes/experimental_detectron_detection_output.h"
|
||||
#include "nodes/experimental_detectron_generate_proposals_single_image.h"
|
||||
|
|
@ -124,7 +124,8 @@ Node::NodesFactory::NodesFactory() : Factory("NodesFactory") {
|
|||
INTEL_CPU_NODE(Pooling, Type::Pooling);
|
||||
INTEL_CPU_NODE(Eltwise, Type::Eltwise);
|
||||
INTEL_CPU_NODE(SoftMax, Type::Softmax);
|
||||
INTEL_CPU_NODE(EmbeddingBagPackedSum, Type::EmbeddingBagPackedSum);
|
||||
INTEL_CPU_NODE(EmbeddingBagPacked, Type::EmbeddingBagPackedSum);
|
||||
INTEL_CPU_NODE(EmbeddingBagPacked, Type::EmbeddingBagPacked);
|
||||
INTEL_CPU_NODE(Input, Type::Input);
|
||||
INTEL_CPU_NODE(Input, Type::Output);
|
||||
INTEL_CPU_NODE(MemoryInput, Type::MemoryInput);
|
||||
|
|
@ -158,7 +159,8 @@ Node::NodesFactory::NodesFactory() : Factory("NodesFactory") {
|
|||
INTEL_CPU_NODE(MultiClassNms, Type::MulticlassNms);
|
||||
INTEL_CPU_NODE(Convert, Type::Convert);
|
||||
INTEL_CPU_NODE(ColorConvert, Type::ColorConvert);
|
||||
INTEL_CPU_NODE(EmbeddingBagOffsetSum, Type::EmbeddingBagOffsetsSum);
|
||||
INTEL_CPU_NODE(EmbeddingBagOffset, Type::EmbeddingBagOffsetsSum);
|
||||
INTEL_CPU_NODE(EmbeddingBagOffset, Type::EmbeddingBagOffsets);
|
||||
INTEL_CPU_NODE(Roll, Type::Roll);
|
||||
INTEL_CPU_NODE(Pad, Type::Pad);
|
||||
INTEL_CPU_NODE(Reshape, Type::Reshape);
|
||||
|
|
|
|||
|
|
@ -402,6 +402,8 @@ using IStaticShapeInferFactory =
|
|||
template <>
|
||||
const IStaticShapeInferFactory::TRegistry IStaticShapeInferFactory::registry{
|
||||
// opset15
|
||||
_OV_OP_SHAPE_INFER_MASK_REG(opset15::EmbeddingBagOffsets, ShapeInferTA, util::bit::mask()),
|
||||
_OV_OP_SHAPE_INFER_MASK_REG(opset15::EmbeddingBagPacked, ShapeInferTA, util::bit::mask()),
|
||||
_OV_OP_SHAPE_INFER_MASK_REG(op::v15::Col2Im, ShapeInferTA, util::bit::mask(1, 2)),
|
||||
// opset14
|
||||
_OV_OP_SHAPE_INFER_MASK_REG(opset14::Inverse, ShapeInferTA, util::bit::mask()),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "common_test_utils/node_builders/embedding_bag_offsets.hpp"
|
||||
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
#include "utils/cpu_test_utils.hpp"
|
||||
|
||||
using namespace CPUTestUtils;
|
||||
namespace ov {
|
||||
namespace test {
|
||||
|
||||
typedef std::tuple<InputShape, // input_shapes
|
||||
std::vector<size_t>, // indices
|
||||
std::vector<size_t>, // offsets
|
||||
size_t, // default_index
|
||||
bool, // with_weights
|
||||
bool, // with_def_index
|
||||
ov::op::util::EmbeddingBagOffsetsBase::Reduction // reduction
|
||||
>
|
||||
embeddingBagOffsetsParams;
|
||||
|
||||
typedef std::tuple<embeddingBagOffsetsParams,
|
||||
ElementType, // embedding table
|
||||
ElementType, // indices
|
||||
ov::test::TargetDevice>
|
||||
embeddingBagOffsetsLayerTestParamsSet;
|
||||
|
||||
class EmbeddingBagOffsetsLayerCPUTest : public testing::WithParamInterface<embeddingBagOffsetsLayerTestParamsSet>,
|
||||
virtual public SubgraphBaseTest,
|
||||
public CPUTestsBase {
|
||||
public:
|
||||
using Reduction = ov::op::util::EmbeddingBagOffsetsBase::Reduction;
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<embeddingBagOffsetsLayerTestParamsSet>& obj) {
|
||||
embeddingBagOffsetsParams params;
|
||||
ElementType netPrecision, indPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(params, netPrecision, indPrecision, targetDevice) = obj.param;
|
||||
|
||||
InputShape inputShapes;
|
||||
std::vector<size_t> indices, offsets;
|
||||
size_t defaultIndex;
|
||||
bool withWeights, withDefIndex;
|
||||
Reduction reduction;
|
||||
std::tie(inputShapes, indices, offsets, defaultIndex, withWeights, withDefIndex, reduction) = params;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=" << inputShapes << "_";
|
||||
result << "I" << ov::test::utils::vec2str(indices) << "_";
|
||||
result << "O" << ov::test::utils::vec2str(offsets) << "_";
|
||||
result << "DI" << defaultIndex << "_";
|
||||
result << "WW" << withWeights << "_";
|
||||
result << "WDI" << withDefIndex << "_";
|
||||
result << "R" << ov::as_string(reduction) << "_";
|
||||
result << "netPRC=" << netPrecision << "_";
|
||||
result << "indPRC=" << indPrecision << "_";
|
||||
result << "targetDevice=" << targetDevice;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
embeddingBagOffsetsParams embParams;
|
||||
ElementType indPrecision;
|
||||
std::tie(embParams, inType, indPrecision, targetDevice) = this->GetParam();
|
||||
|
||||
InputShape inputShapes;
|
||||
std::vector<size_t> indices, offsets;
|
||||
bool withWeights, withDefIndex;
|
||||
Reduction reduction;
|
||||
size_t defaultIndex;
|
||||
std::tie(inputShapes, indices, offsets, defaultIndex, withWeights, withDefIndex, reduction) = embParams;
|
||||
|
||||
selectedType = makeSelectedTypeStr("ref", inType);
|
||||
targetDevice = ov::test::utils::DEVICE_CPU;
|
||||
|
||||
init_input_shapes({inputShapes});
|
||||
|
||||
auto emb_table_node = std::make_shared<ov::op::v0::Parameter>(inType, inputShapes.first);
|
||||
ov::ParameterVector params = {emb_table_node};
|
||||
|
||||
auto embBag = std::dynamic_pointer_cast<ov::op::v15::EmbeddingBagOffsets>(
|
||||
ov::test::utils::make_embedding_bag_offsets(inType,
|
||||
indPrecision,
|
||||
emb_table_node,
|
||||
indices,
|
||||
offsets,
|
||||
defaultIndex,
|
||||
withWeights,
|
||||
withDefIndex,
|
||||
reduction));
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(embBag)};
|
||||
function = std::make_shared<ov::Model>(results, params, "embeddingBagOffsets");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(EmbeddingBagOffsetsLayerCPUTest, CompareWithRefs) {
|
||||
run();
|
||||
CheckPluginRelatedResults(compiledModel, "embeddingBagOffsets");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const std::vector<ElementType> netPrecisions = {ElementType::f32, ElementType::i32, ElementType::u8};
|
||||
|
||||
const std::vector<ElementType> indPrecisions = {ElementType::i64, ElementType::i32};
|
||||
|
||||
const std::vector<InputShape> input_shapes = {
|
||||
// dynamic input shapes
|
||||
{// input model dynamic shapes
|
||||
{ov::Dimension::dynamic(), ov::Dimension::dynamic()},
|
||||
// input tensor shapes
|
||||
{{5, 6}, {10, 35}}},
|
||||
{// input model dynamic shapes
|
||||
{ov::Dimension::dynamic(), ov::Dimension::dynamic(), ov::Dimension::dynamic()},
|
||||
// input tensor shapes
|
||||
{{5, 4, 16}, {10, 12, 8}}},
|
||||
{// input model dynamic shapes with limits
|
||||
{{5, 10}, {6, 35}, {4, 8}},
|
||||
// input tensor shapes
|
||||
{{5, 6, 4}, {10, 35, 8}, {5, 6, 4}}},
|
||||
// static shapes
|
||||
{{5, 6}, {{5, 6}}},
|
||||
{{10, 35}, {{10, 35}}},
|
||||
{{5, 4, 16}, {{5, 4, 16}}},
|
||||
};
|
||||
|
||||
const std::vector<std::vector<size_t>> indices = {{0, 1, 2, 2, 3}, {4, 4, 3, 1, 0}, {1, 2, 1, 2, 1, 2, 1, 2, 1, 2}};
|
||||
const std::vector<std::vector<size_t>> offsets = {{0, 2}, {0, 0, 2, 2}, {2, 4}};
|
||||
const std::vector<size_t> default_index = {0, 4};
|
||||
const std::vector<bool> with_default_index = {false, true};
|
||||
const std::vector<ov::op::util::EmbeddingBagOffsetsBase::Reduction> reduction = {
|
||||
ov::op::util::EmbeddingBagOffsetsBase::Reduction::SUM,
|
||||
ov::op::util::EmbeddingBagOffsetsBase::Reduction::MEAN};
|
||||
|
||||
const auto embBagOffsetArgSetWthWeights = ::testing::Combine(::testing::ValuesIn(input_shapes),
|
||||
::testing::ValuesIn(indices),
|
||||
::testing::ValuesIn(offsets),
|
||||
::testing::ValuesIn(default_index),
|
||||
::testing::Values(true),
|
||||
::testing::ValuesIn(with_default_index),
|
||||
::testing::Values(ov::op::util::EmbeddingBagOffsetsBase::Reduction::SUM));
|
||||
const auto embBagOffsetArgSetNoWeights = ::testing::Combine(::testing::ValuesIn(input_shapes),
|
||||
::testing::ValuesIn(indices),
|
||||
::testing::ValuesIn(offsets),
|
||||
::testing::ValuesIn(default_index),
|
||||
::testing::Values(false),
|
||||
::testing::ValuesIn(with_default_index),
|
||||
::testing::ValuesIn(reduction));
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_EmbeddingBagOffsets_With_Weights,
|
||||
EmbeddingBagOffsetsLayerCPUTest,
|
||||
::testing::Combine(embBagOffsetArgSetWthWeights,
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(indPrecisions),
|
||||
::testing::Values(ov::test::utils::DEVICE_CPU)),
|
||||
EmbeddingBagOffsetsLayerCPUTest::getTestCaseName);
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_EmbeddingBagOffsets_No_Weights,
|
||||
EmbeddingBagOffsetsLayerCPUTest,
|
||||
::testing::Combine(embBagOffsetArgSetNoWeights,
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(indPrecisions),
|
||||
::testing::Values(ov::test::utils::DEVICE_CPU)),
|
||||
EmbeddingBagOffsetsLayerCPUTest::getTestCaseName);
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "common_test_utils/node_builders/embedding_bag_packed.hpp"
|
||||
#include "openvino/op/util/embeddingbag_packed_base.hpp"
|
||||
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
#include "utils/cpu_test_utils.hpp"
|
||||
|
||||
using namespace CPUTestUtils;
|
||||
namespace ov {
|
||||
namespace test {
|
||||
|
||||
typedef std::tuple<InputShape, // input_shapes
|
||||
std::vector<std::vector<size_t>>, // indices
|
||||
bool, // with_weights
|
||||
ov::op::util::EmbeddingBagPackedBase::Reduction // reduction
|
||||
>
|
||||
embeddingBagPackedParams;
|
||||
|
||||
typedef std::tuple<embeddingBagPackedParams,
|
||||
ElementType, // embedding table
|
||||
ElementType, // indices
|
||||
ov::test::TargetDevice>
|
||||
embeddingBagPackedLayerTestParamsSet;
|
||||
|
||||
class EmbeddingBagPackedLayerCPUTest : public testing::WithParamInterface<embeddingBagPackedLayerTestParamsSet>,
|
||||
virtual public SubgraphBaseTest,
|
||||
public CPUTestsBase {
|
||||
public:
|
||||
using Reduction = ov::op::util::EmbeddingBagPackedBase::Reduction;
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<embeddingBagPackedLayerTestParamsSet>& obj) {
|
||||
embeddingBagPackedParams params;
|
||||
ElementType netPrecision, indPrecision;
|
||||
std::string targetDevice;
|
||||
std::tie(params, netPrecision, indPrecision, targetDevice) = obj.param;
|
||||
|
||||
InputShape inputShapes;
|
||||
std::vector<std::vector<size_t>> indices;
|
||||
bool withWeights;
|
||||
Reduction reduction;
|
||||
std::tie(inputShapes, indices, withWeights, reduction) = params;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=" << inputShapes << "_";
|
||||
result << "I" << ov::test::utils::vec2str(indices) << "_";
|
||||
result << "WW" << withWeights << "_";
|
||||
result << "R" << ov::as_string(reduction) << "_";
|
||||
result << "netPRC=" << netPrecision << "_";
|
||||
result << "indPRC=" << indPrecision << "_";
|
||||
result << "targetDevice=" << targetDevice;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
embeddingBagPackedParams embParams;
|
||||
ElementType indPrecision;
|
||||
std::tie(embParams, inType, indPrecision, targetDevice) = this->GetParam();
|
||||
|
||||
InputShape inputShapes;
|
||||
std::vector<std::vector<size_t>> indices;
|
||||
bool withWeights;
|
||||
Reduction reduction;
|
||||
std::tie(inputShapes, indices, withWeights, reduction) = embParams;
|
||||
|
||||
selectedType = makeSelectedTypeStr("ref", inType);
|
||||
targetDevice = ov::test::utils::DEVICE_CPU;
|
||||
|
||||
init_input_shapes({inputShapes});
|
||||
|
||||
auto emb_table_node = std::make_shared<ov::op::v0::Parameter>(inType, inputShapes.first);
|
||||
ov::ParameterVector params = {emb_table_node};
|
||||
|
||||
auto embBag = std::dynamic_pointer_cast<ov::op::v15::EmbeddingBagPacked>(
|
||||
ov::test::utils::make_embedding_bag_packed(inType,
|
||||
indPrecision,
|
||||
emb_table_node,
|
||||
indices,
|
||||
withWeights,
|
||||
reduction));
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(embBag)};
|
||||
function = std::make_shared<ov::Model>(results, params, "embeddingBagPacked");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(EmbeddingBagPackedLayerCPUTest, CompareWithRefs) {
|
||||
run();
|
||||
CheckPluginRelatedResults(compiledModel, "embeddingBagPacked");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const std::vector<ElementType> netPrecisions = {ElementType::f32, ElementType::i32, ElementType::u8};
|
||||
|
||||
const std::vector<ElementType> indPrecisions = {ElementType::i64, ElementType::i32};
|
||||
|
||||
const std::vector<InputShape> input_shapes = {
|
||||
// dynamic input shapes
|
||||
{// input model dynamic shapes
|
||||
{ov::Dimension::dynamic(), ov::Dimension::dynamic()},
|
||||
// input tensor shapes
|
||||
{{{5, 6}}, {10, 35}}},
|
||||
{// input model dynamic shapes
|
||||
{ov::Dimension::dynamic(), ov::Dimension::dynamic(), ov::Dimension::dynamic()},
|
||||
// input tensor shapes
|
||||
{{5, 4, 16}, {10, 12, 8}}},
|
||||
{// input model dynamic shapes with limits
|
||||
{{5, 10}, {6, 35}, {4, 8}},
|
||||
// input tensor shapes
|
||||
{{5, 6, 4}, {10, 35, 8}, {5, 6, 4}}},
|
||||
// static shapes
|
||||
{{5, 6}, {{5, 6}}},
|
||||
{{10, 35}, {{10, 35}}},
|
||||
{{5, 4, 16}, {{5, 4, 16}}},
|
||||
};
|
||||
|
||||
const std::vector<std::vector<std::vector<size_t>>> indices = {{{0, 1}, {2, 2}, {3, 4}},
|
||||
{{4, 4, 3}, {1, 0, 2}},
|
||||
{{1, 2, 1, 2}, {1, 2, 1, 2}}};
|
||||
|
||||
const std::vector<ov::op::util::EmbeddingBagPackedBase::Reduction> reduction = {
|
||||
ov::op::util::EmbeddingBagPackedBase::Reduction::SUM,
|
||||
ov::op::util::EmbeddingBagPackedBase::Reduction::MEAN};
|
||||
|
||||
const auto embBagPackedArgSetWthWeights = ::testing::Combine(::testing::ValuesIn(input_shapes),
|
||||
::testing::ValuesIn(indices),
|
||||
::testing::Values(true),
|
||||
::testing::Values(ov::op::util::EmbeddingBagPackedBase::Reduction::SUM));
|
||||
|
||||
const auto embBagPackedArgSetNoWeights = ::testing::Combine(::testing::ValuesIn(input_shapes),
|
||||
::testing::ValuesIn(indices),
|
||||
::testing::Values(false),
|
||||
::testing::ValuesIn(reduction));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_EmbeddingBagPacked_With_Weights,
|
||||
EmbeddingBagPackedLayerCPUTest,
|
||||
::testing::Combine(embBagPackedArgSetWthWeights,
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(indPrecisions),
|
||||
::testing::Values(ov::test::utils::DEVICE_CPU)),
|
||||
EmbeddingBagPackedLayerCPUTest::getTestCaseName);
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_EmbeddingBagPacked_No_Weights,
|
||||
EmbeddingBagPackedLayerCPUTest,
|
||||
::testing::Combine(embBagPackedArgSetNoWeights,
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(indPrecisions),
|
||||
::testing::Values(ov::test::utils::DEVICE_CPU)),
|
||||
EmbeddingBagPackedLayerCPUTest::getTestCaseName);
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/reference/embedding_bag_offsets.hpp"
|
||||
|
||||
#include "evaluate_node.hpp"
|
||||
|
||||
namespace embedding_bag_offsets_v15 {
|
||||
template <ov::element::Type_t t1, ov::element::Type_t t2>
|
||||
inline void evaluate(const std::shared_ptr<ov::op::v15::EmbeddingBagOffsets>& op,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs) {
|
||||
using T1 = typename ov::element_type_traits<t1>::value_type;
|
||||
using T2 = typename ov::element_type_traits<t2>::value_type;
|
||||
ov::reference::embeddingBagOffsets<T1, T2>(inputs[0].data<T1>(),
|
||||
inputs[1].data<T2>(),
|
||||
inputs[2].data<T2>(),
|
||||
inputs.size() > 3 ? inputs[3].data<T2>() : nullptr,
|
||||
inputs.size() > 4 ? inputs[4].data<T1>() : nullptr,
|
||||
outputs[0].data<T1>(),
|
||||
ov::shape_size(inputs[1].get_shape()),
|
||||
outputs[0].get_shape(),
|
||||
op->get_reduction());
|
||||
}
|
||||
} // namespace embedding_bag_offsets_v15
|
||||
|
||||
template <ov::element::Type_t ET>
|
||||
bool evaluate(const std::shared_ptr<ov::op::v15::EmbeddingBagOffsets>& op,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs) {
|
||||
switch (inputs[1].get_element_type()) {
|
||||
case ov::element::i32:
|
||||
embedding_bag_offsets_v15::evaluate<ET, ov::element::i32>(op, outputs, inputs);
|
||||
break;
|
||||
case ov::element::i64:
|
||||
embedding_bag_offsets_v15::evaluate<ET, ov::element::i64>(op, outputs, inputs);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool evaluate_node<ov::op::v15::EmbeddingBagOffsets>(std::shared_ptr<ov::Node> node,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs) {
|
||||
auto element_type = node->get_output_element_type(0);
|
||||
if (ov::is_type<ov::op::v1::Select>(node) || ov::is_type<ov::op::util::BinaryElementwiseComparison>(node))
|
||||
element_type = node->get_input_element_type(1);
|
||||
|
||||
switch (element_type) {
|
||||
case ov::element::boolean:
|
||||
return evaluate<ov::element::boolean>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::bf16:
|
||||
return evaluate<ov::element::bf16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::f16:
|
||||
return evaluate<ov::element::f16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::f64:
|
||||
return evaluate<ov::element::f64>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::f32:
|
||||
return evaluate<ov::element::f32>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::i4:
|
||||
return evaluate<ov::element::i4>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::i8:
|
||||
return evaluate<ov::element::i8>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::i16:
|
||||
return evaluate<ov::element::i16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::i32:
|
||||
return evaluate<ov::element::i32>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::i64:
|
||||
return evaluate<ov::element::i64>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::u1:
|
||||
return evaluate<ov::element::u1>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::u4:
|
||||
return evaluate<ov::element::u4>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::u8:
|
||||
return evaluate<ov::element::u8>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::u16:
|
||||
return evaluate<ov::element::u16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::u32:
|
||||
return evaluate<ov::element::u32>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
case ov::element::u64:
|
||||
return evaluate<ov::element::u64>(ov::as_type_ptr<ov::op::v15::EmbeddingBagOffsets>(node), outputs, inputs);
|
||||
default:
|
||||
OPENVINO_THROW("Unhandled data type ", node->get_element_type().get_type_name(), " in evaluate_node()");
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,8 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/reference/embedding_bag_offsets_sum.hpp"
|
||||
|
||||
#include "evaluate_node.hpp"
|
||||
#include "openvino/reference/embedding_bag_offsets.hpp"
|
||||
|
||||
namespace embedding_bag_offsets_sum_v3 {
|
||||
template <ov::element::Type_t t1, ov::element::Type_t t2>
|
||||
|
|
@ -13,14 +12,15 @@ inline void evaluate(const std::shared_ptr<ov::op::v3::EmbeddingBagOffsetsSum>&
|
|||
const ov::TensorVector& inputs) {
|
||||
using T1 = typename ov::element_type_traits<t1>::value_type;
|
||||
using T2 = typename ov::element_type_traits<t2>::value_type;
|
||||
ov::reference::embeddingBagOffsetsSum<T1, T2>(inputs[0].data<T1>(),
|
||||
inputs[1].data<T2>(),
|
||||
inputs[2].data<T2>(),
|
||||
inputs.size() > 3 ? inputs[3].data<T2>() : nullptr,
|
||||
inputs.size() > 4 ? inputs[4].data<T1>() : nullptr,
|
||||
outputs[0].data<T1>(),
|
||||
ov::shape_size(inputs[1].get_shape()),
|
||||
outputs[0].get_shape());
|
||||
ov::reference::embeddingBagOffsets<T1, T2>(inputs[0].data<T1>(),
|
||||
inputs[1].data<T2>(),
|
||||
inputs[2].data<T2>(),
|
||||
inputs.size() > 3 ? inputs[3].data<T2>() : nullptr,
|
||||
inputs.size() > 4 ? inputs[4].data<T1>() : nullptr,
|
||||
outputs[0].data<T1>(),
|
||||
ov::shape_size(inputs[1].get_shape()),
|
||||
outputs[0].get_shape(),
|
||||
ov::op::v3::EmbeddingBagOffsetsSum::Reduction::SUM);
|
||||
}
|
||||
} // namespace embedding_bag_offsets_sum_v3
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/reference/embedding_bag_packed.hpp"
|
||||
|
||||
#include "evaluate_node.hpp"
|
||||
|
||||
namespace embedding_bag_packed_v15 {
|
||||
template <ov::element::Type_t t1, ov::element::Type_t t2>
|
||||
inline void evaluate(const std::shared_ptr<ov::op::v15::EmbeddingBagPacked>& op,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs) {
|
||||
using T1 = typename ov::element_type_traits<t1>::value_type;
|
||||
using T2 = typename ov::element_type_traits<t2>::value_type;
|
||||
ov::reference::embeddingBagPacked<T1, T2>(inputs[0].data<T1>(),
|
||||
inputs[1].data<T2>(),
|
||||
inputs.size() > 2 ? inputs[2].data<T1>() : nullptr,
|
||||
outputs[0].data<T1>(),
|
||||
inputs[1].get_shape(),
|
||||
outputs[0].get_shape(),
|
||||
op->get_reduction());
|
||||
}
|
||||
} // namespace embedding_bag_packed_v15
|
||||
|
||||
template <ov::element::Type_t ET>
|
||||
bool evaluate(const std::shared_ptr<ov::op::v15::EmbeddingBagPacked>& op,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs) {
|
||||
switch (inputs[1].get_element_type()) {
|
||||
case ov::element::i32:
|
||||
embedding_bag_packed_v15::evaluate<ET, ov::element::i32>(op, outputs, inputs);
|
||||
break;
|
||||
case ov::element::i64:
|
||||
embedding_bag_packed_v15::evaluate<ET, ov::element::i64>(op, outputs, inputs);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool evaluate_node<ov::op::v15::EmbeddingBagPacked>(std::shared_ptr<ov::Node> node,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs) {
|
||||
auto element_type = node->get_output_element_type(0);
|
||||
if (ov::is_type<ov::op::v1::Select>(node) || ov::is_type<ov::op::util::BinaryElementwiseComparison>(node))
|
||||
element_type = node->get_input_element_type(1);
|
||||
|
||||
switch (element_type) {
|
||||
case ov::element::boolean:
|
||||
return evaluate<ov::element::boolean>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::bf16:
|
||||
return evaluate<ov::element::bf16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::f16:
|
||||
return evaluate<ov::element::f16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::f64:
|
||||
return evaluate<ov::element::f64>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::f32:
|
||||
return evaluate<ov::element::f32>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::i4:
|
||||
return evaluate<ov::element::i4>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::i8:
|
||||
return evaluate<ov::element::i8>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::i16:
|
||||
return evaluate<ov::element::i16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::i32:
|
||||
return evaluate<ov::element::i32>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::i64:
|
||||
return evaluate<ov::element::i64>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::u1:
|
||||
return evaluate<ov::element::u1>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::u4:
|
||||
return evaluate<ov::element::u4>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::u8:
|
||||
return evaluate<ov::element::u8>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::u16:
|
||||
return evaluate<ov::element::u16>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::u32:
|
||||
return evaluate<ov::element::u32>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
case ov::element::u64:
|
||||
return evaluate<ov::element::u64>(ov::as_type_ptr<ov::op::v15::EmbeddingBagPacked>(node), outputs, inputs);
|
||||
default:
|
||||
OPENVINO_THROW("Unhandled data type ", node->get_element_type().get_type_name(), " in evaluate_node()");
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,8 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/reference/embedding_bag_packed_sum.hpp"
|
||||
|
||||
#include "evaluate_node.hpp"
|
||||
#include "openvino/reference/embedding_bag_packed.hpp"
|
||||
|
||||
namespace embedding_bag_packed_sum_v3 {
|
||||
template <ov::element::Type_t t1, ov::element::Type_t t2>
|
||||
|
|
@ -13,12 +12,13 @@ inline void evaluate(const std::shared_ptr<ov::op::v3::EmbeddingBagPackedSum>& o
|
|||
const ov::TensorVector& inputs) {
|
||||
using T1 = typename ov::element_type_traits<t1>::value_type;
|
||||
using T2 = typename ov::element_type_traits<t2>::value_type;
|
||||
ov::reference::embeddingBagPackedSum<T1, T2>(inputs[0].data<T1>(),
|
||||
inputs[1].data<T2>(),
|
||||
inputs.size() > 2 ? inputs[2].data<T1>() : nullptr,
|
||||
outputs[0].data<T1>(),
|
||||
inputs[1].get_shape(),
|
||||
outputs[0].get_shape());
|
||||
ov::reference::embeddingBagPacked<T1, T2>(inputs[0].data<T1>(),
|
||||
inputs[1].data<T2>(),
|
||||
inputs.size() > 2 ? inputs[2].data<T1>() : nullptr,
|
||||
outputs[0].data<T1>(),
|
||||
inputs[1].get_shape(),
|
||||
outputs[0].get_shape(),
|
||||
ov::op::v3::EmbeddingBagPackedSum::Reduction::SUM);
|
||||
}
|
||||
} // namespace embedding_bag_packed_sum_v3
|
||||
|
||||
|
|
|
|||
|
|
@ -498,6 +498,13 @@ extern template bool evaluate_node<ov::op::v14::ROIAlignRotated>(std::shared_ptr
|
|||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs);
|
||||
|
||||
extern template bool evaluate_node<ov::op::v15::EmbeddingBagOffsets>(std::shared_ptr<ov::Node> node,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs);
|
||||
|
||||
extern template bool evaluate_node<ov::op::v15::EmbeddingBagPacked>(std::shared_ptr<ov::Node> node,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs);
|
||||
extern template bool evaluate_node<ov::op::internal::AUGRUCell>(std::shared_ptr<ov::Node> node,
|
||||
ov::TensorVector& outputs,
|
||||
const ov::TensorVector& inputs);
|
||||
|
|
|
|||
|
|
@ -164,6 +164,9 @@ _OPENVINO_OP_REG(AvgPool, ov::op::v14)
|
|||
_OPENVINO_OP_REG(MaxPool, ov::op::v14)
|
||||
_OPENVINO_OP_REG(ROIAlignRotated, ov::op::v14)
|
||||
|
||||
_OPENVINO_OP_REG(EmbeddingBagOffsets, op::v15)
|
||||
_OPENVINO_OP_REG(EmbeddingBagPacked, op::v15)
|
||||
|
||||
_OPENVINO_OP_REG(AUGRUCell, ov::op::internal)
|
||||
_OPENVINO_OP_REG(AUGRUSequence, ov::op::internal)
|
||||
_OPENVINO_OP_REG(RMSNorm, ov::op::internal)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,275 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "base_reference_test.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
|
||||
using namespace reference_tests;
|
||||
using namespace ov;
|
||||
|
||||
struct EmbeddingBagOffsetsParams {
|
||||
template <class IT>
|
||||
EmbeddingBagOffsetsParams(const ov::Shape& iShape,
|
||||
const ov::element::Type& iType,
|
||||
const std::vector<IT>& iValues,
|
||||
const ov::Shape& oShape,
|
||||
const ov::element::Type& oType,
|
||||
const std::vector<IT>& oValues,
|
||||
const std::shared_ptr<ov::op::v0::Constant>& indices,
|
||||
const std::shared_ptr<ov::op::v0::Constant>& offsets,
|
||||
const ov::op::v15::EmbeddingBagOffsets::Reduction reduction,
|
||||
const std::shared_ptr<ov::op::v0::Constant>& default_index = nullptr,
|
||||
const std::shared_ptr<ov::op::v0::Constant>& per_sample_weights = nullptr)
|
||||
: _iShape(iShape),
|
||||
_iType(iType),
|
||||
_iData(CreateTensor(iShape, iType, iValues)),
|
||||
_refShape(oShape),
|
||||
_refType(oType),
|
||||
_refData(CreateTensor(oShape, oType, oValues)) {
|
||||
_indices = indices;
|
||||
_offsets = offsets;
|
||||
_reduction = reduction;
|
||||
_defaultIndex = default_index;
|
||||
_perSampleWeights = per_sample_weights;
|
||||
}
|
||||
ov::Shape _iShape;
|
||||
ov::element::Type _iType;
|
||||
ov::Tensor _iData;
|
||||
|
||||
ov::Shape _refShape;
|
||||
ov::element::Type _refType;
|
||||
ov::Tensor _refData;
|
||||
|
||||
std::shared_ptr<ov::op::v0::Constant> _indices;
|
||||
std::shared_ptr<ov::op::v0::Constant> _offsets;
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction _reduction;
|
||||
std::shared_ptr<ov::op::v0::Constant> _defaultIndex; // Optional, default filled zero.
|
||||
std::shared_ptr<ov::op::v0::Constant> _perSampleWeights; // Optional, default is tensor of ones.
|
||||
};
|
||||
|
||||
class ReferenceEmbeddingBagOffsetsLayerTest : public testing::TestWithParam<EmbeddingBagOffsetsParams>,
|
||||
public CommonReferenceTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto params = GetParam();
|
||||
function = CreateFunction(params._iShape,
|
||||
params._iType,
|
||||
params._indices,
|
||||
params._offsets,
|
||||
params._reduction,
|
||||
params._defaultIndex,
|
||||
params._perSampleWeights);
|
||||
inputData = {params._iData};
|
||||
refOutData = {params._refData};
|
||||
}
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<EmbeddingBagOffsetsParams>& obj) {
|
||||
auto param = obj.param;
|
||||
std::ostringstream result;
|
||||
result << "_iShape=" << param._iShape << "_";
|
||||
result << "_iType=" << param._iType << "_";
|
||||
result << "_refShape=" << param._refShape << "_";
|
||||
result << "_refType=" << param._refType << "_";
|
||||
result << "_reduction=" << param._reduction;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::shared_ptr<ov::Model> CreateFunction(const Shape& input_shape,
|
||||
const element::Type& input_type,
|
||||
const std::shared_ptr<ov::op::v0::Constant> indices,
|
||||
const std::shared_ptr<ov::op::v0::Constant> offsets,
|
||||
const ov::op::v15::EmbeddingBagOffsets::Reduction reduction,
|
||||
const std::shared_ptr<ov::op::v0::Constant> default_index,
|
||||
const std::shared_ptr<ov::op::v0::Constant> per_sample_weights) {
|
||||
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
|
||||
|
||||
if (default_index) {
|
||||
if (per_sample_weights) {
|
||||
const auto ess = std::make_shared<op::v15::EmbeddingBagOffsets>(in,
|
||||
indices,
|
||||
offsets,
|
||||
default_index,
|
||||
per_sample_weights,
|
||||
reduction);
|
||||
return std::make_shared<Model>(NodeVector{ess}, ParameterVector{in});
|
||||
} else {
|
||||
const auto ess =
|
||||
std::make_shared<op::v15::EmbeddingBagOffsets>(in, indices, offsets, default_index, reduction);
|
||||
return std::make_shared<Model>(NodeVector{ess}, ParameterVector{in});
|
||||
}
|
||||
} else {
|
||||
const auto ess = std::make_shared<op::v15::EmbeddingBagOffsets>(in, indices, offsets, reduction);
|
||||
return std::make_shared<Model>(NodeVector{ess}, ParameterVector{in});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ReferenceEmbeddingBagOffsetsLayerTest, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_EmbeddingBagOffsets_With_Hardcoded_Refs,
|
||||
ReferenceEmbeddingBagOffsetsLayerTest,
|
||||
::testing::Values(
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::f32,
|
||||
std::vector<float>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f32,
|
||||
{-1.05f, -1.2f, -0.2f, -0.6f, -0.1f, 0.4f},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{0}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::f32,
|
||||
ov::Shape({4}),
|
||||
std::vector<float>{0.5, 0.5, 0.5, 0.5})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-2.1, -2.4, -0.2, -0.6, -0.2, 0.8},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{0})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-6, -4, 0, 0, 2, 18},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{6, 8, 3, 4, 16, 18},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{1})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-2.1, -2.4, 0, 0, -0.2, 0.8},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({4}), std::vector<int64_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({3}), std::vector<int64_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-6, -4, -1, 2, 2, 18},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({4}), std::vector<int64_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({3}), std::vector<int64_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape(), std::vector<int64_t>{0})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::i8,
|
||||
std::vector<int8_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i8,
|
||||
std::vector<int8_t>{-12, -8, -1, 2, 4, 36},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({4}), std::vector<int64_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({3}), std::vector<int64_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape(), std::vector<int64_t>{0}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i8, ov::Shape({4}), std::vector<int8_t>{2, 2, 2, 2})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{6, 8, 1, 2, 16, 18},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::SUM,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{0})),
|
||||
// Reduction MEAN
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-1.05, -1.2, -0.2, -0.6, -0.1, 0.4},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{0})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-3, -2, 0, 0, 1, 9},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{3, 4, 3, 4, 8, 9},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{1})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-1.05, -1.2, 0, 0, -0.1, 0.4},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({4}), std::vector<int64_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({3}), std::vector<int64_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-3, -2, -1, 2, 1, 9},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({4}), std::vector<int64_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape({3}), std::vector<int64_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i64, ov::Shape(), std::vector<int64_t>{0})),
|
||||
EmbeddingBagOffsetsParams(
|
||||
ov::Shape{5, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{3, 4, 1, 2, 8, 9},
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({4}), std::vector<int32_t>{0, 2, 3, 4}),
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape({3}), std::vector<int32_t>{0, 2, 2}),
|
||||
ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN,
|
||||
std::make_shared<ov::op::v0::Constant>(element::i32, ov::Shape(), std::vector<int32_t>{0}))),
|
||||
ReferenceEmbeddingBagOffsetsLayerTest::getTestCaseName);
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "base_reference_test.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
|
||||
using namespace reference_tests;
|
||||
using namespace ov;
|
||||
|
||||
struct EmbeddingBagPackedParams {
|
||||
template <class IT>
|
||||
EmbeddingBagPackedParams(const ov::Shape& iShape,
|
||||
const ov::element::Type& iType,
|
||||
const std::vector<IT>& iValues,
|
||||
const ov::Shape& oShape,
|
||||
const ov::element::Type& oType,
|
||||
const std::vector<IT>& oValues,
|
||||
const std::shared_ptr<ov::op::v0::Constant>& indices,
|
||||
const ov::op::v15::EmbeddingBagPacked::Reduction reduction,
|
||||
const std::shared_ptr<ov::op::v0::Constant>& per_sample_weights = nullptr)
|
||||
: _iShape(iShape),
|
||||
_iType(iType),
|
||||
_iData(CreateTensor(iShape, iType, iValues)),
|
||||
_refShape(oShape),
|
||||
_refType(oType),
|
||||
_refData(CreateTensor(oShape, oType, oValues)) {
|
||||
_indices = indices;
|
||||
_reduction = reduction;
|
||||
_perSampleWeights = per_sample_weights;
|
||||
}
|
||||
ov::Shape _iShape;
|
||||
ov::element::Type _iType;
|
||||
ov::Tensor _iData;
|
||||
|
||||
ov::Shape _refShape;
|
||||
ov::element::Type _refType;
|
||||
ov::Tensor _refData;
|
||||
|
||||
std::shared_ptr<ov::op::v0::Constant> _indices;
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction _reduction;
|
||||
std::shared_ptr<ov::op::v0::Constant> _perSampleWeights; // Optional, default is tensor of ones.
|
||||
};
|
||||
|
||||
class ReferenceEmbeddingBagPackedLayerTest : public testing::TestWithParam<EmbeddingBagPackedParams>,
|
||||
public CommonReferenceTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto params = GetParam();
|
||||
function =
|
||||
CreateFunction(params._iShape, params._iType, params._indices, params._reduction, params._perSampleWeights);
|
||||
inputData = {params._iData};
|
||||
refOutData = {params._refData};
|
||||
}
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<EmbeddingBagPackedParams>& obj) {
|
||||
auto param = obj.param;
|
||||
std::ostringstream result;
|
||||
result << "_iShape=" << param._iShape << "_";
|
||||
result << "_iType=" << param._iType << "_";
|
||||
result << "_refShape=" << param._refShape << "_";
|
||||
result << "_refType=" << param._refType << "_";
|
||||
result << "_reduction=" << param._reduction;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::shared_ptr<Model> CreateFunction(const Shape& input_shape,
|
||||
const element::Type& input_type,
|
||||
const std::shared_ptr<ov::op::v0::Constant> indices,
|
||||
const ov::op::v15::EmbeddingBagPacked::Reduction reduction,
|
||||
const std::shared_ptr<ov::op::v0::Constant> per_sample_weights) {
|
||||
const auto in = std::make_shared<op::v0::Parameter>(input_type, input_shape);
|
||||
|
||||
if (per_sample_weights) {
|
||||
const auto ess = std::make_shared<op::v15::EmbeddingBagPacked>(in, indices, per_sample_weights, reduction);
|
||||
return std::make_shared<Model>(NodeVector{ess}, ParameterVector{in});
|
||||
} else {
|
||||
const auto ess = std::make_shared<op::v15::EmbeddingBagPacked>(in, indices, reduction);
|
||||
return std::make_shared<Model>(NodeVector{ess}, ParameterVector{in});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ReferenceEmbeddingBagPackedLayerTest, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::shared_ptr<ov::op::v0::Constant> CreateConstant(const std::vector<std::vector<T>>& val,
|
||||
const ov::element::Type& element_type) {
|
||||
if (val.size() > 0) {
|
||||
ov::Shape i_shape({val.size(), val[0].size()});
|
||||
|
||||
size_t i_size = ov::shape_size(i_shape);
|
||||
std::vector<T> i_values(i_size);
|
||||
|
||||
for (size_t i = 0; i < i_shape[0]; i++) {
|
||||
for (size_t j = 0; j < i_shape[1]; j++) {
|
||||
i_values[i * i_shape[1] + j] = val[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<ov::op::v0::Constant>(element_type, i_shape, i_values);
|
||||
} else {
|
||||
return std::make_shared<ov::op::v0::Constant>(element_type, ov::Shape(), std::vector<T>());
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_EmbeddingBagPacked_With_Hardcoded_Refs,
|
||||
ReferenceEmbeddingBagPackedLayerTest,
|
||||
::testing::Values(
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::f32,
|
||||
std::vector<float>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f32,
|
||||
std::vector<float>{-1.05f, -1.2f, -1.f, -1.1f, -0.1f, 0.4f},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM,
|
||||
CreateConstant<float>({{0.5, 0.5}, {0.5, 0.5}, {0.5, 0.5}}, element::f32)),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-2.1, -2.4, -2.0, -2.2, -0.2, 0.8},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-6, -4, -2, -2, 2, 18},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{6, 8, 8, 10, 16, 18},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-2.1, -2.4, -2.0, -2.2, -0.2, 0.8},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-6, -4, -2, -2, 2, 18},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::i8,
|
||||
std::vector<int8_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i8,
|
||||
std::vector<int8_t>{-12, -8, -4, -4, 4, 36},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM,
|
||||
CreateConstant<int8_t>({{2, 2}, {2, 2}, {2, 2}}, element::i8)),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{6, 8, 8, 10, 16, 18},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::SUM),
|
||||
// Reduction MEAN
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f64,
|
||||
std::vector<double>{-1.05, -1.2, -1., -1.1, -0.1, 0.4},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::MEAN),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i32,
|
||||
std::vector<int32_t>{-3, -2, -1, -1, 1, 9},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::MEAN),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u32,
|
||||
std::vector<uint32_t>{3, 4, 4, 5, 8, 9},
|
||||
CreateConstant<int32_t>({{0, 2}, {1, 2}, {3, 4}}, element::i32),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::MEAN),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-0.2, -0.6, -0.1, -0.4, -1.9, -1.8, -1., 1.5, 0.8, -0.7},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::f16,
|
||||
std::vector<float16>{-1.05, -1.2, -1.0, -1.1, -0.1, 0.4},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::MEAN),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-1, 2, 3, 4, -5, -6, -7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::i64,
|
||||
std::vector<int64_t>{-3, -2, -1, -1, 1, 9},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::MEAN),
|
||||
EmbeddingBagPackedParams(ov::Shape{5, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
ov::Shape{3, 2},
|
||||
ov::element::u8,
|
||||
std::vector<uint8_t>{3, 4, 4, 5, 8, 9},
|
||||
CreateConstant<int64_t>({{0, 2}, {1, 2}, {3, 4}}, element::i64),
|
||||
ov::op::v15::EmbeddingBagPacked::Reduction::MEAN)),
|
||||
ReferenceEmbeddingBagPackedLayerTest::getTestCaseName);
|
||||
|
|
@ -1790,14 +1790,17 @@ std::shared_ptr<ov::Model> generateEmbeddingBagOffsetsBase(const std::shared_ptr
|
|||
const auto offsets = std::make_shared<ov::op::v0::Constant>(utils::create_and_fill_tensor(ov::element::i32, ov::Shape{3}));
|
||||
const auto default_index = std::make_shared<ov::op::v0::Constant>(ov::element::i32, ov::Shape(), std::vector<int32_t>{0});
|
||||
|
||||
std::shared_ptr<ov::Node> EmbeddingBagOffsetsSumNode;
|
||||
std::shared_ptr<ov::Node> EmbeddingBagOffsetsNode;
|
||||
if (ov::is_type<ov::op::v3::EmbeddingBagOffsetsSum>(node)) {
|
||||
EmbeddingBagOffsetsSumNode = std::make_shared<ov::op::v3::EmbeddingBagOffsetsSum>(params.at(0), indices, offsets, default_index);
|
||||
EmbeddingBagOffsetsNode = std::make_shared<ov::op::v3::EmbeddingBagOffsetsSum>(params.at(0), indices, offsets, default_index);
|
||||
} else if (ov::is_type<ov::op::v15::EmbeddingBagOffsets>(node)) {
|
||||
const auto reduction = ov::op::v15::EmbeddingBagOffsets::Reduction::MEAN;
|
||||
EmbeddingBagOffsetsNode = std::make_shared<ov::op::v15::EmbeddingBagOffsets>(params.at(0), indices, offsets, default_index, reduction);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(EmbeddingBagOffsetsSumNode)};
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(EmbeddingBagOffsetsNode)};
|
||||
return std::make_shared<ov::Model>(results, params, "EmbeddingBagOffsetsBaseGraph");
|
||||
}
|
||||
|
||||
|
|
@ -1805,14 +1808,17 @@ std::shared_ptr<ov::Model> generateEmbeddingBagPackedBase(const std::shared_ptr<
|
|||
ov::ParameterVector params{std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::Shape{{5, 2}})};
|
||||
const auto indices = std::make_shared<ov::op::v0::Constant>(utils::create_and_fill_tensor(ov::element::i32, ov::Shape{2, 3}));
|
||||
|
||||
std::shared_ptr<ov::Node> EmbeddingBagPackedSumNode;
|
||||
std::shared_ptr<ov::Node> EmbeddingBagPackedNode;
|
||||
if (ov::is_type<ov::op::v3::EmbeddingBagPackedSum>(node)) {
|
||||
EmbeddingBagPackedSumNode = std::make_shared<ov::op::v3::EmbeddingBagPackedSum>(params.at(0), indices);
|
||||
EmbeddingBagPackedNode = std::make_shared<ov::op::v3::EmbeddingBagPackedSum>(params.at(0), indices);
|
||||
} else if (ov::is_type<ov::op::v15::EmbeddingBagPacked>(node)) {
|
||||
const auto reduction = ov::op::v15::EmbeddingBagPacked::Reduction::SUM;
|
||||
EmbeddingBagPackedNode = std::make_shared<ov::op::v15::EmbeddingBagPacked>(params.at(0), indices, reduction);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(EmbeddingBagPackedSumNode)};
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(EmbeddingBagPackedNode)};
|
||||
return std::make_shared<ov::Model>(results, params, "EmbeddingBagPackedBaseGraph");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ CompareMap getCompareMap() {
|
|||
#include "openvino/opsets/opset12_tbl.hpp"
|
||||
#include "openvino/opsets/opset13_tbl.hpp"
|
||||
#include "openvino/opsets/opset14_tbl.hpp"
|
||||
#include "openvino/opsets/opset15_tbl.hpp"
|
||||
|
||||
#include "ov_ops/opset_private_tbl.hpp"
|
||||
#undef _OPENVINO_OP_REG
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,8 @@ InputsMap getInputMap() {
|
|||
#include "openvino/opsets/opset11_tbl.hpp"
|
||||
#include "openvino/opsets/opset12_tbl.hpp"
|
||||
#include "openvino/opsets/opset13_tbl.hpp"
|
||||
#include "openvino/opsets/opset14_tbl.hpp"
|
||||
#include "openvino/opsets/opset15_tbl.hpp"
|
||||
|
||||
#include "ov_ops/opset_private_tbl.hpp"
|
||||
#undef _OPENVINO_OP_REG
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/node.hpp"
|
||||
#include "openvino/op/util/embeddingbag_offsets_base.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace utils {
|
||||
std::shared_ptr<ov::Node> make_embedding_bag_offsets(const element::Type& data_type,
|
||||
const ov::element::Type& indices_type,
|
||||
const ov::Output<Node>& emb_table_node,
|
||||
const std::vector<size_t>& indices,
|
||||
const std::vector<size_t>& offsets,
|
||||
size_t default_index,
|
||||
bool with_weights,
|
||||
bool with_default_index,
|
||||
ov::op::util::EmbeddingBagOffsetsBase::Reduction reduction);
|
||||
} // namespace utils
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/node.hpp"
|
||||
#include "openvino/op/util/embeddingbag_packed_base.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace utils {
|
||||
std::shared_ptr<ov::Node> make_embedding_bag_packed(const ov::element::Type& data_type,
|
||||
const ov::element::Type& indices_type,
|
||||
const ov::Output<Node>& emb_table_node,
|
||||
const std::vector<std::vector<size_t>>& indices,
|
||||
bool with_weights,
|
||||
ov::op::util::EmbeddingBagPackedBase::Reduction reduction);
|
||||
} // namespace utils
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "common_test_utils/node_builders/embedding_bag_offsets.hpp"
|
||||
|
||||
#include "common_test_utils/ov_tensor_utils.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
#include "openvino/op/embeddingbag_offsets.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace utils {
|
||||
std::shared_ptr<ov::Node> make_embedding_bag_offsets(const element::Type& data_type,
|
||||
const ov::element::Type& indices_type,
|
||||
const ov::Output<Node>& emb_table_node,
|
||||
const std::vector<size_t>& indices,
|
||||
const std::vector<size_t>& offsets,
|
||||
size_t default_index,
|
||||
bool with_weights,
|
||||
bool with_default_index,
|
||||
ov::op::util::EmbeddingBagOffsetsBase::Reduction reduction) {
|
||||
ov::Shape i_shape = {indices.size()};
|
||||
auto indices_node = std::make_shared<ov::op::v0::Constant>(indices_type, i_shape, indices);
|
||||
ov::Shape o_shape = {offsets.size()};
|
||||
auto offsetsNode = std::make_shared<ov::op::v0::Constant>(indices_type, o_shape, offsets);
|
||||
|
||||
std::shared_ptr<Node> embBag;
|
||||
if (with_default_index) {
|
||||
auto defIdxNode = std::make_shared<ov::op::v0::Constant>(indices_type, ov::Shape{}, default_index);
|
||||
if (with_weights) {
|
||||
auto tensor = create_and_fill_tensor(data_type, ov::Shape{indices.size()});
|
||||
auto weights_node = std::make_shared<ov::op::v0::Constant>(tensor);
|
||||
|
||||
embBag = std::make_shared<ov::op::v15::EmbeddingBagOffsets>(emb_table_node,
|
||||
indices_node,
|
||||
offsetsNode,
|
||||
defIdxNode,
|
||||
weights_node,
|
||||
reduction);
|
||||
} else {
|
||||
embBag = std::make_shared<ov::op::v15::EmbeddingBagOffsets>(emb_table_node,
|
||||
indices_node,
|
||||
offsetsNode,
|
||||
defIdxNode,
|
||||
reduction);
|
||||
}
|
||||
} else {
|
||||
embBag =
|
||||
std::make_shared<ov::op::v15::EmbeddingBagOffsets>(emb_table_node, indices_node, offsetsNode, reduction);
|
||||
}
|
||||
return embBag;
|
||||
}
|
||||
} // namespace utils
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "common_test_utils/node_builders/embedding_bag_packed.hpp"
|
||||
|
||||
#include "common_test_utils/ov_tensor_utils.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
#include "openvino/op/embeddingbag_packed.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace utils {
|
||||
std::shared_ptr<ov::Node> make_embedding_bag_packed(const ov::element::Type& data_type,
|
||||
const ov::element::Type& indices_type,
|
||||
const ov::Output<Node>& emb_table_node,
|
||||
const std::vector<std::vector<size_t>>& indices,
|
||||
bool with_weights,
|
||||
ov::op::util::EmbeddingBagPackedBase::Reduction reduction) {
|
||||
ov::Shape i_shape({indices.size(), indices[0].size()});
|
||||
size_t i_size = ov::shape_size(i_shape);
|
||||
std::vector<size_t> i_values(i_size);
|
||||
for (int i = 0; i < indices.size(); i++)
|
||||
memcpy(i_values.data() + indices[0].size() * i, indices[i].data(), indices[0].size() * sizeof(size_t));
|
||||
auto indicesNode = std::make_shared<ov::op::v0::Constant>(indices_type, i_shape, i_values);
|
||||
|
||||
std::shared_ptr<Node> embBag;
|
||||
if (with_weights) {
|
||||
auto tensor = create_and_fill_tensor(data_type, i_shape);
|
||||
auto weights_node = std::make_shared<ov::op::v0::Constant>(tensor);
|
||||
|
||||
embBag =
|
||||
std::make_shared<ov::op::v15::EmbeddingBagPacked>(emb_table_node, indicesNode, weights_node, reduction);
|
||||
} else {
|
||||
embBag = std::make_shared<ov::op::v15::EmbeddingBagPacked>(emb_table_node, indicesNode, reduction);
|
||||
}
|
||||
return embBag;
|
||||
}
|
||||
} // namespace utils
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -11,89 +11,228 @@ from pytorch_layer_test_class import PytorchLayerTest
|
|||
class TestEmbeddingBag1dOffsets(PytorchLayerTest):
|
||||
def _prepare_input(self, indicies_dtype, per_sample_weights=False):
|
||||
import numpy as np
|
||||
|
||||
indices = np.array([2, 2, 2, 2, 4, 3, 2, 9]).astype(indicies_dtype)
|
||||
weights = np.random.randn(10, 10).astype(np.float32)
|
||||
offsets = np.array([0, 4]).astype(indicies_dtype)
|
||||
if per_sample_weights:
|
||||
per_sample_weights = np.random.randn(
|
||||
*indices.shape).astype(np.float32)
|
||||
per_sample_weights = np.random.randn(*indices.shape).astype(np.float32)
|
||||
return (indices, weights, offsets, per_sample_weights)
|
||||
return (indices, weights, offsets)
|
||||
|
||||
def create_model(self, per_sample_weights):
|
||||
def create_model(self, mode, per_sample_weights):
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
class aten_embedding_bag(torch.nn.Module):
|
||||
def __init__(self, per_sample_weights=False) -> None:
|
||||
def __init__(self, mode=None, per_sample_weights=False) -> None:
|
||||
super().__init__()
|
||||
self.mode = mode
|
||||
if per_sample_weights:
|
||||
self.forward = self.forward_offsets_per_sample_weights
|
||||
|
||||
def forward(self, indicies, weight, offsets):
|
||||
return F.embedding_bag(indicies, weight, offsets, mode="sum")
|
||||
return F.embedding_bag(indicies, weight, offsets, mode=self.mode)
|
||||
|
||||
def forward_offsets_per_sample_weights(self, indicies, weight, offsets, per_sample_wights):
|
||||
return F.embedding_bag(indicies, weight, offsets, mode="sum", per_sample_weights=per_sample_wights)
|
||||
def forward_offsets_per_sample_weights(
|
||||
self, indicies, weight, offsets, per_sample_wights
|
||||
):
|
||||
return F.embedding_bag(
|
||||
indicies,
|
||||
weight,
|
||||
offsets,
|
||||
mode=self.mode,
|
||||
per_sample_weights=per_sample_wights,
|
||||
)
|
||||
|
||||
ref_net = None
|
||||
|
||||
return aten_embedding_bag(per_sample_weights), ref_net, "aten::embedding_bag"
|
||||
return (
|
||||
aten_embedding_bag(mode, per_sample_weights),
|
||||
ref_net,
|
||||
"aten::embedding_bag",
|
||||
)
|
||||
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.precommit
|
||||
@pytest.mark.precommit_fx_backend
|
||||
@pytest.mark.parametrize("indicies_dtype", ["int", "int32"])
|
||||
@pytest.mark.parametrize("per_sample_weights", [True, False])
|
||||
@pytest.mark.xfail(condition=platform.system() == 'Darwin' and platform.machine() == 'arm64',
|
||||
reason='Ticket - 122715')
|
||||
def test_embedding_bag(self, ie_device, precision, ir_version, indicies_dtype, per_sample_weights):
|
||||
self._test(*self.create_model(per_sample_weights), ie_device, precision, ir_version,
|
||||
kwargs_to_prepare_input={"indicies_dtype": indicies_dtype, "per_sample_weights": per_sample_weights},
|
||||
trace_model=True, dynamic_shapes=not per_sample_weights and ie_device != "GPU")
|
||||
@pytest.mark.parametrize(
|
||||
"mode, per_sample_weights", [("mean", False), ("sum", False), ("sum", True)]
|
||||
)
|
||||
@pytest.mark.xfail(
|
||||
condition=platform.system() == "Darwin" and platform.machine() == "arm64",
|
||||
reason="Ticket - 122715",
|
||||
)
|
||||
def test_embedding_bag(
|
||||
self, ie_device, precision, ir_version, indicies_dtype, mode, per_sample_weights
|
||||
):
|
||||
self._test(
|
||||
*self.create_model(mode, per_sample_weights),
|
||||
ie_device,
|
||||
precision,
|
||||
ir_version,
|
||||
kwargs_to_prepare_input={
|
||||
"indicies_dtype": indicies_dtype,
|
||||
"per_sample_weights": per_sample_weights,
|
||||
},
|
||||
trace_model=True,
|
||||
dynamic_shapes=not per_sample_weights and ie_device != "GPU"
|
||||
)
|
||||
|
||||
|
||||
class TestEmbeddingBag2d(PytorchLayerTest):
|
||||
def _prepare_input(self, indicies_size, indicies_dtype, per_sample_weights):
|
||||
import numpy as np
|
||||
indices = np.random.randint(
|
||||
0, 9, size=indicies_size).astype(indicies_dtype)
|
||||
|
||||
indices = np.random.randint(0, 9, size=indicies_size).astype(indicies_dtype)
|
||||
weights = np.random.randn(10, 10).astype(np.float32)
|
||||
if per_sample_weights:
|
||||
per_sample_weights = np.random.randn(
|
||||
*indices.shape).astype(np.float32)
|
||||
per_sample_weights = np.random.randn(*indices.shape).astype(np.float32)
|
||||
return (indices, weights, per_sample_weights)
|
||||
return (indices, weights)
|
||||
|
||||
def create_model(self, per_sample_weights):
|
||||
def create_model(self, mode, per_sample_weights):
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
class aten_embedding_bag(torch.nn.Module):
|
||||
def __init__(self, per_sample_weights=False) -> None:
|
||||
def __init__(self, mode=None, per_sample_weights=False) -> None:
|
||||
super().__init__()
|
||||
self.mode = mode
|
||||
if per_sample_weights:
|
||||
self.forward = self.forward_per_sample_weights
|
||||
|
||||
def forward(self, indicies, weight):
|
||||
return F.embedding_bag(indicies, weight, mode="sum")
|
||||
return F.embedding_bag(indicies, weight, mode=self.mode)
|
||||
|
||||
def forward_per_sample_weights(self, indicies, weight, per_sample_wights):
|
||||
return F.embedding_bag(indicies, weight, mode="sum", per_sample_weights=per_sample_wights)
|
||||
return F.embedding_bag(
|
||||
indicies,
|
||||
weight,
|
||||
mode=self.mode,
|
||||
per_sample_weights=per_sample_wights,
|
||||
)
|
||||
|
||||
ref_net = None
|
||||
|
||||
return aten_embedding_bag(per_sample_weights), ref_net, "aten::embedding_bag"
|
||||
return (
|
||||
aten_embedding_bag(mode, per_sample_weights),
|
||||
ref_net,
|
||||
"aten::embedding_bag",
|
||||
)
|
||||
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.precommit
|
||||
@pytest.mark.precommit_fx_backend
|
||||
@pytest.mark.parametrize("indicies_size", [[1, 1], [2, 5], [3, 10], [4, 7]])
|
||||
@pytest.mark.parametrize("indicies_dtype", ["int", "int32"])
|
||||
@pytest.mark.parametrize("per_sample_weights", [True, False])
|
||||
@pytest.mark.xfail(condition=platform.system() == 'Darwin' and platform.machine() == 'arm64',
|
||||
reason='Ticket - 122715')
|
||||
def test_embedding_bag(self, ie_device, precision, ir_version, indicies_dtype, indicies_size, per_sample_weights):
|
||||
self._test(*self.create_model(per_sample_weights), ie_device, precision, ir_version,
|
||||
kwargs_to_prepare_input={"indicies_size": indicies_size, "indicies_dtype": indicies_dtype, "per_sample_weights": per_sample_weights},
|
||||
trace_model=True, dynamic_shapes=not per_sample_weights and ie_device != "GPU")
|
||||
@pytest.mark.parametrize(
|
||||
"mode, per_sample_weights", [("mean", False), ("sum", False), ("sum", True)]
|
||||
)
|
||||
@pytest.mark.xfail(
|
||||
condition=platform.system() == "Darwin" and platform.machine() == "arm64",
|
||||
reason="Ticket - 122715",
|
||||
)
|
||||
def test_embedding_bag(
|
||||
self,
|
||||
ie_device,
|
||||
precision,
|
||||
ir_version,
|
||||
indicies_dtype,
|
||||
indicies_size,
|
||||
mode,
|
||||
per_sample_weights,
|
||||
):
|
||||
self._test(
|
||||
*self.create_model(mode, per_sample_weights),
|
||||
ie_device,
|
||||
precision,
|
||||
ir_version,
|
||||
kwargs_to_prepare_input={
|
||||
"indicies_size": indicies_size,
|
||||
"indicies_dtype": indicies_dtype,
|
||||
"per_sample_weights": per_sample_weights,
|
||||
},
|
||||
trace_model=True,
|
||||
dynamic_shapes=not per_sample_weights and ie_device != "GPU"
|
||||
)
|
||||
|
||||
|
||||
class TestEmbeddingBagPretrained(PytorchLayerTest):
|
||||
def _prepare_input(self, indicies_size, indicies_dtype, per_sample_weights):
|
||||
import numpy as np
|
||||
|
||||
indices = np.random.randint(0, 9, size=indicies_size).astype(indicies_dtype)
|
||||
if per_sample_weights:
|
||||
per_sample_weights = np.random.randn(*indices.shape).astype(np.float32)
|
||||
return (indices, per_sample_weights)
|
||||
return (indices,)
|
||||
|
||||
def create_model(self, mode, per_sample_weights):
|
||||
import torch
|
||||
import numpy as np
|
||||
|
||||
class aten_embedding_bag(torch.nn.Module):
|
||||
def __init__(self, mode=None, per_sample_weights=False) -> None:
|
||||
super().__init__()
|
||||
self.mode = mode
|
||||
weights = torch.from_numpy(np.random.randn(10, 10).astype(np.float32))
|
||||
|
||||
self.embeddings = torch.nn.EmbeddingBag.from_pretrained(
|
||||
weights, mode=mode
|
||||
)
|
||||
if per_sample_weights:
|
||||
self.forward = self.forward_per_sample_weights
|
||||
|
||||
def forward(self, indicies):
|
||||
return self.embeddings(indicies)
|
||||
|
||||
def forward_per_sample_weights(self, indicies, per_sample_wights):
|
||||
return (
|
||||
self.embeddings(indicies, per_sample_weights=per_sample_wights),
|
||||
)
|
||||
|
||||
ref_net = None
|
||||
|
||||
return (
|
||||
aten_embedding_bag(mode, per_sample_weights),
|
||||
ref_net,
|
||||
"aten::embedding_bag",
|
||||
)
|
||||
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.precommit
|
||||
@pytest.mark.precommit_fx_backend
|
||||
@pytest.mark.parametrize("indicies_size", [[1, 1], [2, 5], [3, 10], [4, 7]])
|
||||
@pytest.mark.parametrize("indicies_dtype", ["int", "int32"])
|
||||
@pytest.mark.parametrize(
|
||||
"mode, per_sample_weights", [("mean", False), ("sum", False), ("sum", True)]
|
||||
)
|
||||
@pytest.mark.xfail(
|
||||
condition=platform.system() == "Darwin" and platform.machine() == "arm64",
|
||||
reason="Ticket - 122715",
|
||||
)
|
||||
def test_embedding_bag(
|
||||
self,
|
||||
ie_device,
|
||||
precision,
|
||||
ir_version,
|
||||
indicies_dtype,
|
||||
indicies_size,
|
||||
mode,
|
||||
per_sample_weights,
|
||||
):
|
||||
self._test(
|
||||
*self.create_model(mode, per_sample_weights),
|
||||
ie_device,
|
||||
precision,
|
||||
ir_version,
|
||||
kwargs_to_prepare_input={
|
||||
"indicies_size": indicies_size,
|
||||
"indicies_dtype": indicies_dtype,
|
||||
"per_sample_weights": per_sample_weights,
|
||||
},
|
||||
trace_model=True,
|
||||
dynamic_shapes=not per_sample_weights and ie_device != "GPU"
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue