[GPU] Update ROIPooling to use nGraph shape inference (#18500)
This commit is contained in:
1 parent
acc13a70e8
commit
eba1b46719
4 files changed
+457
No files matched your search
@@ -9,6 +9,16 @@
|
||||
#include <string>
|
||||
|
||||
namespace cldnn {
|
||||
template <>
|
||||
struct typed_program_node<roi_pooling> : public typed_program_node_base<roi_pooling> {
|
||||
using parent = typed_program_node_base<roi_pooling>;
|
||||
|
||||
public:
|
||||
using parent::parent;
|
||||
|
||||
program_node& input(size_t index = 0) const { return get_dependency(index); }
|
||||
std::vector<size_t> get_shape_infer_dependencies() const override { return {}; }
|
||||
};
|
||||
|
||||
using roi_pooling_node = typed_program_node<roi_pooling>;
|
||||
|
||||
@@ -17,6 +27,8 @@ class typed_primitive_inst<roi_pooling> : public typed_primitive_inst_base<roi_p
|
||||
using parent = typed_primitive_inst_base<roi_pooling>;
|
||||
|
||||
public:
|
||||
template<typename ShapeType>
|
||||
static std::vector<layout> calc_output_layouts(roi_pooling_node const& node, kernel_impl_params const& impl_param);
|
||||
static layout calc_output_layout(roi_pooling_node const& node, kernel_impl_params const& impl_param);
|
||||
static std::string to_string(roi_pooling_node const& node);
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
//
|
||||
|
||||
#include "roi_pooling_inst.h"
|
||||
#include "roi_pooling_shape_inference.hpp"
|
||||
|
||||
#include "primitive_type_base.h"
|
||||
#include "json_object.h"
|
||||
#include <string>
|
||||
@@ -24,6 +26,32 @@ layout roi_pooling_inst::calc_output_layout(roi_pooling_node const& node, kernel
|
||||
{num_rois, out_fm, desc->pooled_width, desc->pooled_height});
|
||||
}
|
||||
|
||||
template<typename ShapeType>
|
||||
std::vector<layout> roi_pooling_inst::calc_output_layouts(roi_pooling_node const& node, kernel_impl_params const& impl_param) {
|
||||
auto desc = impl_param.typed_desc<roi_pooling>();
|
||||
auto input0_layout = impl_param.get_input_layout(0);
|
||||
auto output_type = desc->output_data_types[0].value_or(input0_layout.data_type);
|
||||
auto data_shape = input0_layout.get<ShapeType>();
|
||||
auto output_format = input0_layout.format;
|
||||
|
||||
ov::op::v0::ROIPooling op;
|
||||
std::vector<int> output_size { desc->pooled_height, desc->pooled_width };
|
||||
op.set_output_roi({ output_size.begin(), output_size.end() });
|
||||
op.set_spatial_scale(desc->spatial_scale);
|
||||
|
||||
ShapeType rois_shape = impl_param.get_input_layout(1).get<ShapeType>();
|
||||
std::vector<ShapeType> output_shapes = { ShapeType() };
|
||||
std::vector<ShapeType> input_shapes = {
|
||||
data_shape,
|
||||
rois_shape
|
||||
};
|
||||
ov::op::v0::shape_infer(&op, input_shapes, output_shapes);
|
||||
|
||||
return { layout{output_shapes[0], output_type, output_format} };
|
||||
}
|
||||
|
||||
template std::vector<layout> roi_pooling_inst::calc_output_layouts<ov::PartialShape>(roi_pooling_node const& node, const kernel_impl_params& impl_param);
|
||||
|
||||
std::string roi_pooling_inst::to_string(roi_pooling_node const& node) {
|
||||
auto desc = node.get_primitive();
|
||||
auto mode = desc->mode == pooling_mode::max
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "shared_test_classes/single_layer/roi_pooling.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;
|
||||
using namespace InferenceEngine;
|
||||
using namespace ov::test;
|
||||
|
||||
namespace GPULayerTestsDefinitions {
|
||||
|
||||
enum ProposalGenerationMode { RANDOM, ULTIMATE_RIGHT_BORDER };
|
||||
|
||||
using ROIPoolingShapes = std::vector<InputShape>;
|
||||
|
||||
typedef std::tuple<
|
||||
ROIPoolingShapes, // Input shapes
|
||||
std::vector<size_t>, // Pooled shape {pooled_h, pooled_w}
|
||||
float, // Spatial scale
|
||||
ngraph::helpers::ROIPoolingTypes, // ROIPooling method
|
||||
InferenceEngine::Precision // Net precision
|
||||
> ROIPoolingParams;
|
||||
|
||||
typedef std::tuple<
|
||||
ROIPoolingParams,
|
||||
ProposalGenerationMode,
|
||||
std::map<std::string, std::string>
|
||||
> ROIPoolingGPUTestParams;
|
||||
|
||||
class ROIPoolingLayerGPUTest : public testing::WithParamInterface<ROIPoolingGPUTestParams>,
|
||||
virtual public ov::test::SubgraphBaseTest {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<ROIPoolingGPUTestParams> obj) {
|
||||
ROIPoolingParams basicParamsSet;
|
||||
ProposalGenerationMode propMode;
|
||||
std::map<std::string, std::string> additionalConfig;
|
||||
|
||||
std::tie(basicParamsSet, propMode, additionalConfig) = obj.param;
|
||||
|
||||
ROIPoolingShapes inputShapes;
|
||||
std::vector<size_t> poolShape;
|
||||
float spatial_scale;
|
||||
ngraph::helpers::ROIPoolingTypes pool_method;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(inputShapes, poolShape, spatial_scale, pool_method, netPrecision) = basicParamsSet;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
for (const auto& shape : inputShapes) {
|
||||
result << CommonTestUtils::partialShape2str({ shape.first }) << "_";
|
||||
}
|
||||
result << "TS=";
|
||||
for (const auto& shape : inputShapes) {
|
||||
result << "(";
|
||||
if (!shape.second.empty()) {
|
||||
auto itr = shape.second.begin();
|
||||
do {
|
||||
result << CommonTestUtils::vec2str(*itr);
|
||||
} while (++itr != shape.second.end() && result << "_");
|
||||
}
|
||||
result << ")_";
|
||||
}
|
||||
|
||||
result << "PS=" << CommonTestUtils::vec2str(poolShape) << "_";
|
||||
result << "Scale=" << spatial_scale << "_";
|
||||
switch (pool_method) {
|
||||
case ngraph::helpers::ROIPoolingTypes::ROI_MAX:
|
||||
result << "Max_";
|
||||
break;
|
||||
case ngraph::helpers::ROIPoolingTypes::ROI_BILINEAR:
|
||||
result << "Bilinear_";
|
||||
break;
|
||||
}
|
||||
result << "config=(";
|
||||
for (const auto& configEntry : additionalConfig) {
|
||||
result << configEntry.first << ", " << configEntry.second << ":";
|
||||
}
|
||||
result << ")";
|
||||
switch (propMode) {
|
||||
case ProposalGenerationMode::ULTIMATE_RIGHT_BORDER:
|
||||
result << "_UltimateRightBorderProposal";
|
||||
break;
|
||||
case ProposalGenerationMode::RANDOM:
|
||||
default:
|
||||
result << "_RandomProposal";
|
||||
break;
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
void generate_inputs(const std::vector<ngraph::Shape>& targetInputStaticShapes) override {
|
||||
const ProposalGenerationMode propMode = std::get<1>(this->GetParam());
|
||||
const float spatial_scale = std::get<2>(std::get<0>(this->GetParam()));
|
||||
const ngraph::helpers::ROIPoolingTypes pool_method = std::get<3>(std::get<0>(this->GetParam()));
|
||||
|
||||
inputs.clear();
|
||||
const auto& funcInputs = function->inputs();
|
||||
|
||||
auto feat_map_shape = targetInputStaticShapes[0];
|
||||
const auto is_roi_max_mode = (pool_method == ngraph::helpers::ROIPoolingTypes::ROI_MAX);
|
||||
const int height = is_roi_max_mode ? feat_map_shape[2] / spatial_scale : 1;
|
||||
const int width = is_roi_max_mode ? feat_map_shape[3] / spatial_scale : 1;
|
||||
|
||||
for (size_t i = 0; i < funcInputs.size(); ++i) {
|
||||
const auto& funcInput = funcInputs[i];
|
||||
ov::Tensor tensor;
|
||||
|
||||
if (i == 1) {
|
||||
tensor = ov::Tensor(funcInput.get_element_type(), targetInputStaticShapes[i]);
|
||||
if (propMode == ULTIMATE_RIGHT_BORDER) {
|
||||
// because of nonalgebraic character of floating point operation, the following values causes inequity:
|
||||
// ((end_h - start_h) * (input_h - 1) / (pooled_h - 1)) * (pooled_h - 1) > (end_h - start_h) * (input_h - 1)
|
||||
// and as result excess of right limit for proposal value if the border case (current_h == pooled_h - 1)
|
||||
// will not be handled explicitly
|
||||
switch (funcInput.get_element_type()) {
|
||||
case ngraph::element::f32: {
|
||||
auto* dataPtr = tensor.data<float>();
|
||||
for (size_t i = 0; i < tensor.get_size(); i += 5) {
|
||||
dataPtr[i] = 0;
|
||||
dataPtr[i + 1] = 0.f;
|
||||
dataPtr[i + 2] = 0.248046786f;
|
||||
dataPtr[i + 3] = 0.471333951f;
|
||||
dataPtr[i + 4] = 1.f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ngraph::element::bf16: {
|
||||
auto* dataPtr = tensor.data<std::int16_t>();
|
||||
for (size_t i = 0; i < tensor.get_size(); i += 5) {
|
||||
dataPtr[i] = static_cast<std::int16_t>(ngraph::float16(0.f).to_bits());
|
||||
dataPtr[i + 1] = static_cast<std::int16_t>(ngraph::float16(0.f).to_bits());
|
||||
dataPtr[i + 2] = static_cast<std::int16_t>(ngraph::float16(0.248046786f).to_bits());
|
||||
dataPtr[i + 3] = static_cast<std::int16_t>(ngraph::float16(0.471333951f).to_bits());
|
||||
dataPtr[i + 4] = static_cast<std::int16_t>(ngraph::float16(1.f).to_bits());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
IE_THROW() << "roi_pooling. Unsupported precision";
|
||||
}
|
||||
} else {
|
||||
switch (funcInput.get_element_type()) {
|
||||
case ngraph::element::f32: {
|
||||
CommonTestUtils::fill_data_roi<InferenceEngine::Precision::FP32>(tensor, feat_map_shape[0] - 1, height, width, 1.f, is_roi_max_mode);
|
||||
break;
|
||||
}
|
||||
case ngraph::element::bf16: {
|
||||
CommonTestUtils::fill_data_roi<InferenceEngine::Precision::BF16>(tensor, feat_map_shape[0] - 1, height, width, 1.f, is_roi_max_mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
IE_THROW() << "roi_pooling. Unsupported precision";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), targetInputStaticShapes[i], 10, 0, 1000);
|
||||
}
|
||||
|
||||
inputs.insert({ funcInput.get_node_shared_ptr(), tensor });
|
||||
}
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
ROIPoolingParams basicParamsSet;
|
||||
ProposalGenerationMode propMode;
|
||||
std::map<std::string, std::string> additionalConfig;
|
||||
|
||||
std::tie(basicParamsSet, propMode, additionalConfig) = this->GetParam();
|
||||
ROIPoolingShapes inputShapes;
|
||||
std::vector<size_t> poolShape;
|
||||
float spatial_scale;
|
||||
ngraph::helpers::ROIPoolingTypes pool_method;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(inputShapes, poolShape, spatial_scale, pool_method, netPrecision) = basicParamsSet;
|
||||
|
||||
targetDevice = CommonTestUtils::DEVICE_GPU;
|
||||
init_input_shapes(inputShapes);
|
||||
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
auto params = ngraph::builder::makeDynamicParams(ngPrc, inputDynamicShapes);
|
||||
auto paramOuts = ngraph::helpers::convert2OutputVector(
|
||||
ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(params));
|
||||
|
||||
auto roi_pooling = ngraph::builder::makeROIPooling(paramOuts[0], paramOuts[1], poolShape, spatial_scale, pool_method);
|
||||
|
||||
ngraph::ResultVector results;
|
||||
for (size_t i = 0; i < roi_pooling->get_output_size(); i++)
|
||||
results.push_back(std::make_shared<ngraph::opset1::Result>(roi_pooling->output(i)));
|
||||
function = std::make_shared<ngraph::Function>(results, params, "ROIPooling");
|
||||
functionRefs = ngraph::clone_function(*function);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ROIPoolingLayerGPUTest, CompareWithRefs) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
|
||||
run();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::map<std::string, std::string> emptyAdditionalConfig;
|
||||
|
||||
const std::vector<ROIPoolingShapes> inShapes = {
|
||||
ROIPoolingShapes{{{}, {{1, 3, 8, 8}}}, {{}, {{1, 5}}}},
|
||||
ROIPoolingShapes{{{}, {{1, 3, 8, 8}}}, {{}, {{3, 5}}}},
|
||||
ROIPoolingShapes{{{}, {{3, 4, 50, 50}}}, {{}, {{3, 5}}}},
|
||||
ROIPoolingShapes{{{}, {{3, 4, 50, 50}}}, {{}, {{5, 5}}}},
|
||||
ROIPoolingShapes{
|
||||
// input 0
|
||||
{
|
||||
// dynamic
|
||||
{-1, -1, -1, -1},
|
||||
// static
|
||||
{
|
||||
{3, 4, 50, 50}, {3, 4, 50, 50}, {3, 4, 50, 50}, {1, 3, 8, 8}, {1, 3, 8, 8}, {3, 4, 50, 50}
|
||||
}
|
||||
},
|
||||
// input 1
|
||||
{
|
||||
// dynamic
|
||||
{-1, 5},
|
||||
// static
|
||||
{
|
||||
{1, 5}, {3, 5}, {5, 5}, {1, 5}, {3, 5}, {5, 5}
|
||||
}
|
||||
},
|
||||
},
|
||||
ROIPoolingShapes{
|
||||
// input 0
|
||||
{
|
||||
// dynamic
|
||||
{-1, {3, 5}, {7, 60}, -1},
|
||||
// static
|
||||
{
|
||||
{3, 4, 50, 50}, {1, 3, 7, 8}, {3, 4, 50, 50}, {1, 3, 7, 8},
|
||||
}
|
||||
},
|
||||
// input 1
|
||||
{
|
||||
// dynamic
|
||||
{{1, 5}, 5},
|
||||
// static
|
||||
{
|
||||
{1, 5}, {2, 5}, {1, 5}, {2, 5}
|
||||
}
|
||||
},
|
||||
},
|
||||
ROIPoolingShapes{
|
||||
// input 0
|
||||
{
|
||||
// dynamic
|
||||
{{1, 8}, {3, 5}, {7, 60}, {5, 50}},
|
||||
// static
|
||||
{
|
||||
{3, 4, 50, 50}, {1, 3, 7, 8}, {8, 5, 59, 5}, {1, 3, 7, 8},
|
||||
}
|
||||
},
|
||||
// input 1
|
||||
{
|
||||
// dynamic
|
||||
{{1, 5}, 5},
|
||||
// static
|
||||
{
|
||||
{1, 5}, {2, 5}, {1, 5}, {2, 5}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const std::vector<std::vector<size_t>> pooledShapes_max = {
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{6, 6}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<size_t>> pooledShapes_bilinear = {
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{6, 6}
|
||||
};
|
||||
|
||||
const std::vector<InferenceEngine::Precision> netPRCs = {InferenceEngine::Precision::FP32};
|
||||
|
||||
const std::vector<float> spatial_scales = {0.625f, 1.f};
|
||||
|
||||
const auto test_ROIPooling_max = ::testing::Combine(::testing::ValuesIn(inShapes),
|
||||
::testing::ValuesIn(pooledShapes_max),
|
||||
::testing::ValuesIn(spatial_scales),
|
||||
::testing::Values(ngraph::helpers::ROIPoolingTypes::ROI_MAX),
|
||||
::testing::ValuesIn(netPRCs));
|
||||
|
||||
const auto test_ROIPooling_bilinear = ::testing::Combine(::testing::ValuesIn(inShapes),
|
||||
::testing::ValuesIn(pooledShapes_bilinear),
|
||||
::testing::Values(spatial_scales[1]),
|
||||
::testing::Values(ngraph::helpers::ROIPoolingTypes::ROI_BILINEAR),
|
||||
::testing::ValuesIn(netPRCs));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ROIPoolingGPU_max, ROIPoolingLayerGPUTest,
|
||||
::testing::Combine(test_ROIPooling_max,
|
||||
::testing::Values(ProposalGenerationMode::RANDOM),
|
||||
::testing::Values(emptyAdditionalConfig)),
|
||||
ROIPoolingLayerGPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ROIPoolingGPU_bilinear, ROIPoolingLayerGPUTest,
|
||||
::testing::Combine(test_ROIPooling_bilinear,
|
||||
::testing::Values(ProposalGenerationMode::RANDOM),
|
||||
::testing::Values(emptyAdditionalConfig)),
|
||||
ROIPoolingLayerGPUTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ROIPoolingGPU_bilinear_ultimateRightBorderProposal, ROIPoolingLayerGPUTest,
|
||||
::testing::Combine(::testing::Combine(::testing::Values(ROIPoolingShapes{{{}, {{1, 1, 50, 50}}}, {{}, {{1, 5}}}}),
|
||||
::testing::Values(std::vector<size_t> { 4, 4 }),
|
||||
::testing::Values(spatial_scales[1]),
|
||||
::testing::Values(ngraph::helpers::ROIPoolingTypes::ROI_BILINEAR),
|
||||
::testing::Values(InferenceEngine::Precision::FP32)),
|
||||
::testing::Values(ProposalGenerationMode::ULTIMATE_RIGHT_BORDER),
|
||||
::testing::Values(emptyAdditionalConfig)),
|
||||
ROIPoolingLayerGPUTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
} // namespace GPULayerTestsDefinitions
|
||||
@@ -0,0 +1,85 @@
|
||||
// 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/roi_pooling.hpp>
|
||||
#include <intel_gpu/primitives/data.hpp>
|
||||
|
||||
#include "roi_pooling_inst.h"
|
||||
|
||||
#include "program_wrapper.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace cldnn;
|
||||
using namespace ::tests;
|
||||
|
||||
namespace shape_infer_tests {
|
||||
|
||||
const float position_sensitive = false;
|
||||
const pooling_mode mode = pooling_mode::bilinear;
|
||||
|
||||
struct roi_pooling_test_params {
|
||||
layout in0_layout;
|
||||
layout in1_layout;
|
||||
int pooled_height;
|
||||
int pooled_width;
|
||||
float spatial_scale;
|
||||
layout expected_layout;
|
||||
};
|
||||
|
||||
class roi_pooling_test : public testing::TestWithParam<roi_pooling_test_params> { };
|
||||
|
||||
TEST_P(roi_pooling_test, shape_infer) {
|
||||
auto p = GetParam();
|
||||
|
||||
auto& engine = get_test_engine();
|
||||
|
||||
auto input0_layout_prim = std::make_shared<input_layout>("input0", p.in0_layout);
|
||||
auto input1_layout_prim = std::make_shared<input_layout>("input1", p.in1_layout);
|
||||
auto roi_pooling_prim = std::make_shared<roi_pooling>("roi_pooling",
|
||||
input_info("input0"),
|
||||
input_info("input1"),
|
||||
mode,
|
||||
position_sensitive,
|
||||
p.pooled_width,
|
||||
p.pooled_height,
|
||||
p.spatial_scale,
|
||||
0, 1, 1);
|
||||
|
||||
cldnn::program prog(engine);
|
||||
|
||||
auto& input0_layout_node = prog.get_or_create(input0_layout_prim);
|
||||
auto& input1_layout_node = prog.get_or_create(input1_layout_prim);
|
||||
|
||||
auto& roi_pooling_node = prog.get_or_create(roi_pooling_prim);
|
||||
program_wrapper::add_connection(prog, input0_layout_node, roi_pooling_node);
|
||||
program_wrapper::add_connection(prog, input1_layout_node, roi_pooling_node);
|
||||
|
||||
auto res = roi_pooling_inst::calc_output_layouts<ov::PartialShape>(roi_pooling_node, *roi_pooling_node.get_kernel_impl_params());
|
||||
|
||||
ASSERT_EQ(res.size(), 1);
|
||||
ASSERT_EQ(res[0], p.expected_layout);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke, roi_pooling_test,
|
||||
testing::ValuesIn(std::vector<roi_pooling_test_params>{
|
||||
{
|
||||
layout{ov::PartialShape{1, 3, 8, 8}, data_types::f32, format::bfyx},
|
||||
layout{ov::PartialShape{3, 5}, data_types::f32, format::bfyx},
|
||||
3, 3, 0.625f,
|
||||
layout{ov::PartialShape{3, 3, 3, 3}, data_types::f32, format::bfyx}
|
||||
},
|
||||
{
|
||||
layout{ov::PartialShape::dynamic(4), data_types::f32, format::bfyx},
|
||||
layout{ov::PartialShape{-1 , 5}, data_types::f32, format::bfyx},
|
||||
5, 5, 1.f,
|
||||
layout{ov::PartialShape{ov::Dimension::dynamic(), ov::Dimension::dynamic(), 5, 5}, data_types::f32, format::bfyx}
|
||||
}
|
||||
}));
|
||||
|
||||
} // shape_infer_tests
|
||||
Reference in new issue
Block a user