diff --git a/src/plugins/intel_gpu/include/intel_gpu/primitives/eltwise.hpp b/src/plugins/intel_gpu/include/intel_gpu/primitives/eltwise.hpp index 1f7093020c9..e37f86dbfd5 100644 --- a/src/plugins/intel_gpu/include/intel_gpu/primitives/eltwise.hpp +++ b/src/plugins/intel_gpu/include/intel_gpu/primitives/eltwise.hpp @@ -72,17 +72,18 @@ struct eltwise : public primitive_base { /// @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(0)), - stride(std::vector(0)) {} + stride(std::vector(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 { /// @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 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(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& 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(0)), - stride(std::vector(0)) {} + stride(std::vector(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& 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(0)), - stride(std::vector(0)) {} + stride(std::vector(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& inputs, eltwise_mode mode, const std::vector& 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(0)) { + stride(std::vector(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 { std::vector coefficients; /// @brief Defines shift in input buffers between adjacent calculations of output values. std::vector stride; + /// @brief Define auto broadcast rule specification. + ov::op::AutoBroadcastSpec broadcast_spec; }; /// @} /// @} diff --git a/src/plugins/intel_gpu/src/graph/eltwise.cpp b/src/plugins/intel_gpu/src/graph/eltwise.cpp index 4e81b52bcbd..ae377e5d9cb 100644 --- a/src/plugins/intel_gpu/src/graph/eltwise.cpp +++ b/src/plugins/intel_gpu/src/graph/eltwise.cpp @@ -107,6 +107,146 @@ layout eltwise_inst::calc_output_layout(eltwise_node const& node, kernel_impl_pa return output_layout; } +template +std::vector eltwise_inst::calc_output_layouts(eltwise_node const& /*node*/, kernel_impl_params const& impl_param) { + auto desc = impl_param.typed_desc(); + 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(); + 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(); + 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_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_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(); + 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& v) { std::stringstream s; diff --git a/src/plugins/intel_gpu/src/graph/include/eltwise_inst.h b/src/plugins/intel_gpu/src/graph/include/eltwise_inst.h index 31abdf43884..c95caad3801 100644 --- a/src/plugins/intel_gpu/src/graph/include/eltwise_inst.h +++ b/src/plugins/intel_gpu/src/graph/include/eltwise_inst.h @@ -75,6 +75,7 @@ public: kernel_selector::eltwise_mode mode = convert_to_eltwise_mode(get_primitive()->mode); return std::make_shared(mode); } + std::vector get_shape_infer_dependencies() const override { return {}; } }; using eltwise_node = typed_program_node; @@ -85,10 +86,10 @@ class typed_primitive_inst : public typed_primitive_inst_base static void check_inputs_count(eltwise_node const& node); public: + template + static std::vector 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); }; diff --git a/src/plugins/intel_gpu/src/graph/include/kernel_selector_helper.h b/src/plugins/intel_gpu/src/graph/include/kernel_selector_helper.h index e8c8a817b31..b0df8ba74b0 100644 --- a/src/plugins/intel_gpu/src/graph/include/kernel_selector_helper.h +++ b/src/plugins/intel_gpu/src/graph/include/kernel_selector_helper.h @@ -125,6 +125,7 @@ struct kernel_impl_params { optional_layout compensation_layout = optional_layout(); std::map 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, diff --git a/src/plugins/intel_gpu/src/graph/include/program_node.h b/src/plugins/intel_gpu/src/graph/include/program_node.h index 93e986d2cd9..eb89869a384 100644 --- a/src/plugins/intel_gpu/src/graph/include/program_node.h +++ b/src/plugins/intel_gpu/src/graph/include/program_node.h @@ -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; } diff --git a/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp b/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp index a4f1b01f22b..e920327652a 100644 --- a/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp +++ b/src/plugins/intel_gpu/src/plugin/ops/eltwise.cpp @@ -82,7 +82,8 @@ void CreateElementwiseOp(Program& p, const std::shared_ptr& op, cl inputPrimitives, mode, {}, - out_dt); + out_dt, + op->get_autob()); p.add_primitive(*op, eltwisePrim); } diff --git a/src/plugins/intel_gpu/tests/shape_infer/eltwise_si_test.cpp b/src/plugins/intel_gpu/tests/shape_infer/eltwise_si_test.cpp new file mode 100644 index 00000000000..b10f3569dd9 --- /dev/null +++ b/src/plugins/intel_gpu/tests/shape_infer/eltwise_si_test.cpp @@ -0,0 +1,205 @@ +// Copyright (C) 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "test_utils.h" + +#include +#include +#include + +#include "eltwise_inst.h" + +#include "program_wrapper.h" + +#include +#include + +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 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 { }; + +TEST_P(eltwise_si_test, shape_infer) { + auto p = GetParam(); + + auto& engine = get_test_engine(); + + auto input1_prim = std::make_shared("input1", p.input1_layout); + auto input2_prim = std::make_shared("input2", p.input2_layout); + auto eltwise_prim = std::make_shared("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(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("input1", p.input1_layout); + auto const_data_prim = std::make_shared("const_data", const_data); + auto eltwise_prim = std::make_shared("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(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{ + {{{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 diff --git a/src/plugins/intel_gpu/tests/test_cases/eltwise_gpu_test.cpp b/src/plugins/intel_gpu/tests/test_cases/eltwise_gpu_test.cpp index d753afbe89f..96d139782da 100644 --- a/src/plugins/intel_gpu/tests/test_cases/eltwise_gpu_test.cpp +++ b/src/plugins/intel_gpu/tests/test_cases/eltwise_gpu_test.cpp @@ -14,6 +14,8 @@ using namespace cldnn; using namespace ::tests; +#define DEFAULT_BROADCAST_SPEC ov::op::AutoBroadcastSpec(ov::op::AutoBroadcastType::NUMPY) + template 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);