[GPU] Update pad output shape for dynamic (#17995)

This commit is contained in:
Kelvin Choi 2023-07-05 13:22:49 +09:00 committed by GitHub
parent 4c072ac4b5
commit 35e26906ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 200 additions and 7 deletions

View File

@ -46,12 +46,22 @@ std::vector<layout> border_inst::calc_output_layouts(border_node const& /*node*/
const bool is_begin_mem = (desc->non_constant_input_mask & border::PAD_NON_CONST_INPUT::BEGIN);
const bool is_end_mem = (desc->non_constant_input_mask & border::PAD_NON_CONST_INPUT::END);
ShapeType pads_shape = is_begin_mem ? impl_param.get_input_layout(1).get<ShapeType>() : ov::Shape{ desc->pads_begin.size() };
layout pads_begin_layout, pads_end_layout;
if (is_begin_mem) {
pads_begin_layout = impl_param.get_input_layout(1);
}
if (is_end_mem) {
pads_end_layout = is_begin_mem ? impl_param.get_input_layout(2) : impl_param.get_input_layout(1);
}
ShapeType pads_begin_shape = is_begin_mem ? pads_begin_layout.get<ShapeType>() : ov::Shape{ desc->pads_begin.size() };
ShapeType pads_end_shape = is_end_mem ? pads_end_layout.get<ShapeType>() : ov::Shape{ desc->pads_end.size() };
std::vector<ShapeType> output_shapes = {ShapeType{}};
std::vector<ShapeType> input_shapes = {
input0_layout.get<ShapeType>(),
pads_shape,
pads_shape,
pads_begin_shape,
pads_end_shape,
};
auto& memory_deps = impl_param.memory_deps;
@ -74,13 +84,13 @@ std::vector<layout> border_inst::calc_output_layouts(border_node const& /*node*/
const_data.emplace(1, make_host_tensor(pads_begin_mem->get_layout(), pads_begin_lock.data()));
auto pads_end_data = desc->pads_end;
auto pads_end_tensor = make_host_tensor({pads_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_end_data.data()));
auto pads_end_tensor = make_host_tensor({pads_end_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_end_data.data()));
const_data.emplace(2, pads_end_tensor);
ov::op::v1::shape_infer(&op, input_shapes, output_shapes, const_data);
} else {
auto pads_begin_data = desc->pads_begin;
auto pads_begin_tensor = make_host_tensor({pads_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_begin_data.data()));
auto pads_begin_tensor = make_host_tensor({pads_begin_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_begin_data.data()));
const_data.emplace(1, pads_begin_tensor);
auto pads_end_mem = memory_deps.at(1);
@ -90,12 +100,20 @@ std::vector<layout> border_inst::calc_output_layouts(border_node const& /*node*/
ov::op::v1::shape_infer(&op, input_shapes, output_shapes, const_data);
}
} else {
std::ptrdiff_t val = desc->pad_value;
auto pads_begin_data = desc->pads_begin;
auto pads_begin_tensor = make_host_tensor({pads_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_begin_data.data()));
if (is_begin_mem && desc->pad_mode == ov::op::PadMode::CONSTANT) {
pads_begin_data = {val, val, val, val};
}
auto pads_begin_tensor = make_host_tensor({pads_begin_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_begin_data.data()));
const_data.emplace(1, pads_begin_tensor);
auto pads_end_data = desc->pads_end;
auto pads_end_tensor = make_host_tensor({pads_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_end_data.data()));
if (is_end_mem && desc->pad_mode == ov::op::PadMode::CONSTANT) {
pads_end_data = {val, val, val, val};
}
auto pads_end_tensor = make_host_tensor({pads_end_shape, data_types::i64, format::bfyx}, static_cast<void*>(pads_end_data.data()));
const_data.emplace(2, pads_end_tensor);
ov::op::v1::shape_infer(&op, input_shapes, output_shapes, const_data);

View File

@ -137,4 +137,179 @@ INSTANTIATE_TEST_SUITE_P(smoke, pad_test_single_input,
}
}));
class pad_test_non_constant_input_begin : public testing::TestWithParam<pad_test_params> { };
TEST_P(pad_test_non_constant_input_begin, shape_infer) {
auto p = GetParam();
auto& engine = get_test_engine();
auto input0_prim = std::make_shared<input_layout>("input0", p.in_layout);
auto input1_prim = std::make_shared<input_layout>("input1", p.pads_begin_layout);
auto border_prim = std::make_shared<border>("output",
std::vector<input_info>({input_info("input0"), input_info("input1")}),
border::PAD_NON_CONST_INPUT::BEGIN,
p.pads_begin_data,
p.pads_end_data,
p.pad_mode,
p.pad_value);
cldnn::program prog(engine);
auto& input0_node = prog.get_or_create(input0_prim);
auto& input1_node = prog.get_or_create(input1_prim);
auto& border_node = prog.get_or_create(border_prim);
program_wrapper::add_connection(prog, input0_node, border_node);
program_wrapper::add_connection(prog, input1_node, border_node);
auto res = border_inst::calc_output_layouts<ov::PartialShape>(border_node, *border_node.get_kernel_impl_params());
ASSERT_EQ(res.size(), 1);
ASSERT_EQ(res[0], p.expected_layout);
}
INSTANTIATE_TEST_SUITE_P(smoke, pad_test_non_constant_input_begin,
testing::ValuesIn(std::vector<pad_test_params>{
{
layout{ov::PartialShape{1, 3, 32, 40}, data_types::f32, format::bfyx},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {1, 0, 3, 7},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{3, 4, 36, 48}, data_types::f32, format::bfyx}
},
{
layout{ov::PartialShape::dynamic(4), data_types::f32, format::bfyx},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {1, 0, 3, 7},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{{2, -1}, {1, -1}, {4, -1}, {8, -1}}, data_types::f32, format::bfyx}
},
{
layout{ov::PartialShape::dynamic(2), data_types::f32, format::bfyx},
layout{ov::PartialShape{2}, data_types::i64, format::bfyx}, {},
layout{ov::PartialShape{2}, data_types::i64, format::bfyx}, {1, 0},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{{2, -1}, {1, -1}}, data_types::f32, format::bfyx}
}
}));
class pad_test_non_constant_input_end : public testing::TestWithParam<pad_test_params> { };
TEST_P(pad_test_non_constant_input_end, shape_infer) {
auto p = GetParam();
auto& engine = get_test_engine();
auto input0_prim = std::make_shared<input_layout>("input0", p.in_layout);
auto input1_prim = std::make_shared<input_layout>("input1", p.pads_end_layout);
auto border_prim = std::make_shared<border>("output",
std::vector<input_info>({input_info("input0"), input_info("input1")}),
border::PAD_NON_CONST_INPUT::END,
p.pads_begin_data,
p.pads_end_data,
p.pad_mode,
p.pad_value);
cldnn::program prog(engine);
auto& input0_node = prog.get_or_create(input0_prim);
auto& input1_node = prog.get_or_create(input1_prim);
auto& border_node = prog.get_or_create(border_prim);
program_wrapper::add_connection(prog, input0_node, border_node);
program_wrapper::add_connection(prog, input1_node, border_node);
auto res = border_inst::calc_output_layouts<ov::PartialShape>(border_node, *border_node.get_kernel_impl_params());
ASSERT_EQ(res.size(), 1);
ASSERT_EQ(res[0], p.expected_layout);
}
INSTANTIATE_TEST_SUITE_P(smoke, pad_test_non_constant_input_end,
testing::ValuesIn(std::vector<pad_test_params>{
{
layout{ov::PartialShape{1, 3, 32, 40}, data_types::f32, format::bfyx},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {1, 0, 3, 7},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{3, 4, 36, 48}, data_types::f32, format::bfyx}
},
{
layout{ov::PartialShape::dynamic(4), data_types::f32, format::bfyx},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {1, 0, 3, 7},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{{2, -1}, {1, -1}, {4, -1}, {8, -1}}, data_types::f32, format::bfyx}
},
{
layout{ov::PartialShape::dynamic(2), data_types::f32, format::bfyx},
layout{ov::PartialShape{2}, data_types::i64, format::bfyx}, {1, 0},
layout{ov::PartialShape{2}, data_types::i64, format::bfyx}, {},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{{2, -1}, {1, -1}}, data_types::f32, format::bfyx}
}
}));
class pad_test_non_constant_input_begin_end : public testing::TestWithParam<pad_test_params> { };
TEST_P(pad_test_non_constant_input_begin_end, shape_infer) {
auto p = GetParam();
auto& engine = get_test_engine();
auto input0_prim = std::make_shared<input_layout>("input0", p.in_layout);
auto input1_prim = std::make_shared<input_layout>("input1", p.pads_begin_layout);
auto input2_prim = std::make_shared<input_layout>("input2", p.pads_end_layout);
auto border_prim = std::make_shared<border>("output",
std::vector<input_info>({input_info("input0"), input_info("input1"), input_info("input2")}),
border::PAD_NON_CONST_INPUT::BEGIN | border::PAD_NON_CONST_INPUT::END,
p.pads_begin_data,
p.pads_end_data,
p.pad_mode,
p.pad_value);
cldnn::program prog(engine);
auto& input0_node = prog.get_or_create(input0_prim);
auto& input1_node = prog.get_or_create(input1_prim);
auto& input2_node = prog.get_or_create(input2_prim);
auto& border_node = prog.get_or_create(border_prim);
program_wrapper::add_connection(prog, input0_node, border_node);
program_wrapper::add_connection(prog, input1_node, border_node);
program_wrapper::add_connection(prog, input2_node, border_node);
auto res = border_inst::calc_output_layouts<ov::PartialShape>(border_node, *border_node.get_kernel_impl_params());
ASSERT_EQ(res.size(), 1);
ASSERT_EQ(res[0], p.expected_layout);
}
INSTANTIATE_TEST_SUITE_P(smoke, pad_test_non_constant_input_begin_end,
testing::ValuesIn(std::vector<pad_test_params>{
{
layout{ov::PartialShape{1, 3, 32, 40}, data_types::f32, format::bfyx},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{3, 5, 34, 42}, data_types::f32, format::bfyx}
},
{
layout{ov::PartialShape::dynamic(4), data_types::f32, format::bfyx},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
layout{ov::PartialShape{4}, data_types::i64, format::bfyx}, {},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{{2, -1}, {2, -1}, {2, -1}, {2, -1}}, data_types::f32, format::bfyx}
},
{
layout{ov::PartialShape::dynamic(2), data_types::f32, format::bfyx},
layout{ov::PartialShape{2}, data_types::i64, format::bfyx}, {},
layout{ov::PartialShape{2}, data_types::i64, format::bfyx}, {},
ov::op::PadMode::CONSTANT, 1.f,
layout{ov::PartialShape{{2, -1}, {2, -1}}, data_types::f32, format::bfyx}
}
}));
} // namespace shape_infer_tests