[GPU] Reduce to use ngraph shape infer at calc_output_layouts (#13032)
This commit is contained in:
@@ -27,6 +27,8 @@ class typed_primitive_inst<reduce> : public typed_primitive_inst_base<reduce> {
|
||||
using parent = typed_primitive_inst_base<reduce>;
|
||||
|
||||
public:
|
||||
template<typename ShapeType>
|
||||
static std::vector<layout> calc_output_layouts(reduce_node const& node, const kernel_impl_params& impl_param);
|
||||
static layout calc_output_layout(reduce_node const& node, kernel_impl_params const& impl_param);
|
||||
static std::string to_string(reduce_node const& node);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "reduce_shape_inference.hpp"
|
||||
|
||||
namespace cldnn {
|
||||
primitive_type_id reduce::type_id() {
|
||||
static primitive_type_base<reduce> instance;
|
||||
@@ -95,6 +97,119 @@ layout reduce_inst::calc_output_layout(reduce_node const& node, kernel_impl_para
|
||||
return layout{output_type, input_format, tensor(batch(in_dims[0]), feature(in_dims[1]), spatial(in_dims[2], in_dims[3]))};
|
||||
}
|
||||
|
||||
template<typename ShapeType>
|
||||
std::vector<layout> reduce_inst::calc_output_layouts(reduce_node const& /*node*/, kernel_impl_params const& impl_param) {
|
||||
auto desc = impl_param.typed_desc<reduce>();
|
||||
|
||||
auto input0_layout = impl_param.get_input_layout(0);
|
||||
|
||||
// get 'output_shapes' by shape_infer of ngraph
|
||||
std::vector<ShapeType> input_shapes = {
|
||||
input0_layout.get<ShapeType>(),
|
||||
ShapeType{0}
|
||||
};
|
||||
|
||||
std::vector<ShapeType> output_shapes = {ShapeType()};
|
||||
|
||||
auto axes = desc->axes;
|
||||
auto axes_tensor = std::make_shared<ngraph::runtime::HostTensor>(ov::element::i64, ov::Shape{axes.size()}, axes.data());
|
||||
std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>> const_data = {{1, axes_tensor}};
|
||||
|
||||
// shape infer by mode
|
||||
auto mode = desc->mode;
|
||||
auto keep_dims = desc->keep_dims;
|
||||
switch (mode) {
|
||||
case reduce_mode::max:
|
||||
{
|
||||
ov::op::v1::ReduceMax op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::min:
|
||||
{
|
||||
ov::op::v1::ReduceMin op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::mean:
|
||||
{
|
||||
ov::op::v1::ReduceMean op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::prod:
|
||||
{
|
||||
ov::op::v1::ReduceProd op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::sum:
|
||||
{
|
||||
ov::op::v1::ReduceSum op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::logical_and:
|
||||
{
|
||||
ov::op::v1::ReduceLogicalAnd op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::logical_or:
|
||||
{
|
||||
ov::op::v1::ReduceLogicalOr op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::l1:
|
||||
{
|
||||
ov::op::v4::ReduceL1 op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::l2:
|
||||
{
|
||||
ov::op::v4::ReduceL2 op;
|
||||
op.set_keep_dims(keep_dims);
|
||||
shape_infer(&op, input_shapes, output_shapes, const_data);
|
||||
break;
|
||||
}
|
||||
case reduce_mode::sum_square:
|
||||
// not implemented
|
||||
case reduce_mode::log_sum:
|
||||
// not implemented
|
||||
case reduce_mode::log_sum_exp:
|
||||
// not implemented
|
||||
default:
|
||||
OPENVINO_ASSERT(false, "Not supported reduce mode");
|
||||
}
|
||||
|
||||
auto input_type = input0_layout.data_type;
|
||||
auto output_type = input_type;
|
||||
std::vector<reduce_mode> reduce_bool_modes = {reduce_mode::logical_and, reduce_mode::logical_or};
|
||||
if (std::find(reduce_bool_modes.begin(), reduce_bool_modes.end(), mode) != reduce_bool_modes.end())
|
||||
output_type = data_types::i8;
|
||||
else if (input_type == data_types::i8 || input_type == data_types::u8)
|
||||
output_type = data_types::f32;
|
||||
|
||||
output_type = desc->output_data_type.value_or(output_type);
|
||||
|
||||
if (impl_param.has_fused_primitives())
|
||||
output_type = impl_param.get_fused_output_layout().data_type;
|
||||
|
||||
auto output_format = format::adjust_to_rank(input0_layout.format, output_shapes[0].size());
|
||||
|
||||
return { layout{output_shapes[0], output_type, output_format} };
|
||||
}
|
||||
|
||||
std::string reduce_inst::to_string(reduce_node const& node) {
|
||||
auto desc = node.get_primitive();
|
||||
auto node_info = node.desc_to_json();
|
||||
|
||||
116
src/plugins/intel_gpu/tests/shape_infer/reduce_si_test.cpp
Normal file
116
src/plugins/intel_gpu/tests/shape_infer/reduce_si_test.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
// 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/reduce.hpp>
|
||||
#include <intel_gpu/primitives/data.hpp>
|
||||
|
||||
#include "reduce_inst.h"
|
||||
|
||||
#include "program_wrapper.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace cldnn;
|
||||
using namespace ::tests;
|
||||
|
||||
namespace shape_infer_tests {
|
||||
|
||||
struct reduce_test_params {
|
||||
layout input;
|
||||
reduce_mode mode;
|
||||
std::vector<int64_t> axes;
|
||||
bool keep_dims;
|
||||
layout expected_layout;
|
||||
};
|
||||
|
||||
class reduce_test : public testing::TestWithParam<reduce_test_params> { };
|
||||
|
||||
TEST_P(reduce_test, shape_infer) {
|
||||
auto p = GetParam();
|
||||
|
||||
auto& engine = get_test_engine();
|
||||
|
||||
auto input_prim = std::make_shared<input_layout>("input", p.input);
|
||||
auto reduce_prim = std::make_shared<reduce>("output", "input", p.mode, p.axes, p.keep_dims);
|
||||
|
||||
cldnn::program prog(engine);
|
||||
|
||||
auto& input_node = prog.get_or_create(input_prim);
|
||||
auto& reduce_node = prog.get_or_create(reduce_prim);
|
||||
program_wrapper::add_connection(prog, input_node, reduce_node);
|
||||
auto res = reduce_inst::calc_output_layouts<ov::PartialShape>(reduce_node, *reduce_node.get_kernel_impl_params());
|
||||
|
||||
ASSERT_EQ(res.size(), 1);
|
||||
ASSERT_EQ(res[0], p.expected_layout);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke, reduce_test,
|
||||
testing::ValuesIn(std::vector<reduce_test_params>{
|
||||
{
|
||||
layout{ov::PartialShape{1, 1, 1, 1}, data_types::f32, format::bfyx},
|
||||
reduce_mode::max, {1}, false,
|
||||
layout{ov::PartialShape{1}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{1, 1, 1, 1}, data_types::f32, format::bfyx},
|
||||
reduce_mode::min, {1}, true,
|
||||
layout{ov::PartialShape{1, 1, 1, 1}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24}, data_types::f32, format::bfyx},
|
||||
reduce_mode::mean, {1}, false,
|
||||
layout{ov::PartialShape{6, 10, 24}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24}, data_types::f32, format::bfyx},
|
||||
reduce_mode::prod, {1}, true,
|
||||
layout{ov::PartialShape{6, 1, 10, 24}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12}, data_types::f32, format::bfyx},
|
||||
reduce_mode::sum, {1}, false,
|
||||
layout{ov::PartialShape{6}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10}, data_types::f32, format::bfyx},
|
||||
reduce_mode::logical_and, {1}, false,
|
||||
layout{ov::PartialShape{6, 10}, data_types::i8, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10}, data_types::f32, format::bfyx},
|
||||
reduce_mode::logical_or, {1}, true,
|
||||
layout{ov::PartialShape{6, 1, 10}, data_types::i8, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24}, data_types::f32, format::bfyx},
|
||||
reduce_mode::l1, {2, 3}, false,
|
||||
layout{ov::PartialShape{6, 12}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24}, data_types::f32, format::bfyx},
|
||||
reduce_mode::l2, {2, 3}, true,
|
||||
layout{ov::PartialShape{6, 12, 1, 1}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24}, data_types::f32, format::bfyx},
|
||||
reduce_mode::max, {-2}, false,
|
||||
layout{ov::PartialShape{6, 12, 24}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24, 3}, data_types::f32, format::bfzyx},
|
||||
reduce_mode::min, {2, 3}, false,
|
||||
layout{ov::PartialShape{6, 12, 3}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape{6, 12, 10, 24, 3, 5}, data_types::f32, format::bfwzyx},
|
||||
reduce_mode::sum, {2, 3}, false,
|
||||
layout{ov::PartialShape{6, 12, 3, 5}, data_types::f32, format::bfyx}
|
||||
},
|
||||
}));
|
||||
|
||||
} // shape_infer_tests
|
||||
Reference in New Issue
Block a user