[GPU] Update DepthToSpace to use nGraph shape inference (#18422)
* Update DepthToSpace to use ngraph shape infer * Remove legacy block_size limitation for static shape Signed-off-by: Andrew Park <andrew.park@intel.com> * Add TCs for ov_gpu_func_tests and ov_gpu_unit_tests Signed-off-by: Andrew Park <andrew.park@intel.com> --------- Signed-off-by: Andrew Park <andrew.park@intel.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
#include "depth_to_space_inst.h"
|
||||
#include "depth_to_space_shape_inference.hpp"
|
||||
|
||||
#include "primitive_type_base.h"
|
||||
#include "intel_gpu/runtime/error_handler.hpp"
|
||||
@@ -20,11 +21,6 @@ layout depth_to_space_inst::calc_output_layout(depth_to_space_node const& node,
|
||||
|
||||
const size_t block_size = desc->block_size;
|
||||
|
||||
if (block_size < 2)
|
||||
CLDNN_ERROR_MESSAGE(desc->id,
|
||||
"Invalid depthToSpace block_size value (should equal at least two). Actual block size is" +
|
||||
std::to_string(block_size));
|
||||
|
||||
if (input_layout.feature() % (block_size * block_size) != 0)
|
||||
CLDNN_ERROR_MESSAGE(
|
||||
desc->id,
|
||||
@@ -52,6 +48,27 @@ layout depth_to_space_inst::calc_output_layout(depth_to_space_node const& node,
|
||||
return layout{input_layout.data_type, input_format, out_size};
|
||||
}
|
||||
|
||||
template<typename ShapeType>
|
||||
std::vector<layout> depth_to_space_inst::calc_output_layouts(depth_to_space_node const& node, kernel_impl_params const& impl_param) {
|
||||
auto desc = impl_param.typed_desc<depth_to_space>();
|
||||
auto input_layout = impl_param.get_input_layout(0);
|
||||
auto output_type = desc->output_data_types[0].value_or(input_layout.data_type);
|
||||
auto output_format = input_layout.format;
|
||||
|
||||
ov::op::v0::DepthToSpace op;
|
||||
op.set_block_size(desc->block_size);
|
||||
|
||||
std::vector<ShapeType> output_shapes = { ShapeType() };
|
||||
std::vector<ShapeType> input_shapes = {
|
||||
input_layout.get<ShapeType>()
|
||||
};
|
||||
ov::op::v0::shape_infer(&op, input_shapes, output_shapes);
|
||||
|
||||
return { layout{output_shapes[0], output_type, output_format} };
|
||||
}
|
||||
|
||||
template std::vector<layout> depth_to_space_inst::calc_output_layouts<ov::PartialShape>(depth_to_space_node const& node, const kernel_impl_params& impl_param);
|
||||
|
||||
std::string depth_to_space_inst::to_string(depth_to_space_node const& node) {
|
||||
auto desc = node.get_primitive();
|
||||
auto node_info = node.desc_to_json();
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
std::shared_ptr<NodeFuseParams> get_fuse_params() const override {
|
||||
return std::make_shared<NodeFuseParams>(depth_to_space::type_id());
|
||||
}
|
||||
std::vector<size_t> get_shape_infer_dependencies() const override { return {}; }
|
||||
};
|
||||
|
||||
using depth_to_space_node = typed_program_node<depth_to_space>;
|
||||
@@ -31,6 +32,8 @@ class typed_primitive_inst<depth_to_space> : public typed_primitive_inst_base<de
|
||||
using parent::parent;
|
||||
|
||||
public:
|
||||
template<typename ShapeType>
|
||||
static std::vector<layout> calc_output_layouts(depth_to_space_node const& node, kernel_impl_params const& impl_param);
|
||||
static layout calc_output_layout(depth_to_space_node const& node, kernel_impl_params const& impl_param);
|
||||
static std::string to_string(depth_to_space_node const& node);
|
||||
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "shared_test_classes/single_layer/depth_to_space.hpp"
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
#include "ie_precision.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "common_test_utils/ov_tensor_utils.hpp"
|
||||
#include <string>
|
||||
|
||||
using namespace ngraph::opset3;
|
||||
using namespace InferenceEngine;
|
||||
using namespace ov::test;
|
||||
|
||||
namespace GPULayerTestsDefinitions {
|
||||
|
||||
typedef std::tuple<
|
||||
InputShape, // Input shape
|
||||
ElementType, // Input element type
|
||||
DepthToSpace::DepthToSpaceMode, // Mode
|
||||
std::size_t // Block size
|
||||
> DepthToSpaceLayerGPUTestParams;
|
||||
|
||||
class DepthToSpaceLayerGPUTest : public testing::WithParamInterface<DepthToSpaceLayerGPUTestParams>,
|
||||
virtual public ov::test::SubgraphBaseTest {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<DepthToSpaceLayerGPUTestParams> obj) {
|
||||
InputShape shapes;
|
||||
ElementType inType;
|
||||
DepthToSpace::DepthToSpaceMode mode;
|
||||
std::size_t blockSize;
|
||||
std::tie(shapes, inType, mode, blockSize) = obj.param;
|
||||
|
||||
std::ostringstream results;
|
||||
results << "IS=" << CommonTestUtils::partialShape2str({shapes.first}) << "_";
|
||||
results << "TS=";
|
||||
for (const auto& item : shapes.second) {
|
||||
results << CommonTestUtils::vec2str(item) << "_";
|
||||
}
|
||||
results << "Prc=" << inType << "_";
|
||||
switch (mode) {
|
||||
case DepthToSpace::DepthToSpaceMode::BLOCKS_FIRST:
|
||||
results << "BLOCKS_FIRST_";
|
||||
break;
|
||||
case DepthToSpace::DepthToSpaceMode::DEPTH_FIRST:
|
||||
results << "DEPTH_FIRST_";
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unsupported DepthToSpaceMode");
|
||||
}
|
||||
results << "BS=" << blockSize;
|
||||
|
||||
return results.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override {
|
||||
InputShape shapes;
|
||||
DepthToSpace::DepthToSpaceMode mode;
|
||||
std::size_t blockSize;
|
||||
std::tie(shapes, inType, mode, blockSize) = this->GetParam();
|
||||
|
||||
targetDevice = CommonTestUtils::DEVICE_GPU;
|
||||
init_input_shapes({shapes});
|
||||
|
||||
auto params = ngraph::builder::makeDynamicParams(inType, inputDynamicShapes);
|
||||
auto d2s = ngraph::builder::makeDepthToSpace(params[0], mode, blockSize);
|
||||
|
||||
ngraph::ResultVector results;
|
||||
for (size_t i = 0; i < d2s->get_output_size(); i++)
|
||||
results.push_back(std::make_shared<ngraph::opset1::Result>(d2s->output(i)));
|
||||
function = std::make_shared<ngraph::Function>(results, params, "DepthToSpace");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(DepthToSpaceLayerGPUTest, CompareWithRefs) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
|
||||
run();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const std::vector<ElementType> inputElementType = {
|
||||
ElementType::f32,
|
||||
ElementType::f16,
|
||||
ElementType::i8
|
||||
};
|
||||
|
||||
const std::vector<DepthToSpace::DepthToSpaceMode> depthToSpaceModes = {
|
||||
DepthToSpace::DepthToSpaceMode::BLOCKS_FIRST,
|
||||
DepthToSpace::DepthToSpaceMode::DEPTH_FIRST
|
||||
};
|
||||
|
||||
// ======================== Static Shapes Tests ========================
|
||||
|
||||
namespace static_shapes {
|
||||
|
||||
const std::vector<ov::Shape> inputShapesBS2_4D = {
|
||||
{1, 64, 1, 1},
|
||||
{1, 64, 1, 3},
|
||||
{1, 128, 3, 3},
|
||||
{2, 128, 1, 1},
|
||||
{1, 192, 2, 2},
|
||||
{2, 256, 2, 3},
|
||||
{1, 512, 2, 1}
|
||||
};
|
||||
|
||||
const std::vector<ov::Shape> inputShapesBS3_4D = {
|
||||
{1, 27, 1, 1},
|
||||
{1, 27, 2, 3},
|
||||
{1, 18, 2, 3},
|
||||
{3, 18, 1, 1},
|
||||
{2, 18, 3, 1}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GPUDepthToSpaceStaticBS2_4D, DepthToSpaceLayerGPUTest,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(static_shapes_to_test_representation(inputShapesBS2_4D)),
|
||||
testing::ValuesIn(inputElementType),
|
||||
testing::ValuesIn(depthToSpaceModes),
|
||||
testing::Values(1, 2)),
|
||||
DepthToSpaceLayerGPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GPUDepthToSpaceStaticBS3_4D, DepthToSpaceLayerGPUTest,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(static_shapes_to_test_representation(inputShapesBS3_4D)),
|
||||
testing::ValuesIn(inputElementType),
|
||||
testing::ValuesIn(depthToSpaceModes),
|
||||
testing::Values(1, 3)),
|
||||
DepthToSpaceLayerGPUTest::getTestCaseName);
|
||||
|
||||
const std::vector<ov::Shape> inputShapesBS2_5D = {
|
||||
{1, 128, 1, 1, 1},
|
||||
{1, 128, 2, 1, 2},
|
||||
{1, 256, 2, 1, 3},
|
||||
{2, 256, 3, 1, 1},
|
||||
{1, 384, 1, 2, 2},
|
||||
{2, 512, 1, 2, 1}
|
||||
};
|
||||
|
||||
const std::vector<ov::Shape> inputShapesBS3_5D = {
|
||||
{1, 54, 1, 1, 1},
|
||||
{1, 54, 2, 1, 2},
|
||||
{3, 54, 1, 1, 1},
|
||||
{2, 54, 3, 1, 2},
|
||||
{1, 54, 3, 2, 2}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GPUDepthToSpaceStaticBS2_5D, DepthToSpaceLayerGPUTest,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(static_shapes_to_test_representation(inputShapesBS2_5D)),
|
||||
testing::ValuesIn(inputElementType),
|
||||
testing::ValuesIn(depthToSpaceModes),
|
||||
testing::Values(1, 2)),
|
||||
DepthToSpaceLayerGPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GPUDepthToSpaceStaticBS3_5D, DepthToSpaceLayerGPUTest,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(static_shapes_to_test_representation(inputShapesBS3_5D)),
|
||||
testing::ValuesIn(inputElementType),
|
||||
testing::ValuesIn(depthToSpaceModes),
|
||||
testing::Values(1, 3)),
|
||||
DepthToSpaceLayerGPUTest::getTestCaseName);
|
||||
|
||||
} // namespace static_shapes
|
||||
|
||||
//======================== Dynamic Shapes Tests ========================
|
||||
|
||||
namespace dynamic_shapes {
|
||||
|
||||
const std::vector<InputShape> inputShapes4D = {
|
||||
{{-1, -1, -1, -1}, // dynamic
|
||||
{{2, 36, 1, 1}, {1, 36, 3, 1}, {2, 36, 1, 1}, {1, 36, 3, 1}}}, // target
|
||||
|
||||
{{-1, 576, -1, -1}, // dynamic
|
||||
{{1, 576, 1, 1}, {1, 576, 2, 2}, {3, 576, 4, 1}, {1, 576, 1, 1}}}, // target
|
||||
|
||||
{{{1, 5}, {36, 72}, {1, 16}, {1, 16}}, // dynamic
|
||||
{{3, 36, 4, 4}, {1, 36, 16, 12}, {3, 72, 8, 8}, {1, 36, 16, 12}}}, // target
|
||||
};
|
||||
|
||||
const std::vector<InputShape> inputShapes5D = {
|
||||
{{-1, -1, -1, -1, -1}, // dynamic
|
||||
{{2, 216, 1, 1, 1},
|
||||
{1, 216, 3, 1, 2},
|
||||
{1, 432, 2, 3, 1},
|
||||
{2, 216, 1, 1, 1}}}, // target
|
||||
|
||||
{{{1, 3}, {216, 432}, {1, 4}, {1, 4}, {1, 4}}, // dynamic
|
||||
{{3, 216, 2, 2, 2}, {1, 432, 1, 1, 1}, {3, 216, 2, 2, 2}}}, // target
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GPUDepthToSpaceDynamic4D, DepthToSpaceLayerGPUTest,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(inputShapes4D),
|
||||
testing::ValuesIn(inputElementType),
|
||||
testing::ValuesIn(depthToSpaceModes),
|
||||
testing::Values(1, 2, 3)),
|
||||
DepthToSpaceLayerGPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GPUDepthToSpaceDynamic5D, DepthToSpaceLayerGPUTest,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(inputShapes5D),
|
||||
testing::ValuesIn(inputElementType),
|
||||
testing::ValuesIn(depthToSpaceModes),
|
||||
testing::Values(1, 2, 3)),
|
||||
DepthToSpaceLayerGPUTest::getTestCaseName);
|
||||
|
||||
} // namespace dynamic_shapes
|
||||
|
||||
} // namespace
|
||||
} // namespace GPULayerTestsDefinitions
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "test_utils.h"
|
||||
|
||||
#include <intel_gpu/primitives/input_layout.hpp>
|
||||
#include <intel_gpu/primitives/depth_to_space.hpp>
|
||||
#include <intel_gpu/primitives/data.hpp>
|
||||
|
||||
#include "depth_to_space_inst.h"
|
||||
|
||||
#include "program_wrapper.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace cldnn;
|
||||
using namespace ::tests;
|
||||
|
||||
namespace shape_infer_tests {
|
||||
|
||||
struct depth_to_space_test_params {
|
||||
layout input_layout;
|
||||
size_t block_size;
|
||||
layout expected_layout;
|
||||
};
|
||||
|
||||
class depth_to_space_test : public testing::TestWithParam<depth_to_space_test_params> { };
|
||||
|
||||
TEST_P(depth_to_space_test, shape_infer) {
|
||||
auto p = GetParam();
|
||||
|
||||
auto& engine = get_test_engine();
|
||||
|
||||
auto input_layout_prim = std::make_shared<input_layout>("input", p.input_layout);
|
||||
auto depth_to_space_prim = std::make_shared<depth_to_space>("depth_to_space", input_info("input"), p.block_size, depth_to_space_mode::blocks_first);
|
||||
|
||||
cldnn::program prog(engine);
|
||||
|
||||
auto& input_layout_node = prog.get_or_create(input_layout_prim);
|
||||
auto& depth_to_space_node = prog.get_or_create(depth_to_space_prim);
|
||||
program_wrapper::add_connection(prog, input_layout_node, depth_to_space_node);
|
||||
auto res = depth_to_space_inst::calc_output_layouts<ov::PartialShape>(depth_to_space_node, *depth_to_space_node.get_kernel_impl_params());
|
||||
|
||||
ASSERT_EQ(res.size(), 1);
|
||||
ASSERT_EQ(res[0], p.expected_layout);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke, depth_to_space_test,
|
||||
testing::ValuesIn(std::vector<depth_to_space_test_params>{
|
||||
{
|
||||
layout{ov::PartialShape{5, 28, 2, 3}, data_types::f32, format::bfyx},
|
||||
2,
|
||||
layout{ov::PartialShape{5, 7, 4, 6}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape::dynamic(4), data_types::f32, format::bfyx},
|
||||
2,
|
||||
layout{ov::PartialShape::dynamic(4), data_types::f32, format::bfyx}
|
||||
}
|
||||
}));
|
||||
|
||||
} // shape_infer_tests
|
||||
Reference in New Issue
Block a user