Liubo/roi align 9 ov core cpu plugin (#11188)
* roi_align_9: ov_core, transformations, template_plugin * roi_align_9: CPU Plugin * keep only constructor with enums which is aligned with spec * remove evaluate function for ROIAlign_9 * Add op check test for operation ROIAlign-9 * Apply suggestions from code review * fix version name from 'v0' to 'v3' in transform part * use common shape_infer function for v3 and v9 * remove'tf_' prefix for ROIAlign::AlignedMode to avoid misleading for models from different platforms
This commit is contained in:
1 parent
ad61593aa5
commit
eddd31f58f
26 files changed
+1022
-35
No files matched your search
@@ -58,7 +58,7 @@
|
||||
* **Description**: *aligned_mode* specifies how to transform the coordinate in original tensor to the resized tensor.
|
||||
* **Range of values**: name of the transformation mode in string format (here spatial_scale is resized_shape[x] / original_shape[x], resized_shape[x] is the shape of resized tensor in axis x, original_shape[x] is the shape of original tensor in axis x and x_original is a coordinate in axis x, for any axis x from the input axes):
|
||||
* *asymmetric* - the coordinate in the resized tensor axis x is calculated according to the formula x_original * spatial_scale
|
||||
* *tf_half_pixel_for_nn* - the coordinate in the resized tensor axis x is x_original * spatial_scale - 0.5
|
||||
* *half_pixel_for_nn* - the coordinate in the resized tensor axis x is x_original * spatial_scale - 0.5
|
||||
* *half_pixel* - the coordinate in the resized tensor axis x is calculated as ((x_original + 0.5) * spatial_scale) - 0.5
|
||||
* **Type**: string
|
||||
* **Default value**: asymmetric
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include <ngraph/runtime/reference/reorg_yolo.hpp>
|
||||
#include <ngraph/runtime/reference/reverse_sequence.hpp>
|
||||
#include <ngraph/runtime/reference/rnn_cell.hpp>
|
||||
#include <ngraph/runtime/reference/roi_align.hpp>
|
||||
#include <ngraph/runtime/reference/roi_pooling.hpp>
|
||||
#include <ngraph/runtime/reference/roll.hpp>
|
||||
#include <ngraph/runtime/reference/scatter_nd_update.hpp>
|
||||
@@ -3084,6 +3085,40 @@ bool evaluate(const shared_ptr<op::v5::GRUSequence>& op,
|
||||
return true;
|
||||
}
|
||||
template <element::Type_t ET>
|
||||
bool evaluate(const shared_ptr<op::v9::ROIAlign>& op, const HostTensorVector& outputs, const HostTensorVector& inputs) {
|
||||
using T = typename element_type_traits<ET>::value_type;
|
||||
std::vector<int64_t> batch_indices_vec_scaled_up = host_tensor_2_vector<int64_t>(inputs[2]);
|
||||
op::v3::ROIAlign::PoolingMode m_mode_v3;
|
||||
switch (op->get_mode()) {
|
||||
case op::v9::ROIAlign::PoolingMode::AVG: {
|
||||
m_mode_v3 = op::v3::ROIAlign::PoolingMode::AVG;
|
||||
break;
|
||||
}
|
||||
case op::v9::ROIAlign::PoolingMode::MAX: {
|
||||
m_mode_v3 = op::v3::ROIAlign::PoolingMode::MAX;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NGRAPH_CHECK(false, "unsupported PoolingMode ");
|
||||
}
|
||||
}
|
||||
runtime::reference::roi_align<T>(inputs[0]->get_data_ptr<const T>(),
|
||||
inputs[1]->get_data_ptr<const T>(),
|
||||
batch_indices_vec_scaled_up.data(),
|
||||
outputs[0]->get_data_ptr<T>(),
|
||||
op->get_input_shape(0),
|
||||
op->get_input_shape(1),
|
||||
op->get_input_shape(2),
|
||||
op->get_output_shape(0),
|
||||
op->get_pooled_h(),
|
||||
op->get_pooled_w(),
|
||||
op->get_sampling_ratio(),
|
||||
op->get_spatial_scale(),
|
||||
m_mode_v3,
|
||||
op->get_aligned_mode());
|
||||
return true;
|
||||
}
|
||||
template <element::Type_t ET>
|
||||
bool evaluate(const shared_ptr<op::v0::ROIPooling>& op,
|
||||
const HostTensorVector& outputs,
|
||||
const HostTensorVector& inputs) {
|
||||
|
||||
@@ -132,3 +132,4 @@ NGRAPH_OP(PriorBox, ngraph::op::v8)
|
||||
NGRAPH_OP(PRelu, op::v0)
|
||||
|
||||
NGRAPH_OP(RDFT, op::v9)
|
||||
NGRAPH_OP(ROIAlign, op::v9)
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "openvino/opsets/opset9.hpp"
|
||||
#include "openvino/opsets/opset5.hpp"
|
||||
#include "openvino/opsets/opset4.hpp"
|
||||
#include "openvino/opsets/opset3.hpp"
|
||||
@@ -49,6 +50,43 @@ struct ROIAlignParams {
|
||||
std::string testcaseName;
|
||||
};
|
||||
|
||||
struct ROIAlignV9Params {
|
||||
template <class IT>
|
||||
ROIAlignV9Params(const PartialShape& pShape, const element::Type& iType, const std::vector<IT>& iValues,
|
||||
const reference_tests::Tensor& expectedFeatureMap,
|
||||
const reference_tests::Tensor& coords, const reference_tests::Tensor& roiIdx,
|
||||
const int32_t pooledH, const int32_t pooledW,
|
||||
const float spatialScale, const int32_t poolingRatio, const std::string& poolingMode,
|
||||
const std::string& alignedMode, const std::string& testcaseName)
|
||||
: pShape(pShape),
|
||||
iType(iType),
|
||||
featureMap(CreateTensor(iType, iValues)),
|
||||
expectedFeatureMap(expectedFeatureMap),
|
||||
coords(coords),
|
||||
roiIdx(roiIdx),
|
||||
pooledH(pooledH),
|
||||
pooledW(pooledW),
|
||||
spatialScale(spatialScale),
|
||||
poolingRatio(poolingRatio),
|
||||
poolingMode(poolingMode),
|
||||
alignedMode(alignedMode),
|
||||
testcaseName(testcaseName) {}
|
||||
|
||||
PartialShape pShape;
|
||||
element::Type iType;
|
||||
ov::Tensor featureMap;
|
||||
reference_tests::Tensor expectedFeatureMap;
|
||||
reference_tests::Tensor coords;
|
||||
reference_tests::Tensor roiIdx;
|
||||
int32_t pooledH;
|
||||
int32_t pooledW;
|
||||
float spatialScale;
|
||||
int32_t poolingRatio;
|
||||
std::string poolingMode;
|
||||
std::string alignedMode;
|
||||
std::string testcaseName;
|
||||
};
|
||||
|
||||
class ReferenceROIAlignTest : public testing::TestWithParam<ROIAlignParams>, public CommonReferenceTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
@@ -98,10 +136,67 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class ReferenceROIAlignV9Test : public testing::TestWithParam<ROIAlignV9Params>, public CommonReferenceTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto params = GetParam();
|
||||
function = CreateFunction(params);
|
||||
inputData = {params.featureMap};
|
||||
refOutData = {params.expectedFeatureMap.data};
|
||||
}
|
||||
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<ROIAlignV9Params>& obj) {
|
||||
auto param = obj.param;
|
||||
std::ostringstream result;
|
||||
result << "iType=" << param.iType;
|
||||
result << "_pShape=" << param.pShape;
|
||||
result << "_efType=" << param.expectedFeatureMap.type;
|
||||
result << "_efShape=" << param.expectedFeatureMap.shape;
|
||||
result << "_cType=" << param.coords.type;
|
||||
result << "_cShape=" << param.coords.shape;
|
||||
result << "_rType=" << param.roiIdx.type;
|
||||
result << "_rShape=" << param.roiIdx.shape;
|
||||
result << "_pooledH=" << param.pooledH;
|
||||
result << "_pooledW=" << param.pooledW;
|
||||
result << "_spatialScale=" << param.spatialScale;
|
||||
result << "_poolingRatio=" << param.poolingRatio;
|
||||
result << "_poolingMode=" << param.poolingMode;
|
||||
result << "_alignedMode=" << param.alignedMode;
|
||||
if (param.testcaseName != "") {
|
||||
result << "_=" << param.testcaseName;
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::shared_ptr<Model> CreateFunction(const ROIAlignV9Params& params) {
|
||||
const auto featureMap = std::make_shared<opset1::Parameter>(params.iType, params.pShape);
|
||||
const auto coords = std::make_shared<opset1::Constant>(params.coords.type, params.coords.shape, params.coords.data.data());
|
||||
const auto roisIdx = std::make_shared<opset1::Constant>(params.roiIdx.type, params.roiIdx.shape, params.roiIdx.data.data());
|
||||
const auto pooling_mode = EnumNames<opset9::ROIAlign::PoolingMode>::as_enum(params.poolingMode);
|
||||
const auto aligned_mode = EnumNames<opset9::ROIAlign::AlignedMode>::as_enum(params.alignedMode);
|
||||
const auto roi_align = std::make_shared<opset9::ROIAlign>(featureMap,
|
||||
coords,
|
||||
roisIdx,
|
||||
params.pooledH,
|
||||
params.pooledW,
|
||||
params.poolingRatio,
|
||||
params.spatialScale,
|
||||
pooling_mode,
|
||||
aligned_mode);
|
||||
auto f = std::make_shared<Model>(NodeVector{roi_align}, ParameterVector{featureMap});
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ReferenceROIAlignTest, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
TEST_P(ReferenceROIAlignV9Test, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
template <element::Type_t ET, element::Type_t ET_IND>
|
||||
std::vector<ROIAlignParams> generateParams() {
|
||||
using T = typename element_type_traits<ET>::value_type;
|
||||
@@ -173,6 +268,94 @@ std::vector<ROIAlignParams> generateCombinedParams() {
|
||||
return combinedParams;
|
||||
}
|
||||
|
||||
template <element::Type_t ET, element::Type_t ET_IND>
|
||||
std::vector<ROIAlignV9Params> generateParamsV9() {
|
||||
using T = typename element_type_traits<ET>::value_type;
|
||||
using T_IND = typename element_type_traits<ET_IND>::value_type;
|
||||
std::vector<ROIAlignV9Params> params {
|
||||
ROIAlignV9Params(PartialShape{2, 1, 8, 8}, ET,
|
||||
std::vector<T>{0, 1, 8, 5, 5, 2, 0, 7, 7, 10, 4, 5, 9, 0, 0, 5,
|
||||
7, 0, 4, 0, 4, 7, 6, 10, 9, 5, 1, 7, 4, 7, 10, 8,
|
||||
2, 0, 8, 3, 6, 8, 10, 4, 2, 10, 7, 8, 7, 0, 6, 9,
|
||||
2, 4, 8, 5, 2, 3, 3, 1, 5, 9, 10, 0, 9, 5, 5, 3,
|
||||
10, 5, 2, 0, 10, 0, 5, 4, 3, 10, 5, 5, 10, 0, 8, 8,
|
||||
9, 1, 0, 7, 9, 6, 8, 7, 10, 9, 2, 3, 3, 5, 6, 9,
|
||||
4, 9, 2, 4, 5, 5, 3, 1, 1, 6, 8, 0, 5, 5, 10, 8,
|
||||
6, 9, 6, 9, 1, 2, 7, 1, 1, 3, 0, 4, 0, 7, 10, 2},
|
||||
reference_tests::Tensor(ET, {2, 1, 2, 2}, std::vector<T>{3, 3.75, 4.75, 5, 3, 5.5, 2.75, 3.75}),
|
||||
reference_tests::Tensor(ET, {2, 4}, std::vector<T>{2, 2, 4, 4, 2, 2, 4, 4}),
|
||||
reference_tests::Tensor(ET_IND, {2}, std::vector<T_IND>{0, 1}),
|
||||
2, 2, 1, 2, "avg", "asymmetric", "roi_align_v9_avg_asymmetric"),
|
||||
|
||||
ROIAlignV9Params(PartialShape{2, 1, 8, 8}, ET,
|
||||
std::vector<T>{0, 1, 8, 5, 5, 2, 0, 7, 7, 10, 4, 5, 9, 0, 0, 5,
|
||||
7, 0, 4, 0, 4, 7, 6, 10, 9, 5, 1, 7, 4, 7, 10, 8,
|
||||
2, 0, 8, 3, 6, 8, 10, 4, 2, 10, 7, 8, 7, 0, 6, 9,
|
||||
2, 4, 8, 5, 2, 3, 3, 1, 5, 9, 10, 0, 9, 5, 5, 3,
|
||||
10, 5, 2, 0, 10, 0, 5, 4, 3, 10, 5, 5, 10, 0, 8, 8,
|
||||
9, 1, 0, 7, 9, 6, 8, 7, 10, 9, 2, 3, 3, 5, 6, 9,
|
||||
4, 9, 2, 4, 5, 5, 3, 1, 1, 6, 8, 0, 5, 5, 10, 8,
|
||||
6, 9, 6, 9, 1, 2, 7, 1, 1, 3, 0, 4, 0, 7, 10, 2},
|
||||
reference_tests::Tensor(ET, {2, 1, 2, 2}, std::vector<T>{3.14, 2.16, 2.86, 5.03, 1.83, 5.84, 2.77, 3.44}),
|
||||
reference_tests::Tensor(ET, {2, 4}, std::vector<T>{2, 2, 4, 4, 2, 2, 4, 4}),
|
||||
reference_tests::Tensor(ET_IND, {2}, std::vector<T_IND>{0, 1}),
|
||||
2, 2, 1, 2, "avg", "half_pixel_for_nn", "roi_align_v9_avg_half_pixel_for_nn"),
|
||||
|
||||
ROIAlignV9Params(PartialShape{2, 1, 8, 8}, ET,
|
||||
std::vector<T>{0, 1, 8, 5, 5, 2, 0, 7, 7, 10, 4, 5, 9, 0, 0, 5,
|
||||
7, 0, 4, 0, 4, 7, 6, 10, 9, 5, 1, 7, 4, 7, 10, 8,
|
||||
2, 0, 8, 3, 6, 8, 10, 4, 2, 10, 7, 8, 7, 0, 6, 9,
|
||||
2, 4, 8, 5, 2, 3, 3, 1, 5, 9, 10, 0, 9, 5, 5, 3,
|
||||
10, 5, 2, 0, 10, 0, 5, 4, 3, 10, 5, 5, 10, 0, 8, 8,
|
||||
9, 1, 0, 7, 9, 6, 8, 7, 10, 9, 2, 3, 3, 5, 6, 9,
|
||||
4, 9, 2, 4, 5, 5, 3, 1, 1, 6, 8, 0, 5, 5, 10, 8,
|
||||
6, 9, 6, 9, 1, 2, 7, 1, 1, 3, 0, 4, 0, 7, 10, 2},
|
||||
reference_tests::Tensor(ET, {2, 1, 2, 2}, std::vector<T>{4.375, 4.9375, 5.6875, 5.625, 4.625, 7.125, 3.3125, 4.3125}),
|
||||
reference_tests::Tensor(ET, {2, 4}, std::vector<T>{2, 2, 4, 4, 2, 2, 4, 4}),
|
||||
reference_tests::Tensor(ET_IND, {2}, std::vector<T_IND>{0, 1}),
|
||||
2, 2, 1, 2, "max", "half_pixel", "roi_align_v9_max_half_pixel"),
|
||||
};
|
||||
return params;
|
||||
}
|
||||
|
||||
std::vector<ROIAlignV9Params> generateCombinedParamsV9() {
|
||||
const std::vector<std::vector<ROIAlignV9Params>> generatedParams {
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::i8>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::i8>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::i8>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::i16>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::i16>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::i16>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::i32>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::i32>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::i32>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::i64>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::i64>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::i64>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::u8>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::u8>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::u8>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::u16>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::u16>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::u16>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::u32>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::u32>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::u32>(),
|
||||
generateParamsV9<element::Type_t::bf16, element::Type_t::u64>(),
|
||||
generateParamsV9<element::Type_t::f16, element::Type_t::u64>(),
|
||||
generateParamsV9<element::Type_t::f32, element::Type_t::u64>(),
|
||||
};
|
||||
std::vector<ROIAlignV9Params> combinedParams;
|
||||
|
||||
for (const auto& params : generatedParams) {
|
||||
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
|
||||
}
|
||||
return combinedParams;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ROIAlign_With_Hardcoded_Refs, ReferenceROIAlignTest,
|
||||
testing::ValuesIn(generateCombinedParams()), ReferenceROIAlignTest::getTestCaseName);
|
||||
} // namespace
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ROIAlignV9_With_Hardcoded_Refs, ReferenceROIAlignV9Test,
|
||||
testing::ValuesIn(generateCombinedParamsV9()), ReferenceROIAlignV9Test::getTestCaseName);
|
||||
} // namespace
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ngraph/pass/graph_rewrite.hpp>
|
||||
#include <transformations_visibility.hpp>
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API ConvertROIAlign3To9;
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ngraph
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief ConvertROIAlign3To9 converts v3::ROIAlign into v9::ROIAlign.
|
||||
*/
|
||||
class ngraph::pass::ConvertROIAlign3To9 : public ngraph::pass::MatcherPass {
|
||||
public:
|
||||
OPENVINO_RTTI("ConvertROIAlign3To9", "0");
|
||||
ConvertROIAlign3To9();
|
||||
};
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ngraph/pass/graph_rewrite.hpp>
|
||||
#include <transformations_visibility.hpp>
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API ConvertROIAlign9To3;
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ngraph
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief ConvertROIAlign9To3 converts v9::ROIAlign into v3::ROIAlign.
|
||||
*/
|
||||
class ngraph::pass::ConvertROIAlign9To3 : public ngraph::pass::MatcherPass {
|
||||
public:
|
||||
OPENVINO_RTTI("ConvertROIAlign9To3", "0");
|
||||
ConvertROIAlign9To3();
|
||||
};
|
||||
+4
@@ -84,6 +84,8 @@
|
||||
#include "transformations/op_conversions/convert_pad_to_group_conv.hpp"
|
||||
#include "transformations/op_conversions/convert_prior_box_v8_to_v0.hpp"
|
||||
#include "transformations/op_conversions/convert_reduce_to_pooling.hpp"
|
||||
#include "transformations/op_conversions/convert_roi_align_v3_to_v9.hpp"
|
||||
#include "transformations/op_conversions/convert_roi_align_v9_to_v3.hpp"
|
||||
#include "transformations/op_conversions/convert_scatter_elements_to_scatter.hpp"
|
||||
#include "transformations/op_conversions/convert_softmax_downgrade.hpp"
|
||||
#include "transformations/op_conversions/convert_softmax_upgrade.hpp"
|
||||
@@ -197,6 +199,8 @@ bool ngraph::pass::CommonOptimizations::run_on_model(const std::shared_ptr<ngrap
|
||||
manager.register_pass<ngraph::pass::ConvertPriorBox8To0>(); // not plugins implemented priorbox8
|
||||
manager.register_pass<ngraph::pass::ConvertDetectionOutput1ToDetectionOutput8, false>();
|
||||
manager.register_pass<ngraph::pass::ConvertDetectionOutput8ToDetectionOutput1>();
|
||||
manager.register_pass<ngraph::pass::ConvertROIAlign3To9, false>();
|
||||
manager.register_pass<ngraph::pass::ConvertROIAlign9To3>();
|
||||
|
||||
auto fq_fusions = manager.register_pass<ngraph::pass::GraphRewrite>();
|
||||
fq_fusions->add_matcher<ngraph::pass::FakeQuantizeMulFusion>();
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_roi_align_v3_to_v9.hpp"
|
||||
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
#include <ngraph/rt_info.hpp>
|
||||
|
||||
#include "itt.hpp"
|
||||
|
||||
ngraph::pass::ConvertROIAlign3To9::ConvertROIAlign3To9() {
|
||||
MATCHER_SCOPE(ConvertROIAlign3To9);
|
||||
|
||||
auto roi_align_v3 = pattern::wrap_type<ngraph::opset3::ROIAlign>();
|
||||
|
||||
ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||
auto roi_align_v3_node = std::dynamic_pointer_cast<ngraph::opset3::ROIAlign>(m.get_match_root());
|
||||
if (!roi_align_v3_node)
|
||||
return false;
|
||||
|
||||
const int pooled_h = roi_align_v3_node->get_pooled_h();
|
||||
const int pooled_w = roi_align_v3_node->get_pooled_w();
|
||||
const int sampling_ratio = roi_align_v3_node->get_sampling_ratio();
|
||||
const float spatial_scale = roi_align_v3_node->get_spatial_scale();
|
||||
ngraph::opset3::ROIAlign::PoolingMode m_mode_v3 = roi_align_v3_node->get_mode();
|
||||
ngraph::opset9::ROIAlign::PoolingMode m_mode_v9;
|
||||
switch (m_mode_v3) {
|
||||
case ngraph::opset3::ROIAlign::PoolingMode::AVG: {
|
||||
m_mode_v9 = ngraph::opset9::ROIAlign::PoolingMode::AVG;
|
||||
break;
|
||||
}
|
||||
case ngraph::opset3::ROIAlign::PoolingMode::MAX: {
|
||||
m_mode_v9 = ngraph::opset9::ROIAlign::PoolingMode::MAX;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw ngraph_error("unsupported PoolingMode ");
|
||||
}
|
||||
}
|
||||
|
||||
auto roi_align_v9 = std::make_shared<ngraph::opset9::ROIAlign>(roi_align_v3_node->input_value(0),
|
||||
roi_align_v3_node->input_value(1),
|
||||
roi_align_v3_node->input_value(2),
|
||||
pooled_h,
|
||||
pooled_w,
|
||||
sampling_ratio,
|
||||
spatial_scale,
|
||||
m_mode_v9);
|
||||
roi_align_v9->set_friendly_name(roi_align_v3_node->get_friendly_name());
|
||||
ngraph::copy_runtime_info(roi_align_v3_node, roi_align_v9);
|
||||
ngraph::replace_node(roi_align_v3_node, roi_align_v9);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<pattern::Matcher>(roi_align_v3, matcher_name);
|
||||
register_matcher(m, callback);
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/convert_roi_align_v9_to_v3.hpp"
|
||||
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
#include <ngraph/rt_info.hpp>
|
||||
|
||||
#include "itt.hpp"
|
||||
|
||||
ngraph::pass::ConvertROIAlign9To3::ConvertROIAlign9To3() {
|
||||
MATCHER_SCOPE(ConvertROIAlign9To3);
|
||||
|
||||
auto roi_align_v9 = pattern::wrap_type<ngraph::opset9::ROIAlign>();
|
||||
|
||||
ngraph::matcher_pass_callback callback = [=](pattern::Matcher& m) {
|
||||
auto roi_align_v9_node = std::dynamic_pointer_cast<ngraph::opset9::ROIAlign>(m.get_match_root());
|
||||
if (!roi_align_v9_node)
|
||||
return false;
|
||||
|
||||
ngraph::opset9::ROIAlign::AlignedMode aligned_mode_v9 = roi_align_v9_node->get_aligned_mode();
|
||||
if (aligned_mode_v9 != ngraph::opset9::ROIAlign::AlignedMode::ASYMMETRIC)
|
||||
return false;
|
||||
|
||||
const int pooled_h = roi_align_v9_node->get_pooled_h();
|
||||
const int pooled_w = roi_align_v9_node->get_pooled_w();
|
||||
const int sampling_ratio = roi_align_v9_node->get_sampling_ratio();
|
||||
const float spatial_scale = roi_align_v9_node->get_spatial_scale();
|
||||
ngraph::opset9::ROIAlign::PoolingMode m_mode_v9 = roi_align_v9_node->get_mode();
|
||||
ngraph::opset3::ROIAlign::PoolingMode m_mode_v3;
|
||||
switch (m_mode_v9) {
|
||||
case ngraph::opset9::ROIAlign::PoolingMode::AVG: {
|
||||
m_mode_v3 = ngraph::opset3::ROIAlign::PoolingMode::AVG;
|
||||
break;
|
||||
}
|
||||
case ngraph::opset9::ROIAlign::PoolingMode::MAX: {
|
||||
m_mode_v3 = ngraph::opset3::ROIAlign::PoolingMode::MAX;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw ngraph_error("unsupported PoolingMode ");
|
||||
}
|
||||
}
|
||||
|
||||
auto roi_align_v3 = std::make_shared<ngraph::opset3::ROIAlign>(roi_align_v9_node->input_value(0),
|
||||
roi_align_v9_node->input_value(1),
|
||||
roi_align_v9_node->input_value(2),
|
||||
pooled_h,
|
||||
pooled_w,
|
||||
sampling_ratio,
|
||||
spatial_scale,
|
||||
m_mode_v3);
|
||||
roi_align_v3->set_friendly_name(roi_align_v9_node->get_friendly_name());
|
||||
ngraph::copy_runtime_info(roi_align_v9_node, roi_align_v3);
|
||||
ngraph::replace_node(roi_align_v9_node, roi_align_v3);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<pattern::Matcher>(roi_align_v9, matcher_name);
|
||||
register_matcher(m, callback);
|
||||
}
|
||||
@@ -12,6 +12,9 @@ namespace op {
|
||||
namespace v3 {
|
||||
using ov::op::v3::ROIAlign;
|
||||
} // namespace v3
|
||||
namespace v9 {
|
||||
using ov::op::v9::ROIAlign;
|
||||
} // namespace v9
|
||||
using v3::ROIAlign;
|
||||
} // namespace op
|
||||
} // namespace ngraph
|
||||
@@ -84,6 +84,71 @@ private:
|
||||
PoolingMode m_mode;
|
||||
};
|
||||
} // namespace v3
|
||||
|
||||
namespace v9 {
|
||||
class OPENVINO_API ROIAlign : public Op {
|
||||
public:
|
||||
OPENVINO_OP("ROIAlign", "opset9");
|
||||
enum class PoolingMode { AVG, MAX };
|
||||
enum class AlignedMode { ASYMMETRIC, HALF_PIXEL_FOR_NN, HALF_PIXEL };
|
||||
|
||||
ROIAlign() = default;
|
||||
/// \brief Constructs a ROIAlign operation.
|
||||
///
|
||||
/// \param input Input feature map {N, C, H, W}
|
||||
/// \param rois Regions of interest to pool over
|
||||
/// \param batch_indices Indices of images in the batch matching
|
||||
/// the number or ROIs
|
||||
/// \param pooled_h Height of the ROI output features
|
||||
/// \param pooled_w Width of the ROI output features
|
||||
/// \param sampling_ratio Number of sampling points used to compute
|
||||
/// an output element
|
||||
/// \param spatial_scale Spatial scale factor used to translate ROI coordinates
|
||||
/// \param mode Method of pooling - 'avg' or 'max'
|
||||
/// \param aligned_mode Method of coordinates alignment - 'asymmetric', 'half_pixel_for_nn' or 'half_pixel'
|
||||
ROIAlign(const Output<Node>& input,
|
||||
const Output<Node>& rois,
|
||||
const Output<Node>& batch_indices,
|
||||
const int pooled_h,
|
||||
const int pooled_w,
|
||||
const int sampling_ratio,
|
||||
const float spatial_scale,
|
||||
const PoolingMode mode,
|
||||
const AlignedMode aligned_mode = AlignedMode::ASYMMETRIC);
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
int get_pooled_h() const {
|
||||
return m_pooled_h;
|
||||
}
|
||||
int get_pooled_w() const {
|
||||
return m_pooled_w;
|
||||
}
|
||||
int get_sampling_ratio() const {
|
||||
return m_sampling_ratio;
|
||||
}
|
||||
float get_spatial_scale() const {
|
||||
return m_spatial_scale;
|
||||
}
|
||||
PoolingMode get_mode() const {
|
||||
return m_mode;
|
||||
}
|
||||
AlignedMode get_aligned_mode() const {
|
||||
return m_aligned_mode;
|
||||
}
|
||||
|
||||
private:
|
||||
PoolingMode mode_from_string(const std::string& mode) const;
|
||||
int m_pooled_h;
|
||||
int m_pooled_w;
|
||||
int m_sampling_ratio;
|
||||
float m_spatial_scale;
|
||||
PoolingMode m_mode;
|
||||
AlignedMode m_aligned_mode;
|
||||
};
|
||||
} // namespace v9
|
||||
} // namespace op
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const op::v3::ROIAlign::PoolingMode& mode);
|
||||
@@ -99,4 +164,28 @@ public:
|
||||
BWDCMP_RTTI_DECLARATION;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const op::v9::ROIAlign::PoolingMode& mode);
|
||||
|
||||
template <>
|
||||
class OPENVINO_API AttributeAdapter<op::v9::ROIAlign::PoolingMode>
|
||||
: public EnumAttributeAdapterBase<op::v9::ROIAlign::PoolingMode> {
|
||||
public:
|
||||
AttributeAdapter(op::v9::ROIAlign::PoolingMode& value)
|
||||
: EnumAttributeAdapterBase<op::v9::ROIAlign::PoolingMode>(value) {}
|
||||
|
||||
OPENVINO_RTTI("AttributeAdapter<ov::op::v9::ROIAlign::PoolingMode>");
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const op::v9::ROIAlign::AlignedMode& mode);
|
||||
|
||||
template <>
|
||||
class OPENVINO_API AttributeAdapter<op::v9::ROIAlign::AlignedMode>
|
||||
: public EnumAttributeAdapterBase<op::v9::ROIAlign::AlignedMode> {
|
||||
public:
|
||||
AttributeAdapter(op::v9::ROIAlign::AlignedMode& value)
|
||||
: EnumAttributeAdapterBase<op::v9::ROIAlign::AlignedMode>(value) {}
|
||||
|
||||
OPENVINO_RTTI("AttributeAdapter<ov::op::v9::ROIAlign::AlignedMode>");
|
||||
};
|
||||
|
||||
} // namespace ov
|
||||
@@ -120,7 +120,6 @@ _OPENVINO_OP_REG(EmbeddingBagOffsetsSum, ov::op::v3)
|
||||
_OPENVINO_OP_REG(GRUCell, ov::op::v3)
|
||||
_OPENVINO_OP_REG(NonZero, ov::op::v3)
|
||||
_OPENVINO_OP_REG(RNNCell, ov::op::v0)
|
||||
_OPENVINO_OP_REG(ROIAlign, ov::op::v3)
|
||||
_OPENVINO_OP_REG(ScatterElementsUpdate, ov::op::v3)
|
||||
_OPENVINO_OP_REG(ScatterUpdate, ov::op::v3)
|
||||
_OPENVINO_OP_REG(ShuffleChannels, ov::op::v0)
|
||||
@@ -193,3 +192,4 @@ _OPENVINO_OP_REG(PriorBox, ov::op::v8)
|
||||
_OPENVINO_OP_REG(IRDFT, ov::op::v9)
|
||||
_OPENVINO_OP_REG(RDFT, ov::op::v9)
|
||||
_OPENVINO_OP_REG(Eye, ov::op::v9)
|
||||
_OPENVINO_OP_REG(ROIAlign, ov::op::v9)
|
||||
@@ -13,6 +13,7 @@ namespace ngraph {
|
||||
namespace runtime {
|
||||
namespace reference {
|
||||
using ROIPoolingMode = op::v3::ROIAlign::PoolingMode;
|
||||
using AlignedMode = op::v9::ROIAlign::AlignedMode;
|
||||
template <typename T>
|
||||
void roi_align(const T* feature_maps,
|
||||
const T* rois,
|
||||
@@ -26,7 +27,8 @@ void roi_align(const T* feature_maps,
|
||||
const int pooled_width,
|
||||
const int sampling_ratio,
|
||||
const float spatial_scale,
|
||||
const ROIPoolingMode& pooling_mode) {
|
||||
const ROIPoolingMode& pooling_mode,
|
||||
const AlignedMode& aligned_mode = AlignedMode::ASYMMETRIC) {
|
||||
auto C = feature_maps_shape[1];
|
||||
auto feature_map_height = feature_maps_shape[2];
|
||||
auto feature_map_width = feature_maps_shape[3];
|
||||
@@ -37,15 +39,44 @@ void roi_align(const T* feature_maps,
|
||||
CoordinateTransform rois_transform(rois_shape);
|
||||
CoordinateTransform out_transform(out_shape);
|
||||
|
||||
bool aligned = false;
|
||||
T offset_src = static_cast<T>(0);
|
||||
T offset_dst = static_cast<T>(0);
|
||||
switch (aligned_mode) {
|
||||
case AlignedMode::HALF_PIXEL_FOR_NN: {
|
||||
aligned = true;
|
||||
offset_dst = static_cast<T>(-0.5);
|
||||
break;
|
||||
}
|
||||
case AlignedMode::HALF_PIXEL: {
|
||||
aligned = true;
|
||||
offset_src = static_cast<T>(0.5);
|
||||
offset_dst = static_cast<T>(-0.5);
|
||||
break;
|
||||
}
|
||||
case AlignedMode::ASYMMETRIC: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw ngraph_error(std::string("Not supported aligned_mode"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int roi_index = 0; roi_index < num_rois; roi_index++) {
|
||||
// Get ROI`s corners
|
||||
T x1 = rois[rois_transform.index({roi_index, 0})] * spatial_scale;
|
||||
T y1 = rois[rois_transform.index({roi_index, 1})] * spatial_scale;
|
||||
T x2 = rois[rois_transform.index({roi_index, 2})] * spatial_scale;
|
||||
T y2 = rois[rois_transform.index({roi_index, 3})] * spatial_scale;
|
||||
T x1 = (rois[rois_transform.index({roi_index, 0})] + offset_src) * spatial_scale + offset_dst;
|
||||
T y1 = (rois[rois_transform.index({roi_index, 1})] + offset_src) * spatial_scale + offset_dst;
|
||||
T x2 = (rois[rois_transform.index({roi_index, 2})] + offset_src) * spatial_scale + offset_dst;
|
||||
T y2 = (rois[rois_transform.index({roi_index, 3})] + offset_src) * spatial_scale + offset_dst;
|
||||
|
||||
T roi_width = std::max(x2 - x1, static_cast<T>(1.0));
|
||||
T roi_height = std::max(y2 - y1, static_cast<T>(1.0));
|
||||
T roi_width = x2 - x1;
|
||||
T roi_height = y2 - y1;
|
||||
|
||||
if (!aligned) {
|
||||
roi_width = std::max(roi_width, static_cast<T>(1.0));
|
||||
roi_height = std::max(roi_height, static_cast<T>(1.0));
|
||||
}
|
||||
|
||||
T bin_width = roi_width / pooled_width;
|
||||
T bin_height = roi_height / pooled_height;
|
||||
|
||||
@@ -11,10 +11,11 @@
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v3 {
|
||||
|
||||
template <class T>
|
||||
void shape_infer(const ov::op::v3::ROIAlign* op, const std::vector<T>& input_shapes, std::vector<T>& output_shapes) {
|
||||
using DimType = typename std::iterator_traits<typename T::iterator>::value_type;
|
||||
template <class OpType, class ShapeType>
|
||||
void infer_roi_align_shape(const OpType* op,
|
||||
const std::vector<ShapeType>& input_shapes,
|
||||
std::vector<ShapeType>& output_shapes) {
|
||||
using DimType = typename std::iterator_traits<typename ShapeType::iterator>::value_type;
|
||||
NODE_VALIDATION_CHECK(op, input_shapes.size() == 3 && output_shapes.size() == 1);
|
||||
|
||||
const auto& input_ps = input_shapes[0];
|
||||
@@ -71,7 +72,23 @@ void shape_infer(const ov::op::v3::ROIAlign* op, const std::vector<T>& input_sha
|
||||
output_shape[0] = Dimension::dynamic();
|
||||
}
|
||||
}
|
||||
template <class T>
|
||||
void shape_infer(const ov::op::v3::ROIAlign* op, const std::vector<T>& input_shapes, std::vector<T>& output_shapes) {
|
||||
NODE_VALIDATION_CHECK(op, input_shapes.size() == 3 && output_shapes.size() == 1);
|
||||
ov::op::v3::infer_roi_align_shape(op, input_shapes, output_shapes);
|
||||
}
|
||||
|
||||
} // namespace v3
|
||||
namespace v9 {
|
||||
|
||||
template <class T>
|
||||
void shape_infer(const ov::op::v9::ROIAlign* op, const std::vector<T>& input_shapes, std::vector<T>& output_shapes) {
|
||||
using DimType = typename std::iterator_traits<typename T::iterator>::value_type;
|
||||
NODE_VALIDATION_CHECK(op, input_shapes.size() == 3 && output_shapes.size() == 1);
|
||||
|
||||
ov::op::v3::infer_roi_align_shape(op, input_shapes, output_shapes);
|
||||
}
|
||||
|
||||
} // namespace v9
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
@@ -119,6 +119,98 @@ shared_ptr<Node> op::v3::ROIAlign::clone_with_new_inputs(const OutputVector& new
|
||||
m_mode);
|
||||
}
|
||||
|
||||
// ------------------------------ V9 ------------------------------
|
||||
|
||||
op::v9::ROIAlign::ROIAlign(const Output<Node>& input,
|
||||
const Output<Node>& rois,
|
||||
const Output<Node>& batch_indices,
|
||||
const int pooled_h,
|
||||
const int pooled_w,
|
||||
const int sampling_ratio,
|
||||
const float spatial_scale,
|
||||
const PoolingMode mode,
|
||||
const AlignedMode aligned_mode)
|
||||
: Op{{input, rois, batch_indices}},
|
||||
m_pooled_h{pooled_h},
|
||||
m_pooled_w{pooled_w},
|
||||
m_sampling_ratio{sampling_ratio},
|
||||
m_spatial_scale{spatial_scale},
|
||||
m_mode{mode},
|
||||
m_aligned_mode{aligned_mode} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
void op::v9::ROIAlign::validate_and_infer_types() {
|
||||
NGRAPH_OP_SCOPE(v9_ROIAlign_validate_and_infer_types);
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(0).is_real() && get_input_element_type(1).is_real(),
|
||||
"The data type for input and ROIs is expected to be a floating point type. Got: ",
|
||||
get_input_element_type(0),
|
||||
" and: ",
|
||||
get_input_element_type(1));
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(0) == get_input_element_type(1),
|
||||
"Type of feature maps (inputs) and rois is expected to be the same. Got: ",
|
||||
get_input_element_type(0),
|
||||
" and: ",
|
||||
get_input_element_type(1));
|
||||
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
get_input_element_type(2).is_integral_number(),
|
||||
"The data type for batch indices is expected to be an integer. Got: ",
|
||||
get_input_element_type(2));
|
||||
|
||||
std::vector<ov::PartialShape> output_shapes = {ov::PartialShape{}};
|
||||
const std::vector<ov::PartialShape> input_shapes = {get_input_partial_shape(0),
|
||||
get_input_partial_shape(1),
|
||||
get_input_partial_shape(2)};
|
||||
|
||||
shape_infer(this, input_shapes, output_shapes);
|
||||
set_output_size(1);
|
||||
set_output_type(0, get_input_element_type(0), output_shapes[0]);
|
||||
|
||||
const auto& input_ps = get_input_partial_shape(0);
|
||||
|
||||
// if the channels dimension is not known
|
||||
// the first input should be used during the function specialization
|
||||
if (input_ps.rank().is_static() && input_ps[1].is_dynamic()) {
|
||||
set_input_is_relevant_to_shape(0);
|
||||
}
|
||||
// if the 'NUM_ROIS' value is not known
|
||||
// the last 2 inputs should be used during the function specialization
|
||||
if ((output_shapes[0])[0].is_dynamic()) {
|
||||
set_input_is_relevant_to_shape(1);
|
||||
set_input_is_relevant_to_shape(2);
|
||||
}
|
||||
}
|
||||
|
||||
bool op::v9::ROIAlign::visit_attributes(AttributeVisitor& visitor) {
|
||||
NGRAPH_OP_SCOPE(v9_ROIAlign_visit_attributes);
|
||||
visitor.on_attribute("pooled_h", m_pooled_h);
|
||||
visitor.on_attribute("pooled_w", m_pooled_w);
|
||||
visitor.on_attribute("sampling_ratio", m_sampling_ratio);
|
||||
visitor.on_attribute("spatial_scale", m_spatial_scale);
|
||||
visitor.on_attribute("mode", m_mode);
|
||||
visitor.on_attribute("aligned_mode", m_aligned_mode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v9::ROIAlign::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
NGRAPH_OP_SCOPE(v9_ROIAlign_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<ROIAlign>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
m_pooled_h,
|
||||
m_pooled_w,
|
||||
m_sampling_ratio,
|
||||
m_spatial_scale,
|
||||
m_mode,
|
||||
m_aligned_mode);
|
||||
}
|
||||
|
||||
namespace ov {
|
||||
BWDCMP_RTTI_DEFINITION(AttributeAdapter<ov::op::v3::ROIAlign::PoolingMode>);
|
||||
|
||||
@@ -130,12 +222,38 @@ NGRAPH_API EnumNames<ngraph::op::v3::ROIAlign::PoolingMode>& EnumNames<ngraph::o
|
||||
return enum_names;
|
||||
}
|
||||
|
||||
template <>
|
||||
NGRAPH_API EnumNames<ngraph::op::v9::ROIAlign::PoolingMode>& EnumNames<ngraph::op::v9::ROIAlign::PoolingMode>::get() {
|
||||
static auto enum_names = EnumNames<ngraph::op::v9::ROIAlign::PoolingMode>(
|
||||
"op::v9::ROIAlign::PoolingMode",
|
||||
{{"avg", ngraph::op::v9::ROIAlign::PoolingMode::AVG}, {"max", ngraph::op::v9::ROIAlign::PoolingMode::MAX}});
|
||||
return enum_names;
|
||||
}
|
||||
|
||||
template <>
|
||||
NGRAPH_API EnumNames<ngraph::op::v9::ROIAlign::AlignedMode>& EnumNames<ngraph::op::v9::ROIAlign::AlignedMode>::get() {
|
||||
static auto enum_names = EnumNames<ngraph::op::v9::ROIAlign::AlignedMode>(
|
||||
"op::v9::ROIAlign::AlignedMode",
|
||||
{{"asymmetric", ngraph::op::v9::ROIAlign::AlignedMode::ASYMMETRIC},
|
||||
{"half_pixel_for_nn", ngraph::op::v9::ROIAlign::AlignedMode::HALF_PIXEL_FOR_NN},
|
||||
{"half_pixel", ngraph::op::v9::ROIAlign::AlignedMode::HALF_PIXEL}});
|
||||
return enum_names;
|
||||
}
|
||||
|
||||
} // namespace ov
|
||||
|
||||
std::ostream& ov::operator<<(std::ostream& s, const op::v3::ROIAlign::PoolingMode& type) {
|
||||
return s << as_string(type);
|
||||
}
|
||||
|
||||
std::ostream& ov::operator<<(std::ostream& s, const op::v9::ROIAlign::PoolingMode& type) {
|
||||
return s << as_string(type);
|
||||
}
|
||||
|
||||
std::ostream& ov::operator<<(std::ostream& s, const op::v9::ROIAlign::AlignedMode& type) {
|
||||
return s << as_string(type);
|
||||
}
|
||||
|
||||
namespace roi_alinop {
|
||||
namespace {
|
||||
template <element::Type_t ET>
|
||||
@@ -148,7 +266,8 @@ bool evaluate(const HostTensorPtr& feature_maps,
|
||||
const int sampling_ratio,
|
||||
const float spatial_scale,
|
||||
const op::v3::ROIAlign::PoolingMode& pooling_mode,
|
||||
const ov::Shape& batch_indices_shape) {
|
||||
const ov::Shape& batch_indices_shape,
|
||||
const op::v9::ROIAlign::AlignedMode& aligned_mode = op::v9::ROIAlign::AlignedMode::ASYMMETRIC) {
|
||||
using T = typename element_type_traits<ET>::value_type;
|
||||
runtime::reference::roi_align<T>(feature_maps->get_data_ptr<ET>(),
|
||||
rois->get_data_ptr<ET>(),
|
||||
@@ -162,7 +281,8 @@ bool evaluate(const HostTensorPtr& feature_maps,
|
||||
pooled_width,
|
||||
sampling_ratio,
|
||||
spatial_scale,
|
||||
pooling_mode);
|
||||
pooling_mode,
|
||||
aligned_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -172,7 +292,8 @@ bool evaluate_roi_align(const HostTensorVector& args,
|
||||
const int pooled_width,
|
||||
const int sampling_ratio,
|
||||
const float spatial_scale,
|
||||
const op::v3::ROIAlign::PoolingMode& pooling_mode) {
|
||||
const op::v3::ROIAlign::PoolingMode& pooling_mode,
|
||||
const op::v9::ROIAlign::AlignedMode& aligned_mode = op::v9::ROIAlign::AlignedMode::ASYMMETRIC) {
|
||||
auto feature_maps = args[0];
|
||||
auto rois = args[1];
|
||||
auto batch_indices = args[2];
|
||||
@@ -191,7 +312,8 @@ bool evaluate_roi_align(const HostTensorVector& args,
|
||||
sampling_ratio,
|
||||
spatial_scale,
|
||||
pooling_mode,
|
||||
batch_indices->get_shape());
|
||||
batch_indices->get_shape(),
|
||||
aligned_mode);
|
||||
NGRAPH_TYPE_CASE(evaluate_roi_align,
|
||||
f16,
|
||||
feature_maps,
|
||||
@@ -203,7 +325,8 @@ bool evaluate_roi_align(const HostTensorVector& args,
|
||||
sampling_ratio,
|
||||
spatial_scale,
|
||||
pooling_mode,
|
||||
batch_indices->get_shape());
|
||||
batch_indices->get_shape(),
|
||||
aligned_mode);
|
||||
NGRAPH_TYPE_CASE(evaluate_roi_align,
|
||||
f32,
|
||||
feature_maps,
|
||||
@@ -215,7 +338,8 @@ bool evaluate_roi_align(const HostTensorVector& args,
|
||||
sampling_ratio,
|
||||
spatial_scale,
|
||||
pooling_mode,
|
||||
batch_indices->get_shape());
|
||||
batch_indices->get_shape(),
|
||||
aligned_mode);
|
||||
default:
|
||||
rc = false;
|
||||
break;
|
||||
|
||||
@@ -58,3 +58,57 @@ TEST(type_prop_layers, roi_align_incompatible_rois_second_dim) {
|
||||
ASSERT_THROW(const auto unused = make_shared<op::v3::ROIAlign>(data, rois, batch_indices, 3, 4, 1, 1.0f, "avg"),
|
||||
ngraph::NodeValidationFailure);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, roi_align_9_basic_shape_inference) {
|
||||
const auto data = make_shared<op::Parameter>(element::f32, Shape{2, 3, 5, 5});
|
||||
const auto rois = make_shared<op::Parameter>(element::f32, Shape{7, 4});
|
||||
const auto batch_indices = make_shared<op::Parameter>(element::i32, Shape{7});
|
||||
const auto pooling_mode = EnumNames<op::v9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
const auto aligned_mode = EnumNames<op::v9::ROIAlign::AlignedMode>::as_enum("half_pixel_for_nn");
|
||||
const auto op = make_shared<op::v9::ROIAlign>(data, rois, batch_indices, 2, 2, 1, 1.0f, pooling_mode, aligned_mode);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{7, 3, 2, 2}));
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, roi_align_9_dynamic_channels_dim) {
|
||||
const auto data = make_shared<op::Parameter>(element::f32, PartialShape{10, Dimension(), 5, 5});
|
||||
const auto rois = make_shared<op::Parameter>(element::f32, Shape{7, 4});
|
||||
const auto batch_indices = make_shared<op::Parameter>(element::i32, Shape{7});
|
||||
const auto pooling_mode = EnumNames<op::v9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
const auto aligned_mode = EnumNames<op::v9::ROIAlign::AlignedMode>::as_enum("half_pixel_for_nn");
|
||||
const auto op = make_shared<op::v9::ROIAlign>(data, rois, batch_indices, 3, 4, 1, 1.0f, pooling_mode, aligned_mode);
|
||||
ASSERT_TRUE(op->get_output_partial_shape(0).same_scheme(PartialShape{7, Dimension(), 3, 4}));
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, roi_align_9_num_rois_from_batch_indices) {
|
||||
const auto data = make_shared<op::Parameter>(element::f32, PartialShape{10, 3, 5, 5});
|
||||
const auto rois = make_shared<op::Parameter>(element::f32, PartialShape{Dimension{}, Dimension{}});
|
||||
const auto batch_indices = make_shared<op::Parameter>(element::i32, Shape{9});
|
||||
const auto pooling_mode = EnumNames<op::v9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
const auto aligned_mode = EnumNames<op::v9::ROIAlign::AlignedMode>::as_enum("asymmetric");
|
||||
const auto op = make_shared<op::v9::ROIAlign>(data, rois, batch_indices, 3, 4, 1, 1.0f, pooling_mode, aligned_mode);
|
||||
ASSERT_EQ(op->get_shape(), (Shape{9, 3, 3, 4}));
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, roi_align_9_incompatible_num_rois) {
|
||||
const auto data = make_shared<op::Parameter>(element::f32, Shape{10, 3, 5, 5});
|
||||
const auto rois = make_shared<op::Parameter>(element::f32, PartialShape{1, Dimension{}});
|
||||
const auto batch_indices = make_shared<op::Parameter>(element::i32, Shape{2});
|
||||
const auto pooling_mode = EnumNames<op::v9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
const auto aligned_mode = EnumNames<op::v9::ROIAlign::AlignedMode>::as_enum("asymmetric");
|
||||
// the first dimension of rois and batch_indices should be equal
|
||||
ASSERT_THROW(
|
||||
const auto unused =
|
||||
make_shared<op::v9::ROIAlign>(data, rois, batch_indices, 3, 4, 1, 1.0f, pooling_mode, aligned_mode),
|
||||
ngraph::NodeValidationFailure);
|
||||
}
|
||||
|
||||
TEST(type_prop_layers, roi_align_9_default_aligned_mode) {
|
||||
const auto data = make_shared<op::Parameter>(element::f32, Shape{10, 3, 5, 5});
|
||||
const auto rois = make_shared<op::Parameter>(element::f32, PartialShape{1, Dimension{}});
|
||||
const auto batch_indices = make_shared<op::Parameter>(element::i32, Shape{2});
|
||||
const auto pooling_mode = EnumNames<op::v9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
// the first dimension of rois and batch_indices should be equal
|
||||
ASSERT_THROW(
|
||||
const auto unused = make_shared<op::v9::ROIAlign>(data, rois, batch_indices, 3, 4, 1, 1.0f, pooling_mode),
|
||||
ngraph::NodeValidationFailure);
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <cpu/x64/cpu_isa_traits.hpp>
|
||||
#include "ie_parallel.hpp"
|
||||
#include <selective_build.h>
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
|
||||
#include <cpu/x64/jit_generator.hpp>
|
||||
#include "emitters/jit_load_store_emitters.hpp"
|
||||
@@ -29,7 +29,8 @@ namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
using ngPoolingMode = ngraph::op::v3::ROIAlign::PoolingMode;
|
||||
using ngPoolingMode = ngraph::opset9::ROIAlign::PoolingMode;
|
||||
using ngAlignedMode = ngraph::opset9::ROIAlign::AlignedMode;
|
||||
|
||||
#define GET_OFF(field) offsetof(jit_roi_align_call_args, field)
|
||||
|
||||
@@ -633,9 +634,9 @@ private:
|
||||
|
||||
bool ROIAlign::isSupportedOperation(const std::shared_ptr<const ngraph::Node>& op, std::string& errorMessage) noexcept {
|
||||
try {
|
||||
auto roiAlign = ngraph::as_type_ptr<const ngraph::opset3::ROIAlign>(op);
|
||||
auto roiAlign = ngraph::as_type_ptr<const ngraph::opset9::ROIAlign>(op);
|
||||
if (!roiAlign) {
|
||||
errorMessage = "Only opset3 ROIAlign operation is supported";
|
||||
errorMessage = "Only opset9 ROIAlign operation is supported";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -644,6 +645,12 @@ bool ROIAlign::isSupportedOperation(const std::shared_ptr<const ngraph::Node>& o
|
||||
errorMessage = "Doesn't support mode: " + ngraph::as_string(mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
const ngAlignedMode alignedMode = roiAlign->get_aligned_mode();
|
||||
if (alignedMode != ngAlignedMode::ASYMMETRIC && alignedMode != ngAlignedMode::HALF_PIXEL_FOR_NN && alignedMode != ngAlignedMode::HALF_PIXEL) {
|
||||
errorMessage = "Doesn't support mode: " + ngraph::as_string(alignedMode);
|
||||
return false;
|
||||
}
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
@@ -656,7 +663,7 @@ ROIAlign::ROIAlign(const std::shared_ptr<ngraph::Node>& op, const dnnl::engine&
|
||||
if (isSupportedOperation(op, errorMessage)) {
|
||||
errorPrefix = "ROIPooling layer with name '" + getName() + "' ";
|
||||
|
||||
auto roiAlign = ngraph::as_type_ptr<const ngraph::opset3::ROIAlign>(op);
|
||||
auto roiAlign = ngraph::as_type_ptr<const ngraph::opset9::ROIAlign>(op);
|
||||
pooledH = roiAlign->get_pooled_h();
|
||||
pooledW = roiAlign->get_pooled_w();
|
||||
spatialScale = roiAlign->get_spatial_scale();
|
||||
@@ -667,6 +674,14 @@ ROIAlign::ROIAlign(const std::shared_ptr<ngraph::Node>& op, const dnnl::engine&
|
||||
} else if (m == ngPoolingMode::AVG) {
|
||||
algorithm = Algorithm::ROIAlignAvg;
|
||||
}
|
||||
const ngAlignedMode mAligned = roiAlign->get_aligned_mode();
|
||||
if (mAligned == ngAlignedMode::ASYMMETRIC) {
|
||||
alignedMode = ROIAlignedMode::ra_asymmetric;
|
||||
} else if (mAligned == ngAlignedMode::HALF_PIXEL_FOR_NN) {
|
||||
alignedMode = ROIAlignedMode::ra_half_pixel_for_nn;
|
||||
} else if (mAligned == ngAlignedMode::HALF_PIXEL) {
|
||||
alignedMode = ROIAlignedMode::ra_half_pixel;
|
||||
}
|
||||
} else {
|
||||
IE_THROW(NotImplemented) << errorMessage;
|
||||
}
|
||||
@@ -885,6 +900,28 @@ void ROIAlign::executeSpecified() {
|
||||
else
|
||||
srcIndexTbl.resize(realRois);
|
||||
|
||||
bool aligned = false;
|
||||
float offset_src = 0;
|
||||
float offset_dst = 0;
|
||||
|
||||
switch (alignedMode) {
|
||||
case ROIAlignedMode::ra_half_pixel_for_nn: {
|
||||
aligned = true;
|
||||
offset_dst = -0.5;
|
||||
break;
|
||||
}
|
||||
case ROIAlignedMode::ra_half_pixel: {
|
||||
aligned = true;
|
||||
offset_src = 0.5;
|
||||
offset_dst = -0.5;
|
||||
break;
|
||||
}
|
||||
case ROIAlignedMode::ra_asymmetric:
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parallel_for(realRois, [&](size_t n) {
|
||||
int roiOff = n * 4;
|
||||
const float* srcRoiPtr = &srcRoi[roiOff];
|
||||
@@ -895,13 +932,17 @@ void ROIAlign::executeSpecified() {
|
||||
IE_THROW() << "Demanded batch (id = " << roiBatchInd << ") doesn't exist";
|
||||
}
|
||||
|
||||
float x1 = srcRoiPtr[0] * spatialScale;
|
||||
float y1 = srcRoiPtr[1] * spatialScale;
|
||||
float x2 = srcRoiPtr[2] * spatialScale;
|
||||
float y2 = srcRoiPtr[3] * spatialScale;
|
||||
float x1 = (srcRoiPtr[0] + offset_src) * spatialScale + offset_dst;
|
||||
float y1 = (srcRoiPtr[1] + offset_src) * spatialScale + offset_dst;
|
||||
float x2 = (srcRoiPtr[2] + offset_src) * spatialScale + offset_dst;
|
||||
float y2 = (srcRoiPtr[3] + offset_src) * spatialScale + offset_dst;
|
||||
|
||||
float roiHeight = std::max(y2 - y1, 1.0f);
|
||||
float roiWidth = std::max(x2 - x1, 1.0f);
|
||||
float roiHeight = y2 - y1;
|
||||
float roiWidth = x2 - x1;
|
||||
if (!aligned) {
|
||||
roiHeight = std::max(roiHeight, 1.0f);
|
||||
roiWidth = std::max(roiWidth, 1.0f);
|
||||
}
|
||||
float binHeight = roiHeight / pooledH;
|
||||
float binWidth = roiWidth / pooledW;
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@ enum ROIAlignLayoutType {
|
||||
nspc
|
||||
};
|
||||
|
||||
enum ROIAlignedMode {
|
||||
ra_asymmetric,
|
||||
ra_half_pixel_for_nn,
|
||||
ra_half_pixel
|
||||
};
|
||||
|
||||
struct jit_roi_align_params {
|
||||
Algorithm alg;
|
||||
InferenceEngine::Precision data_prc;
|
||||
@@ -79,6 +85,7 @@ private:
|
||||
int pooledW = 7;
|
||||
int samplingRatio = 2;
|
||||
float spatialScale = 1.0f;
|
||||
ROIAlignedMode alignedMode;
|
||||
template <typename inputType, typename outputType>
|
||||
void executeSpecified();
|
||||
template<typename T>
|
||||
|
||||
@@ -83,6 +83,8 @@
|
||||
#include <transformations/utils/utils.hpp>
|
||||
#include <snippets/pass/collapse_subgraph.hpp>
|
||||
#include "ngraph_transformations/snippets_mark_skipped.hpp"
|
||||
#include <transformations/op_conversions/convert_roi_align_v9_to_v3.hpp>
|
||||
#include <transformations/op_conversions/convert_roi_align_v3_to_v9.hpp>
|
||||
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include <ngraph/opsets/opset2.hpp>
|
||||
@@ -409,11 +411,13 @@ static void TransformationUpToCPUSpecificOpSet(std::shared_ptr<ngraph::Function>
|
||||
pass_config->disable<ngraph::pass::ConvertReduceSumToPooling>();
|
||||
pass_config->disable<ngraph::pass::SliceToStridedSlice>();
|
||||
pass_config->disable<ngraph::pass::ConvertDetectionOutput8ToDetectionOutput1>();
|
||||
pass_config->disable<ngraph::pass::ConvertROIAlign9To3>();
|
||||
|
||||
pass_config->enable<ngraph::pass::NormalizeL2Decomposition>();
|
||||
pass_config->enable<ngraph::pass::ConvertInterpolate1ToInterpolate4>();
|
||||
pass_config->enable<ngraph::pass::ConvertGather1ToGather7>();
|
||||
pass_config->enable<ngraph::pass::ConvertDetectionOutput1ToDetectionOutput8>();
|
||||
pass_config->enable<ngraph::pass::ConvertROIAlign3To9>();
|
||||
|
||||
if (useLpt) {
|
||||
CPU_LPT_SCOPE(LowPrecisionTransformations_Part3);
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <string>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/op_conversions/convert_roi_align_v3_to_v9.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertROIAlign3To9) {
|
||||
{
|
||||
const int N = 1;
|
||||
const int C = 3;
|
||||
const int H = 5;
|
||||
const int W = 5;
|
||||
const int num_rois = 5;
|
||||
const int pooled_height = 3;
|
||||
const int pooled_width = 4;
|
||||
const auto data_shape = Shape{N, C, H, W};
|
||||
const auto rois_shape = Shape{num_rois, 4};
|
||||
|
||||
const auto data = std::make_shared<opset3::Parameter>(element::f32, data_shape);
|
||||
const auto rois = std::make_shared<opset3::Parameter>(element::f32, rois_shape);
|
||||
const auto batch_indices = std::make_shared<opset3::Parameter>(element::i32, Shape{num_rois});
|
||||
|
||||
auto roi_align = std::make_shared<opset3::ROIAlign>(data,
|
||||
rois,
|
||||
batch_indices,
|
||||
pooled_height,
|
||||
pooled_width,
|
||||
2,
|
||||
1.0f / 16.0f,
|
||||
"avg");
|
||||
|
||||
function = std::make_shared<Function>(NodeVector{roi_align}, ParameterVector{data, rois, batch_indices});
|
||||
manager.register_pass<pass::ConvertROIAlign3To9>();
|
||||
}
|
||||
|
||||
{
|
||||
const int N = 1;
|
||||
const int C = 3;
|
||||
const int H = 5;
|
||||
const int W = 5;
|
||||
const int num_rois = 5;
|
||||
const int pooled_height = 3;
|
||||
const int pooled_width = 4;
|
||||
const auto data_shape = Shape{N, C, H, W};
|
||||
const auto rois_shape = Shape{num_rois, 4};
|
||||
|
||||
const auto data = std::make_shared<opset9::Parameter>(element::f32, data_shape);
|
||||
const auto rois = std::make_shared<opset9::Parameter>(element::f32, rois_shape);
|
||||
const auto batch_indices = std::make_shared<opset9::Parameter>(element::i32, Shape{num_rois});
|
||||
const auto pooling_mode = EnumNames<opset9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
|
||||
auto roi_align = std::make_shared<opset9::ROIAlign>(data,
|
||||
rois,
|
||||
batch_indices,
|
||||
pooled_height,
|
||||
pooled_width,
|
||||
2,
|
||||
1.0f / 16.0f,
|
||||
pooling_mode);
|
||||
|
||||
function_ref = std::make_shared<Function>(NodeVector{roi_align}, ParameterVector{data, rois, batch_indices});
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/opsets/opset3.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
#include <ngraph/pass/manager.hpp>
|
||||
#include <string>
|
||||
#include <transformations/init_node_info.hpp>
|
||||
#include <transformations/op_conversions/convert_roi_align_v9_to_v3.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertROIAlign9To3) {
|
||||
{
|
||||
const int N = 1;
|
||||
const int C = 3;
|
||||
const int H = 5;
|
||||
const int W = 5;
|
||||
const int num_rois = 5;
|
||||
const int pooled_height = 3;
|
||||
const int pooled_width = 4;
|
||||
const auto data_shape = Shape{N, C, H, W};
|
||||
const auto rois_shape = Shape{num_rois, 4};
|
||||
|
||||
const auto data = std::make_shared<opset9::Parameter>(element::f32, data_shape);
|
||||
const auto rois = std::make_shared<opset9::Parameter>(element::f32, rois_shape);
|
||||
const auto batch_indices = std::make_shared<opset9::Parameter>(element::i32, Shape{num_rois});
|
||||
const auto pooling_mode = EnumNames<opset9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
|
||||
auto roi_align = std::make_shared<opset9::ROIAlign>(data,
|
||||
rois,
|
||||
batch_indices,
|
||||
pooled_height,
|
||||
pooled_width,
|
||||
2,
|
||||
1.0f / 16.0f,
|
||||
pooling_mode);
|
||||
|
||||
function = std::make_shared<Function>(NodeVector{roi_align}, ParameterVector{data, rois, batch_indices});
|
||||
manager.register_pass<pass::ConvertROIAlign9To3>();
|
||||
}
|
||||
|
||||
{
|
||||
const int N = 1;
|
||||
const int C = 3;
|
||||
const int H = 5;
|
||||
const int W = 5;
|
||||
const int num_rois = 5;
|
||||
const int pooled_height = 3;
|
||||
const int pooled_width = 4;
|
||||
const auto data_shape = Shape{N, C, H, W};
|
||||
const auto rois_shape = Shape{num_rois, 4};
|
||||
|
||||
const auto data = std::make_shared<opset9::Parameter>(element::f32, data_shape);
|
||||
const auto rois = std::make_shared<opset9::Parameter>(element::f32, rois_shape);
|
||||
const auto batch_indices = std::make_shared<opset9::Parameter>(element::i32, Shape{num_rois});
|
||||
|
||||
auto roi_align = std::make_shared<opset3::ROIAlign>(data,
|
||||
rois,
|
||||
batch_indices,
|
||||
pooled_height,
|
||||
pooled_width,
|
||||
2,
|
||||
1.0f / 16.0f,
|
||||
"avg");
|
||||
|
||||
function_ref = std::make_shared<Function>(NodeVector{roi_align}, ParameterVector{data, rois, batch_indices});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertROIAlign9To3_aligned_mode) {
|
||||
{
|
||||
const int N = 1;
|
||||
const int C = 3;
|
||||
const int H = 5;
|
||||
const int W = 5;
|
||||
const int num_rois = 5;
|
||||
const int pooled_height = 3;
|
||||
const int pooled_width = 4;
|
||||
const auto data_shape = Shape{N, C, H, W};
|
||||
const auto rois_shape = Shape{num_rois, 4};
|
||||
|
||||
const auto data = std::make_shared<opset9::Parameter>(element::f32, data_shape);
|
||||
const auto rois = std::make_shared<opset9::Parameter>(element::f32, rois_shape);
|
||||
const auto batch_indices = std::make_shared<opset9::Parameter>(element::i32, Shape{num_rois});
|
||||
const auto pooling_mode = EnumNames<opset9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
const auto aligned_mode = EnumNames<opset9::ROIAlign::AlignedMode>::as_enum("half_pixel_for_nn");
|
||||
|
||||
auto roi_align = std::make_shared<opset9::ROIAlign>(data,
|
||||
rois,
|
||||
batch_indices,
|
||||
pooled_height,
|
||||
pooled_width,
|
||||
2,
|
||||
1.0f / 16.0f,
|
||||
pooling_mode,
|
||||
aligned_mode);
|
||||
|
||||
function = std::make_shared<Function>(NodeVector{roi_align}, ParameterVector{data, rois, batch_indices});
|
||||
manager.register_pass<pass::ConvertROIAlign9To3>();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ using ROIAlignSpecificParams = std::tuple<
|
||||
float, // scale for given region considering actual input size
|
||||
int, // pooling ratio
|
||||
std::string, // pooling mode
|
||||
std::string, // aligned mode
|
||||
ROIAlignShapes
|
||||
>;
|
||||
|
||||
@@ -52,8 +53,9 @@ public:
|
||||
float spatialScale;
|
||||
int samplingRatio;
|
||||
std::string mode;
|
||||
std::string alignedMode;
|
||||
ROIAlignShapes inputShapes;
|
||||
std::tie(pooledH, pooledW, spatialScale, samplingRatio, mode, inputShapes) = roiPar;
|
||||
std::tie(pooledH, pooledW, spatialScale, samplingRatio, mode, alignedMode, inputShapes) = roiPar;
|
||||
std::ostringstream result;
|
||||
|
||||
result << netPrecision << "_IS=";
|
||||
@@ -74,6 +76,7 @@ public:
|
||||
result << "spatialScale=" << spatialScale << "_";
|
||||
result << "samplingRatio=" << samplingRatio << "_";
|
||||
result << mode << "_";
|
||||
result << alignedMode << "_";
|
||||
result << CPUTestsBase::getTestCaseName(cpuParams);
|
||||
|
||||
return result.str();
|
||||
@@ -138,16 +141,19 @@ protected:
|
||||
float spatialScale;
|
||||
int samplingRatio;
|
||||
std::string mode;
|
||||
std::string alignedMode;
|
||||
ROIAlignShapes inputShapes;
|
||||
std::tie(pooledH, pooledW, spatialScale, samplingRatio, mode, inputShapes) = roiAlignParams;
|
||||
std::tie(pooledH, pooledW, spatialScale, samplingRatio, mode, alignedMode, inputShapes) = roiAlignParams;
|
||||
|
||||
init_input_shapes(inputShapes);
|
||||
|
||||
auto float_params = ngraph::builder::makeDynamicParams(inputPrecision, { inputDynamicShapes[0], inputDynamicShapes[1] });
|
||||
auto int_params = ngraph::builder::makeDynamicParams(ngraph::element::i32, { inputDynamicShapes[2] });
|
||||
auto pooling_mode = ngraph::EnumNames<ngraph::opset9::ROIAlign::PoolingMode>::as_enum(mode);
|
||||
auto aligned_mode = ngraph::EnumNames<ngraph::opset9::ROIAlign::AlignedMode>::as_enum(alignedMode);
|
||||
|
||||
auto roialign = std::make_shared<ngraph::opset3::ROIAlign>(float_params[0], float_params[1], int_params[0], pooledH, pooledW,
|
||||
samplingRatio, spatialScale, mode);
|
||||
auto roialign = std::make_shared<ngraph::opset9::ROIAlign>(float_params[0], float_params[1], int_params[0], pooledH, pooledW,
|
||||
samplingRatio, spatialScale, pooling_mode, aligned_mode);
|
||||
|
||||
selectedType = makeSelectedTypeStr(selectedType, inputPrecision);
|
||||
if (inputPrecision == ElementType::bf16) {
|
||||
@@ -206,6 +212,12 @@ const std::vector<std::string> modeVector = {
|
||||
"max"
|
||||
};
|
||||
|
||||
const std::vector<std::string> alignedModeVector = {
|
||||
"asymmetric",
|
||||
"half_pixel_for_nn",
|
||||
"half_pixel"
|
||||
};
|
||||
|
||||
const std::vector<ROIAlignShapes> inputShapeVector = {
|
||||
ROIAlignShapes{{{}, {{ 2, 22, 20, 20 }}}, {{}, {{2, 4}}}, {{}, {{2}}}},
|
||||
ROIAlignShapes{{{}, {{ 2, 18, 20, 20 }}}, {{}, {{2, 4}}}, {{}, {{2}}}},
|
||||
@@ -239,6 +251,7 @@ const auto roiAlignParams = ::testing::Combine(
|
||||
::testing::ValuesIn(spatialScaleVector), // scale for given region considering actual input size
|
||||
::testing::ValuesIn(poolingRatioVector), // pooling ratio for bin
|
||||
::testing::ValuesIn(modeVector), // pooling mode
|
||||
::testing::ValuesIn(alignedModeVector), // aligned mode
|
||||
::testing::ValuesIn(inputShapeVector) // feature map shape
|
||||
);
|
||||
|
||||
|
||||
+13
@@ -837,6 +837,18 @@ std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v3::ROIAlign>
|
||||
return std::make_shared<ov::Model>(results, params, "ROIAlignGraph");
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v9::ROIAlign>& node) {
|
||||
const auto params = ngraph::builder::makeDynamicParams(ov::element::f16, {{2, 1, 16, 16}});
|
||||
const auto coords = ngraph::builder::makeConstant<float16>(ov::element::f16, {2, 4}, {2, 2, 8, 8, 2, 2, 8, 8});
|
||||
const auto roisIdx = ngraph::builder::makeConstant<int32_t>(ov::element::i32, {2}, {0, 1});
|
||||
const auto pooling_mode = EnumNames<op::v9::ROIAlign::PoolingMode>::as_enum("avg");
|
||||
const auto aligned_mode = EnumNames<op::v9::ROIAlign::AlignedMode>::as_enum("half_pixel_for_nn");
|
||||
auto Node =
|
||||
std::make_shared<ov::op::v9::ROIAlign>(params.at(0), coords, roisIdx, 2, 2, 2, 1, pooling_mode, aligned_mode);
|
||||
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(Node)};
|
||||
return std::make_shared<ov::Model>(results, params, "ROIAlignGraph");
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v0::ROIPooling> &node) {
|
||||
const auto params = ngraph::builder::makeDynamicParams(ov::element::f16, {{1, 3, 8, 8},
|
||||
{1, 5}});
|
||||
@@ -1769,6 +1781,7 @@ OpGenerator getOpGeneratorMap() {
|
||||
#include "openvino/opsets/opset6_tbl.hpp"
|
||||
#include "openvino/opsets/opset7_tbl.hpp"
|
||||
#include "openvino/opsets/opset8_tbl.hpp"
|
||||
#include "openvino/opsets/opset9_tbl.hpp"
|
||||
#undef _OPENVINO_OP_REG
|
||||
};
|
||||
return opGeneratorMap;
|
||||
|
||||
@@ -76,6 +76,7 @@ CompareMap getCompareMap() {
|
||||
#include "ngraph/opsets/opset6_tbl.hpp"
|
||||
#include "ngraph/opsets/opset7_tbl.hpp"
|
||||
#include "ngraph/opsets/opset8_tbl.hpp"
|
||||
#include "ngraph/opsets/opset9_tbl.hpp"
|
||||
|
||||
#undef NGRAPH_OP
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@ Summary::Summary() {
|
||||
opsets.push_back(ngraph::get_opset6());
|
||||
opsets.push_back(ngraph::get_opset7());
|
||||
opsets.push_back(ngraph::get_opset8());
|
||||
opsets.push_back(ngraph::get_opset9());
|
||||
}
|
||||
|
||||
Summary &Summary::getInstance() {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <ngraph/opsets/opset6.hpp>
|
||||
#include <ngraph/opsets/opset7.hpp>
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
|
||||
#include "ngraph_functions/utils/data_utils.hpp"
|
||||
#include "openvino/core/partial_shape.hpp"
|
||||
|
||||
Reference in new issue
Block a user