[GPU][ROIAlignRotated]: Fixed a bug with wrong batch indexing and added functional test for the op. (#24611)
This is a follow up to #23955 ### Details: - Added functional test for ROI Align Rotated - Fixed a "bug" with wrong batch index inside cl kernel revealed by functional test for ROI Align Rotated. ### Tickets: - *[141877](https://jira.devtools.intel.com/browse/CVS-141877)*
This commit is contained in:
parent
94f287a051
commit
9732d4ac17
|
|
@ -17,6 +17,7 @@
|
|||
#include "openvino/op/split.hpp"
|
||||
#include "openvino/op/prelu.hpp"
|
||||
#include "openvino/op/roi_align.hpp"
|
||||
#include "openvino/op/roi_align_rotated.hpp"
|
||||
#include "openvino/op/variadic_split.hpp"
|
||||
#include "openvino/op/util/op_types.hpp"
|
||||
#include "openvino/op/loop.hpp"
|
||||
|
|
@ -221,7 +222,8 @@ static void CreateConstantOp(ProgramBuilder& p, const std::shared_ptr<ov::op::v0
|
|||
if (constDims.size() == 4 && input_shape.size() == 3) { // In case of weight dim 4 and input dim 3,
|
||||
constDims.push_back(1); // The weight cldnn tensor adds 1d to the end as the input cldnn tensor does
|
||||
}
|
||||
} else if (ov::is_type<ov::op::v3::ROIAlign>(outOp) || ov::is_type<ov::op::v9::ROIAlign>(outOp)) {
|
||||
} else if (ov::is_type<ov::op::v3::ROIAlign>(outOp) || ov::is_type<ov::op::v9::ROIAlign>(outOp) ||
|
||||
ov::is_type<ov::op::v15::ROIAlignRotated>(outOp)) { //< Hacks...
|
||||
consts[op].needsBatchInterpretation = constDims.size() == 1;
|
||||
} else if ((ov::is_type<ov::op::v5::Loop>(outOp) || ov::is_type<ov::op::v0::TensorIterator>(outOp))) {
|
||||
// when inner network has 1d parameter which is connected to outer loop's constant 1d data,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
#include "single_op_tests/roi_align_rotated.hpp"
|
||||
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
namespace {
|
||||
using ov::test::ROIAlignRotatedLayerTest;
|
||||
|
||||
const std::vector<ov::element::Type> netPRCs = {
|
||||
ov::element::f32
|
||||
// There is no possibility to test ROIAlign in fp16 precision,
|
||||
// because on edge cases where in fp32 version ROI value is
|
||||
// a little bit smaller than the nearest integer value,
|
||||
// it would be bigger than the nearest integer in fp16 precision.
|
||||
// Such behavior leads to completely different results of ROIAlign
|
||||
// in fp32 and fp16 precisions.
|
||||
// In real AI applications this problem is solved by precision-aware training.
|
||||
|
||||
// ov::element::f16
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(gtest_smoke_TestsROIAlignRotatedROIAlignLayerTest_EvalGenerateName_,
|
||||
ROIAlignRotatedLayerTest,
|
||||
::testing::Combine(::testing::ValuesIn(ov::test::static_shapes_to_test_representation(
|
||||
std::vector<std::vector<ov::Shape>>{{{3, 8, 16, 16}},
|
||||
{{2, 1, 16, 10}},
|
||||
{{4, 3, 5, 12}}})),
|
||||
::testing::ValuesIn(std::vector<int>{2, 4}),
|
||||
::testing::Values(2),
|
||||
::testing::Values(2),
|
||||
::testing::Values(2),
|
||||
::testing::ValuesIn(std::vector<float>{1, 0.625}),
|
||||
::testing::ValuesIn(std::vector<bool>{true, false}),
|
||||
::testing::ValuesIn(netPRCs),
|
||||
::testing::Values(ov::test::utils::DEVICE_GPU)),
|
||||
ROIAlignRotatedLayerTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared_test_classes/single_op/roi_align_rotated.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
TEST_P(ROIAlignRotatedLayerTest, Inference) {
|
||||
run();
|
||||
}
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
using roialignrotatedParams = std::tuple<std::vector<InputShape>, // Feature map shape
|
||||
int, // Num of Rois
|
||||
int, // Pooled h
|
||||
int, // Pooled w
|
||||
int, // Sampling ratio
|
||||
float, // Spatial scale
|
||||
bool, // Clockwise mode
|
||||
ov::element::Type, // Model type
|
||||
ov::test::TargetDevice>; // Device name
|
||||
|
||||
class ROIAlignRotatedLayerTest : public testing::WithParamInterface<roialignrotatedParams>,
|
||||
virtual public ov::test::SubgraphBaseTest {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<roialignrotatedParams>& obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright (C) 2018-2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "shared_test_classes/single_op/roi_align_rotated.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
#include "openvino/core/enum_names.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
|
||||
static constexpr int ROI_DEF_SIZE = 5;
|
||||
static constexpr int SEED = 7877;
|
||||
static constexpr float PI = 3.14159265358979323846f;
|
||||
|
||||
struct TestParams {
|
||||
std::vector<InputShape> input_shapes;
|
||||
int num_rois;
|
||||
int pooled_h;
|
||||
int pooled_w;
|
||||
int sampliong_ratio;
|
||||
float spatial_scale;
|
||||
bool clockwise_mode;
|
||||
ov::element::Type model_type;
|
||||
std::string target_device;
|
||||
};
|
||||
|
||||
static TestParams ExtractTestParams(const roialignrotatedParams& param) {
|
||||
TestParams tp;
|
||||
std::tie(tp.input_shapes,
|
||||
tp.num_rois,
|
||||
tp.pooled_h,
|
||||
tp.pooled_w,
|
||||
tp.sampliong_ratio,
|
||||
tp.spatial_scale,
|
||||
tp.clockwise_mode,
|
||||
tp.model_type,
|
||||
tp.target_device) = param;
|
||||
return tp;
|
||||
}
|
||||
|
||||
static float RandomFloat(float low, float high) {
|
||||
static std::default_random_engine engine(SEED);
|
||||
std::uniform_real_distribution<float> dis(low, high);
|
||||
return dis(engine);
|
||||
}
|
||||
|
||||
static std::vector<float> FillRoisTensor(int num_rois, int height, int width) {
|
||||
std::vector<float> rois;
|
||||
rois.resize(num_rois * ROI_DEF_SIZE);
|
||||
|
||||
for (int i = 0; i < rois.size() / ROI_DEF_SIZE; i++) {
|
||||
// center_x, center_y, width, height, angle
|
||||
rois[i * ROI_DEF_SIZE + 0] = RandomFloat(0.0f, width);
|
||||
rois[i * ROI_DEF_SIZE + 1] = RandomFloat(0.0f, height);
|
||||
rois[i * ROI_DEF_SIZE + 2] = RandomFloat(0.0f, width);
|
||||
rois[i * ROI_DEF_SIZE + 3] = RandomFloat(0.0f, height);
|
||||
rois[i * ROI_DEF_SIZE + 4] = RandomFloat(0.0f, 2 * PI);
|
||||
}
|
||||
|
||||
return rois;
|
||||
}
|
||||
|
||||
static std::vector<int> FillBAtchIdxTensor(int num_rois, int batch_size) {
|
||||
std::vector<int> idx;
|
||||
idx.resize(num_rois);
|
||||
int batch_id = 0;
|
||||
for (int i = 0; i < idx.size(); i++) {
|
||||
idx[i] = batch_id;
|
||||
batch_id = (batch_id + 1) % batch_size;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
std::string ROIAlignRotatedLayerTest::getTestCaseName(const testing::TestParamInfo<roialignrotatedParams>& obj) {
|
||||
const TestParams tp = ExtractTestParams(obj.param);
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=(";
|
||||
for (size_t i = 0lu; i < tp.input_shapes.size(); i++) {
|
||||
result << ov::test::utils::partialShape2str({tp.input_shapes[i].first})
|
||||
<< (i < tp.input_shapes.size() - 1lu ? "_" : "");
|
||||
}
|
||||
result << ")_TS=";
|
||||
for (size_t i = 0lu; i < tp.input_shapes.front().second.size(); i++) {
|
||||
result << "{";
|
||||
for (size_t j = 0lu; j < tp.input_shapes.size(); j++) {
|
||||
result << ov::test::utils::vec2str(tp.input_shapes[j].second[i])
|
||||
<< (j < tp.input_shapes.size() - 1lu ? "_" : "");
|
||||
}
|
||||
result << "}_";
|
||||
}
|
||||
result << "numRois=" << tp.num_rois << "_";
|
||||
result << "pooledH=" << tp.pooled_h << "_";
|
||||
result << "pooledW=" << tp.pooled_w << "_";
|
||||
result << "samplingRatio=" << tp.sampliong_ratio << "_";
|
||||
result << "spatialScale=" << tp.spatial_scale << "_";
|
||||
result << "clockwiseMode=" << tp.clockwise_mode << "_";
|
||||
result << "modelType=" << tp.model_type.to_string() << "_";
|
||||
result << "trgDev=" << tp.target_device;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void ROIAlignRotatedLayerTest::SetUp() {
|
||||
const TestParams tp = ExtractTestParams(this->GetParam());
|
||||
targetDevice = tp.target_device;
|
||||
init_input_shapes(tp.input_shapes);
|
||||
|
||||
const auto input_batch_size = inputDynamicShapes[0][0].get_length();
|
||||
const auto input_height = inputDynamicShapes[0][2].get_length();
|
||||
const auto input_width = inputDynamicShapes[0][3].get_length();
|
||||
|
||||
auto input = std::make_shared<ov::op::v0::Parameter>(tp.model_type, inputDynamicShapes[0]);
|
||||
const auto rois_shape = ov::Shape{static_cast<size_t>(tp.num_rois), ROI_DEF_SIZE};
|
||||
const auto rois_idx_shape = ov::Shape{static_cast<size_t>(tp.num_rois)};
|
||||
|
||||
auto rois = std::make_shared<ov::op::v0::Constant>(tp.model_type,
|
||||
rois_shape,
|
||||
FillRoisTensor(tp.num_rois, input_height, input_width).data());
|
||||
auto rois_idx = std::make_shared<ov::op::v0::Constant>(ov::element::i32,
|
||||
rois_idx_shape,
|
||||
FillBAtchIdxTensor(tp.num_rois, input_batch_size).data());
|
||||
auto roi_align = std::make_shared<ov::op::v15::ROIAlignRotated>(input,
|
||||
rois,
|
||||
rois_idx,
|
||||
tp.pooled_h,
|
||||
tp.pooled_w,
|
||||
tp.sampliong_ratio,
|
||||
tp.spatial_scale,
|
||||
tp.clockwise_mode);
|
||||
function = std::make_shared<ov::Model>(roi_align->outputs(), ov::ParameterVector{input}, "roi_align_rotated");
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
|
@ -287,6 +287,28 @@ TEST_DATA(LIST(1, 1, 5, 5),
|
|||
LIST(0),
|
||||
LIST(5.1271, 1.2473, 6.1773, 2.9598, 7.2275, 3.2300, 8.2777, 3.7458, 9.3279, 4.4060),
|
||||
"roi_align_rotated_all_features");
|
||||
TEST_DATA(LIST(1, 1, 2, 5),
|
||||
2,
|
||||
2,
|
||||
1.0f,
|
||||
2,
|
||||
true,
|
||||
LIST(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
|
||||
LIST(0.5, 0.5, 1, 1, 0),
|
||||
LIST(0),
|
||||
LIST(1.0, 1.25, 2.25, 2.50),
|
||||
"input_image_not_rectangular");
|
||||
TEST_DATA(LIST(2, 1, 2, 5),
|
||||
2,
|
||||
2,
|
||||
1.0f,
|
||||
2,
|
||||
true,
|
||||
LIST(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20),
|
||||
LIST(0.5, 1., 2., 5., 0.5, 0., 2., 5., 1., 0.),
|
||||
LIST(0, 1),
|
||||
LIST(0.5201, 1.9866, 2.5219, 3.0896, 0.0000, 16.7500, 0.0000, 16.7500),
|
||||
"input_image_not_rectangular_batch_2");
|
||||
|
||||
#undef PI
|
||||
#undef LIST
|
||||
|
|
|
|||
Loading…
Reference in New Issue