[GPU] Eltwise new shape infer (#12897) (#12897)

This commit is contained in:
Paul Youngsoo Ahn
2022-09-16 11:51:52 +09:00
committed by GitHub
parent 5e977fc470
commit 0bc85f820e
8 changed files with 392 additions and 19 deletions

View File

@@ -72,17 +72,18 @@ struct eltwise : public primitive_base<eltwise> {
/// @param input Input primitive id.
/// @param input2 Second input primitive id with values needed for eltwise computation.
/// @param mode Eltwise mode.
/// @param with_activation Enables Relu activation.
/// @param activation_slp Relu activation slope.
/// @param spec Auto broadcast rule specificiation.
eltwise(const primitive_id& id,
const primitive_id& input,
const primitive_id& input2,
eltwise_mode mode,
const ov::op::AutoBroadcastSpec& spec = ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY),
const padding& output_padding = padding())
: primitive_base(id, {input, input2}, output_padding),
mode(mode),
coefficients(std::vector<float>(0)),
stride(std::vector<tensor>(0)) {}
stride(std::vector<tensor>(0)),
broadcast_spec(spec.m_type, spec.m_axis) { }
/// @brief Constructs eltwise primitive.
/// @param id This primitive id.
@@ -90,62 +91,73 @@ struct eltwise : public primitive_base<eltwise> {
/// @param input2 Second input primitive id with values needed for eltwise computation.
/// @param stride Defines shift in input buffers between adjacent calculations of output values.
/// @param mode Eltwise mode.
/// @param with_activation Enables Relu activation.
/// @param activation_slp Relu activation slope.
/// @param spec Auto broadcast rule specificiation.
eltwise(const primitive_id& id,
const primitive_id& input,
const primitive_id& input2,
std::vector<tensor> stride,
eltwise_mode mode,
const ov::op::AutoBroadcastSpec& spec = ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY),
const padding& output_padding = padding())
: primitive_base(id, {input, input2}, output_padding),
mode(mode),
coefficients(std::vector<float>(0)),
stride(stride) {}
stride(stride),
broadcast_spec(spec.m_type, spec.m_axis) { }
/// @brief Constructs eltwise primitive.
/// @param id This primitive id.
/// @param inputs Input primitives ids.
/// @param mode Eltwise mode.
/// @param data_type Expected output data type.
/// @param spec Auto broadcast rule specificiation.
eltwise(const primitive_id& id,
const std::vector<primitive_id>& inputs,
eltwise_mode mode,
data_types data_type,
const ov::op::AutoBroadcastSpec& spec = ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY),
const padding& output_padding = padding())
: primitive_base(id, inputs, output_padding, optional_data_type{data_type}),
mode(mode),
coefficients(std::vector<float>(0)),
stride(std::vector<tensor>(0)) {}
stride(std::vector<tensor>(0)),
broadcast_spec(spec.m_type, spec.m_axis) { }
/// @brief Constructs eltwise primitive.
/// @param id This primitive id.
/// @param inputs Input primitives ids.
/// @param mode Eltwise mode.
/// @param spec Auto broadcast rule specificiation.
eltwise(const primitive_id& id,
const std::vector<primitive_id>& inputs,
eltwise_mode mode,
const ov::op::AutoBroadcastSpec& spec = ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY),
const padding& output_padding = padding())
: primitive_base(id, inputs, output_padding),
mode(mode),
coefficients(std::vector<float>(0)),
stride(std::vector<tensor>(0)) {}
stride(std::vector<tensor>(0)),
broadcast_spec(spec.m_type, spec.m_axis) { }
/// @brief Constructs eltwise primitive.
/// @param id This primitive id.
/// @param inputs Input primitives ids.
/// @param coefficients Blob-wise coefficient for SUM operation
/// @param mode Eltwise mode.
/// @param coefficients Blob-wise coefficient for SUM operation
/// @param data_type Expected output data type.
/// @param spec Auto broadcast rule specificiation.
eltwise(const primitive_id& id,
const std::vector<primitive_id>& inputs,
eltwise_mode mode,
const std::vector<float>& coefficients,
data_types data_type,
const ov::op::AutoBroadcastSpec& spec = ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY),
const padding& output_padding = padding())
: primitive_base(id, inputs, output_padding, optional_data_type{data_type}),
mode(mode),
coefficients(coefficients),
stride(std::vector<tensor>(0)) {
stride(std::vector<tensor>(0)),
broadcast_spec(spec.m_type, spec.m_axis) {
if (mode == eltwise_mode::sum && !coefficients.empty() && coefficients.size() != inputs.size()) {
throw std::invalid_argument("Invalid eltwise sum coefficients count (should be equal to 0 or input.size)");
}
@@ -160,6 +172,8 @@ struct eltwise : public primitive_base<eltwise> {
std::vector<float> coefficients;
/// @brief Defines shift in input buffers between adjacent calculations of output values.
std::vector<tensor> stride;
/// @brief Define auto broadcast rule specification.
ov::op::AutoBroadcastSpec broadcast_spec;
};
/// @}
/// @}

View File

@@ -107,6 +107,146 @@ layout eltwise_inst::calc_output_layout(eltwise_node const& node, kernel_impl_pa
return output_layout;
}
template<typename ShapeType>
std::vector<layout> eltwise_inst::calc_output_layouts(eltwise_node const& /*node*/, kernel_impl_params const& impl_param) {
auto desc = impl_param.typed_desc<eltwise>();
auto input_layout = impl_param.get_non_padded_input_layout(impl_param.primary_input_idx);
auto out_data_type = desc->output_data_type.value_or(input_layout.data_type);
auto get_output_layout = [&]() {
const auto& autob = desc->broadcast_spec;
auto out_pshape = input_layout.get<ShapeType>();
cldnn::format out_format = input_layout.format;
if (input_layout.format == format::b_fs_zyx_fsv16) // use optimized 5D
out_format = format::b_fs_zyx_fsv16;
else if (input_layout.format == format::bs_fs_zyx_bsv16_fsv16)
out_format = format::bs_fs_zyx_bsv16_fsv16;
for (size_t i = 0; i < impl_param.input_layouts.size(); i++) {
if (impl_param.primary_input_idx == i)
continue;
auto l = impl_param.get_non_padded_input_layout(i);
auto in_pshape = l.get<ShapeType>();
if (autob.m_type == ov::op::AutoBroadcastType::NONE) {
OPENVINO_ASSERT(ShapeType::merge_into(out_pshape, in_pshape), desc->id + ": Argument shapes are inconsistent.\n");
} else if (autob.m_type == ov::op::AutoBroadcastType::NUMPY || autob.m_type == ov::op::AutoBroadcastType::PDPD) {
auto origin_out_pshape = out_pshape;
// For out_pshape{2,3,15,1} and int_pshae{1,3},
// expected output shape for NUMPY should be out_pshape{2,3,15,1} but the actual output will be {2,3,15,3}
// So, fill the rank with default dim(1) for shape which has smaller rank.
if (autob.m_type == ov::op::AutoBroadcastType::NUMPY
&& out_pshape.rank().is_static() && in_pshape.rank().is_static()
&& out_pshape.rank() != in_pshape.rank()) {
ov::Dimension default_dim(1);
const auto in_pshape_rank = in_pshape.rank().get_length();
const auto out_pshape_rank = out_pshape.rank().get_length();
auto new_rank = std::max(in_pshape_rank, out_pshape_rank);
for (auto i = in_pshape_rank; i < new_rank; i++) {
in_pshape.push_back(default_dim);
}
for (auto i = out_pshape_rank; i < new_rank; i++) {
out_pshape.push_back(default_dim);
}
}
if (!ShapeType::broadcast_merge_into(out_pshape, in_pshape, autob)) {
// Temporarily add codes which get output shape using max value from each dimension to pass some legacy functional tests.
// IE_THROW() << desc->id << ": incorrect input shapes (" << out_pshape << " & " << in_pshape << ")\n" << str_endline;
out_pshape = origin_out_pshape;
if (out_pshape.is_static() && in_pshape.is_static()) {
auto in_shape = in_pshape.to_shape();
auto out_shape = out_pshape.to_shape();
for (size_t i = 0; i < in_shape.size(); i++) {
out_shape[i] = std::max(out_shape[i], in_shape[i]);
}
out_pshape = ShapeType(out_shape);
} else {
if (in_pshape.rank().is_static()) {
out_pshape = ShapeType::dynamic(in_pshape.rank());
}
}
}
} else {
OPENVINO_ASSERT(false, desc->id + ": Unsupported auto broadcast specification\n");
}
if (l.format == format::b_fs_zyx_fsv16) // use optimized 5D
out_format = format::b_fs_zyx_fsv16;
else if (l.format == format::bs_fs_zyx_bsv16_fsv16)
out_format = format::bs_fs_zyx_bsv16_fsv16;
}
return layout(out_pshape, out_data_type, out_format);
};
auto output_layout = get_output_layout();
auto mode = desc->mode;
// list of operations supported for integer types
if (input_layout.data_type == data_types::i8 || input_layout.data_type == data_types::u8 ||
input_layout.data_type == data_types::i32 || input_layout.data_type == data_types::i64) {
std::vector<eltwise_mode> eltwise_int_modes = {eltwise_mode::sum,
eltwise_mode::sub,
eltwise_mode::prod,
eltwise_mode::div,
eltwise_mode::min,
eltwise_mode::max,
eltwise_mode::mod,
eltwise_mode::eq,
eltwise_mode::ne,
eltwise_mode::lt,
eltwise_mode::le,
eltwise_mode::gt,
eltwise_mode::ge,
eltwise_mode::squared_diff,
eltwise_mode::floor_mod,
eltwise_mode::logic_and,
eltwise_mode::logic_or,
eltwise_mode::logic_xor};
OPENVINO_ASSERT((std::find(eltwise_int_modes.begin(), eltwise_int_modes.end(), mode) != eltwise_int_modes.end()),
desc->id + "Requested eltwise mode is not supported for integer types.");
}
// Logic and comparison operations should return i8 for any inputs
std::vector<eltwise_mode> eltwise_bool_modes = {eltwise_mode::eq,
eltwise_mode::ne,
eltwise_mode::lt,
eltwise_mode::le,
eltwise_mode::gt,
eltwise_mode::ge,
eltwise_mode::logic_and,
eltwise_mode::logic_or,
eltwise_mode::logic_xor};
if (std::find(eltwise_bool_modes.begin(), eltwise_bool_modes.end(), mode) != eltwise_bool_modes.end()) {
output_layout.data_type = data_types::i8;
}
output_layout.data_type = desc->output_data_type.value_or(output_layout.data_type);
if (impl_param.has_fused_primitives()) {
output_layout.data_type = impl_param.get_fused_output_layout().data_type;
}
if (!desc->stride.empty()) {
auto input_pshape = input_layout.get<ShapeType>();
if (input_pshape.is_static()) {
// we can safely use only first stride, since we're using first input, and input / stride should give exact same
// value for every input
auto in_shape = input_pshape.get_shape();
for (size_t i = 0; i < desc->stride[0].spatial.size(); i++) {
const size_t idx = in_shape.size() - 1 - i;
if (idx < 0)
break;
in_shape[idx] = (in_shape[idx] - 1) / desc->stride[0].spatial[i] + 1;
}
input_layout.set_partial_shape({in_shape});
}
return { input_layout };
}
return { output_layout };
}
static inline std::string stringify_vector(const std::vector<float>& v) {
std::stringstream s;

View File

@@ -75,6 +75,7 @@ public:
kernel_selector::eltwise_mode mode = convert_to_eltwise_mode(get_primitive()->mode);
return std::make_shared<kernel_selector::eltwise_fuse_params>(mode);
}
std::vector<size_t> get_shape_infer_dependencies() const override { return {}; }
};
using eltwise_node = typed_program_node<eltwise>;
@@ -85,10 +86,10 @@ class typed_primitive_inst<eltwise> : public typed_primitive_inst_base<eltwise>
static void check_inputs_count(eltwise_node const& node);
public:
template<typename ShapeType>
static std::vector<layout> calc_output_layouts(eltwise_node const& /*node*/, const kernel_impl_params& impl_param);
static layout calc_output_layout(eltwise_node const& node, kernel_impl_params const& impl_param);
static std::string to_string(eltwise_node const& node);
public:
typed_primitive_inst(network& network, eltwise_node const& node);
};

View File

@@ -125,6 +125,7 @@ struct kernel_impl_params {
optional_layout compensation_layout = optional_layout();
std::map<size_t, memory::ptr> memory_deps = {};
size_t primary_input_idx = 0;
memory::ptr reordered_weights = nullptr;
@@ -144,7 +145,8 @@ struct kernel_impl_params {
, output_layout(_out_layout)
, fused_desc(_fused_descs)
, fused_act_funcs(_fused_act_funcs)
, activation_params(_act_params) {}
, activation_params(_act_params)
, primary_input_idx(0) {}
layout get_input_layout(size_t idx = 0) const {
OPENVINO_ASSERT(input_layouts.size() > idx,

View File

@@ -146,6 +146,14 @@ public:
get_fused_primitives(),
get_fused_activations_funcs(), get_fused_activations_params()));
params->memory_deps = get_const_memory_deps();
auto deps = get_dependencies();
for (size_t i = 0; i < deps.size(); i++) {
if (!deps[i]->is_constant()) {
params->primary_input_idx = i;
break;
}
}
return params;
}

View File

@@ -82,7 +82,8 @@ void CreateElementwiseOp(Program& p, const std::shared_ptr<ngraph::Node>& op, cl
inputPrimitives,
mode,
{},
out_dt);
out_dt,
op->get_autob());
p.add_primitive(*op, eltwisePrim);
}

View File

@@ -0,0 +1,205 @@
// Copyright (C) 2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "test_utils.h"
#include <intel_gpu/primitives/input_layout.hpp>
#include <intel_gpu/primitives/eltwise.hpp>
#include <intel_gpu/primitives/data.hpp>
#include "eltwise_inst.h"
#include "program_wrapper.h"
#include <cmath>
#include <algorithm>
using namespace cldnn;
using namespace ::tests;
using namespace ov::op;
using namespace ov;
namespace shape_infer_tests {
struct eltwise_test_params {
layout input1_layout;
layout input2_layout;
eltwise_mode mode;
AutoBroadcastSpec auto_broadcast_spec;
layout expected_layout;
std::vector<tensor> stride;
};
std::string to_string(const eltwise_mode mode) {
std::string str_mode;
switch (mode) {
case eltwise_mode::sum:
str_mode = "sum";
break;
case eltwise_mode::sub:
str_mode = "subtract";
break;
case eltwise_mode::max:
str_mode = "max";
break;
case eltwise_mode::prod:
str_mode = "product";
break;
case eltwise_mode::div:
str_mode = "div";
break;
case eltwise_mode::min:
str_mode = "min";
break;
case eltwise_mode::pow:
str_mode = "pow";
break;
case eltwise_mode::squared_diff:
str_mode = "squared_diff";
break;
case eltwise_mode::mod:
str_mode = "mod";
break;
case eltwise_mode::eq:
str_mode = "equal";
break;
case eltwise_mode::ne:
str_mode = "not equal";
break;
case eltwise_mode::lt:
str_mode = "less";
break;
case eltwise_mode::le:
str_mode = "less-or-equal";
break;
case eltwise_mode::gt:
str_mode = "greater";
break;
case eltwise_mode::ge:
str_mode = "greater-or-equal";
break;
case eltwise_mode::logic_and:
str_mode = "and";
break;
case eltwise_mode::logic_or:
str_mode = "or";
break;
case eltwise_mode::logic_xor:
str_mode = "xor";
break;
case eltwise_mode::floor_mod:
str_mode = "floor_mod";
break;
default:
str_mode = "not supported mode";
break;
}
return str_mode;
}
std::string to_string(const cldnn::layout& l) {
std::stringstream s;
s << "{" << data_type_traits::name(l.data_type) << ","
<< l.format.to_string() << ","
<< l.get_partial_shape() << "}";
return s.str();
}
std::ostream& operator<<(std::ostream& ost, const eltwise_test_params& params) {
ost << "{ IN1:" << to_string(params.input1_layout) << ","
<< "IN2:" << to_string(params.input2_layout) << ","
<< to_string(params.mode) << ","
<< "{" << params.auto_broadcast_spec.m_type << ", " << std::to_string(params.auto_broadcast_spec.m_axis) << "},"
<< "EXPECTED:" << to_string(params.expected_layout) << ","
<< "STRIDE:{";
for (auto& s : params.stride) {
ost << s << ",";
}
ost << "}\n";
return ost;
}
class eltwise_si_test : public testing::TestWithParam<eltwise_test_params> { };
TEST_P(eltwise_si_test, shape_infer) {
auto p = GetParam();
auto& engine = get_test_engine();
auto input1_prim = std::make_shared<input_layout>("input1", p.input1_layout);
auto input2_prim = std::make_shared<input_layout>("input2", p.input2_layout);
auto eltwise_prim = std::make_shared<eltwise>("output", "input1", "input2", p.stride, p.mode, p.auto_broadcast_spec);
cldnn::program prog(engine);
auto& input1_node = prog.get_or_create(input1_prim);
auto& input2_node = prog.get_or_create(input2_prim);
auto& eltwise_node = prog.get_or_create(eltwise_prim);
program_wrapper::add_connection(prog, input1_node, eltwise_node);
program_wrapper::add_connection(prog, input2_node, eltwise_node);
auto res = eltwise_inst::calc_output_layouts<ov::PartialShape>(eltwise_node, *eltwise_node.get_kernel_impl_params());
ASSERT_EQ(res.size(), 1);
ASSERT_EQ(res[0], p.expected_layout);
}
TEST_P(eltwise_si_test, shape_infer_const_data) {
auto p = GetParam();
auto& engine = get_test_engine();
auto const_data = engine.allocate_memory(p.input2_layout);
auto input1_prim = std::make_shared<input_layout>("input1", p.input1_layout);
auto const_data_prim = std::make_shared<data>("const_data", const_data);
auto eltwise_prim = std::make_shared<eltwise>("output", "input1", "const_data", p.stride, p.mode, p.auto_broadcast_spec);
cldnn::program prog(engine);
auto& input1_node = prog.get_or_create(input1_prim);
auto& const_data_node = prog.get_or_create(const_data_prim);
auto& eltwise_node = prog.get_or_create(eltwise_prim);
program_wrapper::add_connection(prog, input1_node, eltwise_node);
program_wrapper::add_connection(prog, const_data_node, eltwise_node);
auto res = eltwise_inst::calc_output_layouts<ov::PartialShape>(eltwise_node, *eltwise_node.get_kernel_impl_params());
ASSERT_EQ(res.size(), 1);
ASSERT_EQ(res[0], p.expected_layout);
}
INSTANTIATE_TEST_SUITE_P(smoke, eltwise_si_test,
testing::ValuesIn(std::vector<eltwise_test_params>{
{{{2, 1, 5}, data_types::f32, format::bfyx}, {{2, 1, 5}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NONE}, {{2, 1, 5}, data_types::f32, format::bfyx}, {}},
{{{2, 1, 5}, data_types::f32, format::bfyx}, {{1, 4, 1}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{2, 4, 5}, data_types::f32, format::bfyx}, {}},
{{{1, 1, 5}, data_types::f32, format::bfyx}, {{5, 2, 1, 3}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{5, 2, 5, 3}, data_types::f32, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{4, 5}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD, -1}, {{2, 3, 4, 5}, data_types::f32, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{1, 3}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD}, {{2, 3, 4, 5}, data_types::f32, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{3}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD, 1}, {{2, 3, 4, 5}, data_types::f32, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{3}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{3, 3, 4, 5}, data_types::f32, format::bfyx}, {}},
// test for dynamic shape
{{{1, 1, 5}, data_types::f32, format::bfyx}, {{5, 2, 1, 3}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{5, 2, 5, 3}, data_types::f32, format::bfyx}, {}},
{{PartialShape::dynamic(3), data_types::f32, format::bfyx}, {{2, 3, 4, 5}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD}, {PartialShape::dynamic(4), data_types::f32, format::bfyx}, {}},
{{{2, -1, 5}, data_types::f32, format::bfyx}, {{1, 4, 1}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{2, 4, 5}, data_types::f32, format::bfyx}, {}},
{{PartialShape::dynamic(3), data_types::f32, format::bfyx}, {{1, 4, 1}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{-1, 4, -1}, data_types::f32, format::bfyx}, {}},
{{PartialShape::dynamic(3), data_types::f32, format::bfyx}, {{2, 1, 5}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{2, -1, 5}, data_types::f32, format::bfyx}, {}},
{{PartialShape::dynamic(3), data_types::f32, format::bfyx}, {{1, 4, 1}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD}, {PartialShape::dynamic(3), data_types::f32, format::bfyx}, {}},
{{{-1, -1, 1024, 512}, data_types::f32, format::bfyx}, {{1, 1, 512, 1}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {ov::PartialShape::dynamic(4), data_types::f32, format::bfyx}, {}},
// test for output data type of logic and comparison operations
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{3}, data_types::f32, format::bfyx}, eltwise_mode::eq, {AutoBroadcastType::NUMPY}, {{3, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f16, format::bfyx}, {{3}, data_types::f16, format::bfyx}, eltwise_mode::ne, {AutoBroadcastType::NUMPY}, {{3, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f16, format::bfyx}, {{3}, data_types::f16, format::bfyx}, eltwise_mode::lt, {AutoBroadcastType::NUMPY}, {{3, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::i32, format::bfyx}, {{3}, data_types::i32, format::bfyx}, eltwise_mode::le, {AutoBroadcastType::NUMPY}, {{3, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::i64, format::bfyx}, {{3}, data_types::i64, format::bfyx}, eltwise_mode::gt, {AutoBroadcastType::NUMPY}, {{3, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::u8, format::bfyx}, {{3}, data_types::u8, format::bfyx}, eltwise_mode::ge, {AutoBroadcastType::PDPD, 1}, {{2, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::i8, format::bfyx}, {{3}, data_types::i8, format::bfyx}, eltwise_mode::logic_and,{AutoBroadcastType::PDPD, 1}, {{2, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{3}, data_types::f32, format::bfyx}, eltwise_mode::logic_or, {AutoBroadcastType::PDPD, 1}, {{2, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
{{{2, 3, 4, 5}, data_types::f32, format::bfyx}, {{3}, data_types::f32, format::bfyx}, eltwise_mode::logic_xor,{AutoBroadcastType::PDPD, 1}, {{2, 3, 4, 5}, data_types::i8, format::bfyx}, {}},
// test stride
{{{5, 2, 1, 20}, data_types::f32, format::bfyx}, {{1, 1, 40}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {{5, 2, 1, 5}, data_types::f32, format::bfyx}, {{1,3,4,2}}},
{{{2, 3, 40,50}, data_types::f32, format::bfyx}, {{40, 50}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD, -1}, {{2, 3, 5, 10}, data_types::f32, format::bfyx}, {{1,1,5,8}}},
{{PartialShape::dynamic(4), data_types::f32, format::bfyx}, {{2, 1, 5}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::NUMPY}, {PartialShape::dynamic(4), data_types::f32, format::bfyx}, {{1,1,5,8}}},
{{PartialShape::dynamic(4), data_types::f32, format::bfyx}, {{2, 1, 5}, data_types::f32, format::bfyx}, eltwise_mode::sum, {AutoBroadcastType::PDPD, 1}, {PartialShape::dynamic(4), data_types::f32, format::bfyx}, {{1,1,3,8}}},
}));
} // shape_infer_tests

View File

@@ -14,6 +14,8 @@
using namespace cldnn;
using namespace ::tests;
#define DEFAULT_BROADCAST_SPEC ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY)
template <typename T>
T eltwise_execute(cldnn::eltwise_mode mode, T x, T y) {
switch (mode) {
@@ -91,7 +93,7 @@ void generic_eltwise_test(cldnn::format test_input_fmt, int input_b, int input_f
topology.add(input_layout("input1", input1->get_layout()));
topology.add(input_layout("input2", input2->get_layout()));
topology.add(reorder("reorder1", "input1", input1->get_layout().with_padding(padding{{ 0, 0, input_padding_x, input_padding_y }, 0 })));
topology.add(eltwise("eltwise", {"reorder1", "input2"}, mode, padding{ { 0, 0, output_padding_x, output_padding_y }, 0 }));
topology.add(eltwise("eltwise", {"reorder1", "input2"}, mode, DEFAULT_BROADCAST_SPEC, padding{ { 0, 0, output_padding_x, output_padding_y }, 0 }));
primitive_id out_id = "eltwise";
if (relu)
{
@@ -2795,7 +2797,7 @@ TEST(eltwise_gpu_f16, bfyx_and_fs_b_yx_fsv32_output_padding) {
topology golden_topology;
golden_topology.add(input_layout("input1", input1->get_layout()));
golden_topology.add(input_layout("input2", input2->get_layout()));
golden_topology.add(eltwise("eltwise", "input1", "input2", eltwise_mode::sum, padding{ {0,0,5,10} , 0 }));
golden_topology.add(eltwise("eltwise", "input1", "input2", eltwise_mode::sum, DEFAULT_BROADCAST_SPEC, padding{ {0,0,5,10} , 0 }));
network golden_network(engine, golden_topology);
golden_network.set_input_data("input1", input1);
@@ -2811,7 +2813,7 @@ TEST(eltwise_gpu_f16, bfyx_and_fs_b_yx_fsv32_output_padding) {
FS_B_YX_FSV32_OUTPUT_topology.add(input_layout("input2", input2->get_layout()));
FS_B_YX_FSV32_OUTPUT_topology.add(reorder("reorder1", "input1", layout(data_types::f16, format::fs_b_yx_fsv32, input_tensor)));
FS_B_YX_FSV32_OUTPUT_topology.add(reorder("reorder2", "input2", layout(data_types::f16, format::byxf, input_tensor)));
FS_B_YX_FSV32_OUTPUT_topology.add(eltwise("eltwise", "reorder1", "reorder2", eltwise_mode::sum, padding{ {0,0,5,10} , 0 }));
FS_B_YX_FSV32_OUTPUT_topology.add(eltwise("eltwise", "reorder1", "reorder2", eltwise_mode::sum, DEFAULT_BROADCAST_SPEC, padding{ {0,0,5,10} , 0 }));
FS_B_YX_FSV32_OUTPUT_topology.add(reorder("reorderOutput", "eltwise", layout(data_types::f16, format::bfyx, input_tensor,
padding{ {0,0,5,10} , 0 })));
@@ -2829,7 +2831,7 @@ TEST(eltwise_gpu_f16, bfyx_and_fs_b_yx_fsv32_output_padding) {
BYXF_OUTPUT_topology.add(input_layout("input2", input2->get_layout()));
BYXF_OUTPUT_topology.add(reorder("reorder1", "input1", layout(data_types::f16, format::byxf, input_tensor)));
BYXF_OUTPUT_topology.add(reorder("reorder2", "input2", layout(data_types::f16, format::fs_b_yx_fsv32, input_tensor)));
BYXF_OUTPUT_topology.add(eltwise("eltwise", "reorder1", "reorder2", eltwise_mode::sum, padding{ {0,0,5,10} , 0 }));
BYXF_OUTPUT_topology.add(eltwise("eltwise", "reorder1", "reorder2", eltwise_mode::sum, DEFAULT_BROADCAST_SPEC, padding{ {0,0,5,10} , 0 }));
BYXF_OUTPUT_topology.add(reorder("reorderOutput", "eltwise", layout(data_types::f16, format::bfyx, input_tensor,
padding{ {0,0,5,10} , 0 })));
@@ -3011,7 +3013,7 @@ void generic_eltwise_bool_test(cldnn::format test_input_fmt, int input_b, int in
topology.add(input_layout("input1", input1->get_layout()));
topology.add(input_layout("input2", input2->get_layout()));
topology.add(reorder("reorder1", "input1", input1->get_layout().with_padding(padding{{ 0, 0, input_padding_x, input_padding_y }, 0 })));
topology.add(eltwise("eltwise", {"reorder1", "input2"}, mode, padding{ { 0, 0, output_padding_x, output_padding_y }, 0 }));
topology.add(eltwise("eltwise", {"reorder1", "input2"}, mode, DEFAULT_BROADCAST_SPEC, padding{ { 0, 0, output_padding_x, output_padding_y }, 0 }));
network network(engine, topology);
network.set_input_data("input1", input1);