Meiyang/paddle generate proposals 2 (#11285)
* create new op v9::GenerateProposalsSingleImage and support paddle generate proposal v2 * support scale in GenerateProposals * Add output roi_num in GenerateProposal; change anchor's shape to [H, W, A, 4] * fix paddle generate proposals frontend issue * rename MKLDNNGenerateProposalsSingleImage to GenerateProposalsSingleImage * add GenerateProposals attribute 'roi_num_type' * fuse type togenerate_proposals * multibatch support * fix review comments; paddle tests added * use pad instead of concat * fix generate proposals visitor test parameter * add testcase for generate proposal scale and fix generate proposals reference issue * rename to GenerateProposals * add generate proposals ngraph reshape test; opset9 support and test; * fix compiling issue * add dependency 'paddledet' on paddle frontend test * Update src/core/include/ngraph/op/generate_proposals.hpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/include/openvino/op/generate_proposals.hpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/reference/include/ngraph/runtime/reference/generate_proposal.hpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/src/op/generate_proposals.cpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/include/ngraph/op/generate_proposals.hpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/src/op/generate_proposals.cpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/src/op/generate_proposals.cpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/src/op/generate_proposals.cpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/include/openvino/op/generate_proposals.hpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Update src/core/include/openvino/op/generate_proposals.hpp Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * fix compiling issue after newly added commit * clang fix * fix compiling issue * add paddledet dependency * fix compiling issue * fix compiling issue * clang fix * skip ppdet.modeling.ops in paddle generate proposals test * single layer update after rebase master * set pycocotools to 2.0.4 * skip ppdet.modeling.ops.__init__ * add paddle test dependency * fix template issue * rename mkldnn to dnnl * fix template issue * fix windows compiling issue * update testcase vector construction * add shape check and test; add some annotation; apply review suggestion * Revert "add paddle test dependency" This reverts commit 959a2d770d3f6cb28d4609981c79cc49a25847fd. * rm dependency of paddledet for paddle frontend test * update opset9 number * fix windows issue Co-authored-by: Luo Cheng <cheng.luo@intel.com> Co-authored-by: Ilya Churaev <ilyachur@gmail.com>
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include <ngraph/runtime/reference/gather_nd.hpp>
|
||||
#include <ngraph/runtime/reference/gather_tree.hpp>
|
||||
#include <ngraph/runtime/reference/gelu.hpp>
|
||||
#include <ngraph/runtime/reference/generate_proposal.hpp>
|
||||
#include <ngraph/runtime/reference/greater.hpp>
|
||||
#include <ngraph/runtime/reference/grn.hpp>
|
||||
#include <ngraph/runtime/reference/group_convolution.hpp>
|
||||
@@ -3296,6 +3297,79 @@ bool evaluate(const shared_ptr<op::v6::ExperimentalDetectronTopKROIs>& op,
|
||||
return true;
|
||||
}
|
||||
|
||||
template <element::Type_t ET>
|
||||
bool evaluate(const shared_ptr<op::v9::GenerateProposals>& op,
|
||||
const HostTensorVector& outputs,
|
||||
const HostTensorVector& inputs) {
|
||||
const auto attrs = op->get_attrs();
|
||||
|
||||
size_t post_nms_count = 0;
|
||||
if (attrs.post_nms_count < 0) {
|
||||
throw ngraph_error("The attribute post_nms_count of the operation "
|
||||
"GenerateProposals must be a "
|
||||
"nonnegative integer.");
|
||||
} else {
|
||||
post_nms_count = static_cast<size_t>(attrs.post_nms_count);
|
||||
}
|
||||
|
||||
const auto output_type = op->get_input_element_type(0);
|
||||
|
||||
const auto im_info_shape = inputs[0]->get_shape();
|
||||
const auto anchors_shape = inputs[1]->get_shape();
|
||||
const auto deltas_shape = inputs[2]->get_shape();
|
||||
const auto scores_shape = inputs[3]->get_shape();
|
||||
|
||||
const auto im_info_data = get_floats(inputs[0], im_info_shape);
|
||||
const auto anchors_data = get_floats(inputs[1], anchors_shape);
|
||||
const auto deltas_data = get_floats(inputs[2], deltas_shape);
|
||||
const auto scores_data = get_floats(inputs[3], scores_shape);
|
||||
|
||||
std::vector<float> output_rois;
|
||||
std::vector<float> output_scores;
|
||||
std::vector<int64_t> output_num;
|
||||
|
||||
runtime::reference::generate_proposals(im_info_data,
|
||||
anchors_data,
|
||||
deltas_data,
|
||||
scores_data,
|
||||
attrs,
|
||||
im_info_shape,
|
||||
anchors_shape,
|
||||
deltas_shape,
|
||||
scores_shape,
|
||||
output_rois,
|
||||
output_scores,
|
||||
output_num);
|
||||
|
||||
uint64_t num_selected = static_cast<uint64_t>(std::accumulate(output_num.begin(), output_num.end(), 0));
|
||||
|
||||
Shape output_rois_shape = Shape{num_selected, 4};
|
||||
Shape output_scores_shape = Shape{num_selected};
|
||||
|
||||
outputs[0]->set_element_type(output_type);
|
||||
outputs[0]->set_shape(output_rois_shape);
|
||||
outputs[1]->set_element_type(output_type);
|
||||
outputs[1]->set_shape(output_scores_shape);
|
||||
|
||||
const auto roi_num_type = op->get_output_element_type(2);
|
||||
Shape output_roi_num_shape = Shape{im_info_shape[0]};
|
||||
outputs[2]->set_element_type(roi_num_type);
|
||||
outputs[2]->set_shape(output_roi_num_shape);
|
||||
|
||||
runtime::reference::generate_proposals_postprocessing(outputs[0]->get_data_ptr(),
|
||||
outputs[1]->get_data_ptr(),
|
||||
outputs[2]->get_data_ptr(),
|
||||
output_type,
|
||||
roi_num_type,
|
||||
output_rois,
|
||||
output_scores,
|
||||
output_num,
|
||||
output_rois_shape,
|
||||
output_scores_shape);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <element::Type_t ET>
|
||||
bool evaluate(const shared_ptr<op::v6::ExperimentalDetectronGenerateProposalsSingleImage>& op,
|
||||
const HostTensorVector& outputs,
|
||||
|
||||
@@ -98,6 +98,7 @@ NGRAPH_OP(Assign, ngraph::op::v6)
|
||||
NGRAPH_OP(CTCGreedyDecoderSeqLen, op::v6)
|
||||
NGRAPH_OP(ExperimentalDetectronDetectionOutput, op::v6)
|
||||
NGRAPH_OP(ExperimentalDetectronGenerateProposalsSingleImage, op::v6)
|
||||
NGRAPH_OP(GenerateProposals, op::v9)
|
||||
NGRAPH_OP(ExperimentalDetectronPriorGridGenerator, op::v6)
|
||||
NGRAPH_OP(ExperimentalDetectronROIFeatureExtractor, op::v6)
|
||||
NGRAPH_OP(ExperimentalDetectronTopKROIs, op::v6)
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "openvino/op/generate_proposals.hpp"
|
||||
#include "base_reference_test.hpp"
|
||||
|
||||
using namespace reference_tests;
|
||||
using namespace ov;
|
||||
|
||||
using Attrs = op::v9::GenerateProposals::Attributes;
|
||||
|
||||
namespace {
|
||||
struct GPParams {
|
||||
template <class IT, class RT>
|
||||
GPParams(const Attrs& attrs,
|
||||
const size_t batch, const size_t number_of_channels, const size_t height, const size_t width,
|
||||
const element::Type& iType, const element::Type& roiNumType,
|
||||
const std::vector<IT>& imageSizeInfoValues, const std::vector<IT>& anchorsValues,
|
||||
const std::vector<IT>& deltasValues, const std::vector<IT>& scoresValues,
|
||||
const std::vector<IT>& refRoisValues, const std::vector<IT>& refScoresValues,
|
||||
const std::vector<RT>& refRoiNumValues,
|
||||
const std::string& testcaseName = "")
|
||||
: attrs(attrs),
|
||||
inType(iType),
|
||||
outType(iType),
|
||||
roiNumType(roiNumType),
|
||||
imageSizeInfoData(CreateTensor(iType, imageSizeInfoValues)),
|
||||
anchorsData(CreateTensor(iType, anchorsValues)),
|
||||
deltasData(CreateTensor(iType, deltasValues)),
|
||||
scoresData(CreateTensor(iType, scoresValues)),
|
||||
refRoisData(CreateTensor(iType, refRoisValues)),
|
||||
refScoresData(CreateTensor(iType, refScoresValues)),
|
||||
refRoiNumData(CreateTensor(roiNumType, refRoiNumValues)),
|
||||
testcaseName(testcaseName) {
|
||||
imageSizeInfoShape = Shape{batch, 3};
|
||||
anchorsShape = Shape{height, width, number_of_channels, 4};
|
||||
deltasShape = Shape{batch, number_of_channels * 4, height, width};
|
||||
scoresShape = Shape{batch, number_of_channels, height, width};
|
||||
}
|
||||
|
||||
Attrs attrs;
|
||||
PartialShape imageSizeInfoShape;
|
||||
PartialShape anchorsShape;
|
||||
PartialShape deltasShape;
|
||||
PartialShape scoresShape;
|
||||
ov::element::Type inType;
|
||||
ov::element::Type outType;
|
||||
ov::element::Type roiNumType;
|
||||
ov::Tensor imageSizeInfoData;
|
||||
ov::Tensor anchorsData;
|
||||
ov::Tensor deltasData;
|
||||
ov::Tensor scoresData;
|
||||
ov::Tensor refRoisData;
|
||||
ov::Tensor refScoresData;
|
||||
ov::Tensor refRoiNumData;
|
||||
std::string testcaseName;
|
||||
};
|
||||
|
||||
class ReferenceGPLayerTest : public testing::TestWithParam<GPParams>, public CommonReferenceTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto params = GetParam();
|
||||
function = CreateFunction(params);
|
||||
inputData = {params.imageSizeInfoData, params.anchorsData, params.deltasData, params.scoresData};
|
||||
refOutData = {params.refRoisData, params.refScoresData, params.refRoiNumData};
|
||||
}
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<GPParams>& obj) {
|
||||
auto param = obj.param;
|
||||
std::ostringstream result;
|
||||
result << "imageSizeInfoShape=" << param.imageSizeInfoShape << "_";
|
||||
result << "anchorsShape=" << param.anchorsShape << "_";
|
||||
result << "deltasShape=" << param.deltasShape << "_";
|
||||
result << "scoresShape=" << param.scoresShape << "_";
|
||||
result << "iType=" << param.inType << "_";
|
||||
result << "oType=" << param.outType << "_";
|
||||
result << "roiNumType=" << param.roiNumType;
|
||||
if (param.testcaseName != "")
|
||||
result << "_" << param.testcaseName;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::shared_ptr<Model> CreateFunction(const GPParams& params) {
|
||||
const auto im_info = std::make_shared<op::v0::Parameter>(params.inType, params.imageSizeInfoShape);
|
||||
const auto anchors = std::make_shared<op::v0::Parameter>(params.inType, params.anchorsShape);
|
||||
const auto deltas = std::make_shared<op::v0::Parameter>(params.inType, params.deltasShape);
|
||||
const auto scores = std::make_shared<op::v0::Parameter>(params.inType, params.scoresShape);
|
||||
const auto GenerateProposal = std::make_shared<op::v9::GenerateProposals>(im_info,
|
||||
anchors,
|
||||
deltas,
|
||||
scores,
|
||||
params.attrs);
|
||||
GenerateProposal->set_roi_num_type(params.roiNumType);
|
||||
return std::make_shared<ov::Model>(GenerateProposal->outputs(), ParameterVector {im_info, anchors, deltas, scores});
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ReferenceGPLayerTest, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
template <element::Type_t IN_ET, element::Type_t OUT_RT>
|
||||
std::vector<GPParams> generateGPFloatParams() {
|
||||
using T = typename element_type_traits<IN_ET>::value_type;
|
||||
using RT = typename element_type_traits<OUT_RT>::value_type;
|
||||
|
||||
Attrs attrs;
|
||||
attrs.min_size = 1.0;
|
||||
attrs.nms_threshold = 0.699999988079071;
|
||||
attrs.pre_nms_count = 1000;
|
||||
attrs.post_nms_count = 6;
|
||||
attrs.nms_eta = 1.0;
|
||||
attrs.normalized = true;
|
||||
|
||||
std::vector<GPParams> generateProposalParams {
|
||||
GPParams(attrs,
|
||||
1,
|
||||
3, // A
|
||||
2, // H
|
||||
6, // W
|
||||
IN_ET,
|
||||
OUT_RT,
|
||||
std::vector<T>{1.0f, 1.0f, 0.0f},
|
||||
std::vector<T>(144, 1.0f), // anchors [H, W, A, 4]
|
||||
std::vector<T>(144, 1.0f), // deltas [N, A * 4, H, W]
|
||||
std::vector<T>{5.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 4.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 8.0f, 1.0f}, // scores [N, A, H, W]
|
||||
std::vector<T>(24, 1.0f), // ref rois
|
||||
std::vector<T>{8.0f, 5.0f, 4.0f, 1.0f, 1.0f, 1.0f}, // ref scores
|
||||
std::vector<RT>{6}, // ref roiNum
|
||||
"eval"),
|
||||
GPParams(attrs,
|
||||
2,
|
||||
3,
|
||||
2,
|
||||
6,
|
||||
IN_ET,
|
||||
OUT_RT,
|
||||
std::vector<T>{150.0, 150.0, 0.0, 150.0, 150.0, 0.0},
|
||||
std::vector<T>{12.0, 68.0, 102.0, 123.0, 46.0, 80.0, 79.0, 128.0, 33.0, 71.0, 127.0, 86.0, 33.0, 56.0, 150.0, 73.0,
|
||||
5.0, 41.0, 93.0, 150.0, 74.0, 66.0, 106.0, 115.0, 17.0, 37.0, 87.0, 150.0, 31.0, 27.0, 150.0, 39.0,
|
||||
29.0, 23.0, 112.0, 123.0, 41.0, 37.0, 103.0, 150.0, 8.0, 46.0, 98.0, 111.0, 7.0, 69.0, 114.0, 150.0,
|
||||
70.0, 21.0, 150.0, 125.0, 54.0, 19.0, 132.0, 68.0, 62.0, 8.0, 150.0, 101.0, 57.0, 81.0, 150.0, 97.0,
|
||||
79.0, 29.0, 109.0, 130.0, 12.0, 63.0, 100.0, 150.0, 17.0, 33.0, 113.0, 150.0, 90.0, 78.0, 150.0, 111.0,
|
||||
47.0, 68.0, 150.0, 71.0, 66.0, 103.0, 111.0, 150.0, 4.0, 17.0, 112.0, 94.0, 12.0, 8.0, 119.0, 98.0,
|
||||
54.0, 56.0, 120.0, 150.0, 56.0, 29.0, 150.0, 31.0, 42.0, 3.0, 139.0, 92.0, 41.0, 65.0, 150.0, 130.0,
|
||||
49.0, 13.0, 143.0, 30.0, 40.0, 60.0, 150.0, 150.0, 23.0, 73.0, 24.0, 115.0, 56.0, 84.0, 107.0, 108.0,
|
||||
63.0, 8.0, 142.0, 125.0, 78.0, 37.0, 93.0, 144.0, 40.0, 34.0, 150.0, 46.0, 30.0, 21.0, 150.0, 120.0},
|
||||
std::vector<T>{9.062256, 10.883133, 9.8441105, 12.694285, 0.41781136, 8.749107, 14.990341, 6.587644, 1.4206103,
|
||||
13.299262, 12.432549, 2.736371, 0.22732796, 6.3361835, 12.268727, 2.1009045, 4.771589, 2.5131326,
|
||||
5.610736, 9.3604145, 4.27379, 8.317948, 0.60510135, 6.7446275, 1.0207708, 1.1352817, 1.5785321,
|
||||
1.718335, 1.8093798, 0.99247587, 1.3233583, 1.7432803, 1.8534478, 1.2593061, 1.7394226, 1.7686696,
|
||||
1.647999, 1.7611449, 1.3119122, 0.03007332, 1.1106564, 0.55669737, 0.2546148, 1.9181818, 0.7134989,
|
||||
2.0407224, 1.7211134, 1.8565536, 14.562747, 2.8786168, 0.5927796, 0.2064463, 7.6794515, 8.672126,
|
||||
10.139171, 8.002429, 7.002932, 12.6314945, 10.550842, 0.15784842, 0.3194304, 10.752157, 3.709805,
|
||||
11.628928, 0.7136225, 14.619964, 15.177284, 2.2824087, 15.381494, 0.16618137, 7.507227, 11.173228,
|
||||
0.4923559, 1.8227729, 1.4749299, 1.7833921, 1.2363617, -0.23659119, 1.5737582, 1.779316, 1.9828427,
|
||||
1.0482665, 1.4900246, 1.3563544, 1.5341306, 0.7634312, 4.6216766e-05, 1.6161222, 1.7512476, 1.9363779,
|
||||
0.9195784, 1.4906164, -0.03244795, 0.681073, 0.6192401, 1.8033613, 14.146055, 3.4043705, 15.292292,
|
||||
3.5295358, 11.138999, 9.952057, 5.633434, 12.114562, 9.427372, 12.384038, 9.583308, 8.427233,
|
||||
15.293704, 3.288159, 11.64898, 9.350885, 2.0037227, 13.523184, 4.4176426, 6.1057625, 14.400079,
|
||||
8.248259, 11.815807, 15.713364, 1.0023532, 1.3203261, 1.7100681, 0.7407832, 1.09448, 1.7188418,
|
||||
1.4412547, 1.4862992, 0.74790007, 0.31571656, 0.6398838, 2.0236106, 1.1869069, 1.7265586, 1.2624544,
|
||||
0.09934269, 1.3508598, 0.85212964, -0.38968498, 1.7059708, 1.6533034, 1.7400402, 1.8123854, -0.43063712,
|
||||
9.062256, 10.883133, 9.8441105, 12.694285, 0.41781136, 8.749107, 14.990341, 6.587644, 1.4206103,
|
||||
13.299262, 12.432549, 2.736371, 0.22732796, 6.3361835, 12.268727, 2.1009045, 4.771589, 2.5131326,
|
||||
5.610736, 9.3604145, 4.27379, 8.317948, 0.60510135, 6.7446275, 1.0207708, 1.1352817, 1.5785321,
|
||||
1.718335, 1.8093798, 0.99247587, 1.3233583, 1.7432803, 1.8534478, 1.2593061, 1.7394226, 1.7686696,
|
||||
1.647999, 1.7611449, 1.3119122, 0.03007332, 1.1106564, 0.55669737, 0.2546148, 1.9181818, 0.7134989,
|
||||
2.0407224, 1.7211134, 1.8565536, 14.562747, 2.8786168, 0.5927796, 0.2064463, 7.6794515, 8.672126,
|
||||
10.139171, 8.002429, 7.002932, 12.6314945, 10.550842, 0.15784842, 0.3194304, 10.752157, 3.709805,
|
||||
11.628928, 0.7136225, 14.619964, 15.177284, 2.2824087, 15.381494, 0.16618137, 7.507227, 11.173228,
|
||||
0.4923559, 1.8227729, 1.4749299, 1.7833921, 1.2363617, -0.23659119, 1.5737582, 1.779316, 1.9828427,
|
||||
1.0482665, 1.4900246, 1.3563544, 1.5341306, 0.7634312, 4.6216766e-05, 1.6161222, 1.7512476, 1.9363779,
|
||||
0.9195784, 1.4906164, -0.03244795, 0.681073, 0.6192401, 1.8033613, 14.146055, 3.4043705, 15.292292,
|
||||
3.5295358, 11.138999, 9.952057, 5.633434, 12.114562, 9.427372, 12.384038, 9.583308, 8.427233,
|
||||
15.293704, 3.288159, 11.64898, 9.350885, 2.0037227, 13.523184, 4.4176426, 6.1057625, 14.400079,
|
||||
8.248259, 11.815807, 15.713364, 1.0023532, 1.3203261, 1.7100681, 0.7407832, 1.09448, 1.7188418,
|
||||
1.4412547, 1.4862992, 0.74790007, 0.31571656, 0.6398838, 2.0236106, 1.1869069, 1.7265586, 1.2624544,
|
||||
0.09934269, 1.3508598, 0.85212964, -0.38968498, 1.7059708, 1.6533034, 1.7400402, 1.8123854, -0.43063712},
|
||||
std::vector<T>{0.7719922, 0.35906568, 0.29054508, 0.18124384, 0.5604661, 0.84750974, 0.98948747, 0.009793862, 0.7184191,
|
||||
0.5560748, 0.6952493, 0.6732593, 0.3306898, 0.6790913, 0.41128764, 0.34593266, 0.94296855, 0.7348507,
|
||||
0.24478768, 0.94024557, 0.05405676, 0.06466125, 0.36244348, 0.07942984, 0.10619422, 0.09412837, 0.9053611,
|
||||
0.22870538, 0.9237487, 0.20986171, 0.5067282, 0.29709867, 0.53138554, 0.189101, 0.4786443, 0.88421875,
|
||||
0.7719922, 0.35906568, 0.29054508, 0.18124384, 0.5604661, 0.84750974, 0.98948747, 0.009793862, 0.7184191,
|
||||
0.5560748, 0.6952493, 0.6732593, 0.3306898, 0.6790913, 0.41128764, 0.34593266, 0.94296855, 0.7348507,
|
||||
0.24478768, 0.94024557, 0.05405676, 0.06466125, 0.36244348, 0.07942984, 0.10619422, 0.09412837, 0.9053611,
|
||||
0.22870538, 0.9237487, 0.20986171, 0.5067282, 0.29709867, 0.53138554, 0.189101, 0.4786443, 0.88421875},
|
||||
std::vector<T>{149, 149, 149, 149, 149, 0, 149, 149, 149, 60.87443542480469, 149, 149, 149, 61.89498901367188, 149,
|
||||
149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 0, 149, 149, 149, 60.87443542480469,
|
||||
149, 149, 149, 61.89498901367188, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149},
|
||||
std::vector<T>{0.9894874691963196, 0.9429685473442078,
|
||||
0.9402455687522888, 0.9237486720085144,
|
||||
0.9053611159324646, 0.8842187523841858,
|
||||
0.9894874691963196, 0.9429685473442078,
|
||||
0.9402455687522888, 0.9237486720085144,
|
||||
0.9053611159324646, 0.8842187523841858},
|
||||
std::vector<RT>{6, 6},
|
||||
"batch_2"),
|
||||
GPParams(attrs,
|
||||
1,
|
||||
3, // A
|
||||
2, // H
|
||||
6, // W
|
||||
IN_ET,
|
||||
OUT_RT,
|
||||
std::vector<T>{200.0f, 200.0f, 4.0f},
|
||||
std::vector<T>{0.0f, 1.0f, 2.0f, 3.0f,
|
||||
4.0f, 5.0f, 6.0f, 7.0f,
|
||||
8.0f, 9.0f, 10.0f, 11.0f,
|
||||
12.0f, 13.0f, 14.0f, 15.0f,
|
||||
16.0f, 17.0f, 18.0f, 19.0f,
|
||||
20.0f, 21.0f, 22.0f, 23.0f,
|
||||
24.0f, 25.0f, 26.0f, 27.0f,
|
||||
28.0f, 29.0f, 30.0f, 31.0f,
|
||||
32.0f, 33.0f, 34.0f, 35.0f,
|
||||
36.0f, 37.0f, 38.0f, 39.0f,
|
||||
40.0f, 41.0f, 42.0f, 43.0f,
|
||||
44.0f, 45.0f, 46.0f, 47.0f,
|
||||
48.0f, 49.0f, 50.0f, 51.0f,
|
||||
52.0f, 53.0f, 54.0f, 55.0f,
|
||||
56.0f, 57.0f, 58.0f, 59.0f,
|
||||
60.0f, 61.0f, 62.0f, 63.0f,
|
||||
64.0f, 65.0f, 66.0f, 67.0f,
|
||||
68.0f, 69.0f, 70.0f, 71.0f,
|
||||
72.0f, 73.0f, 74.0f, 75.0f,
|
||||
76.0f, 77.0f, 78.0f, 79.0f,
|
||||
80.0f, 81.0f, 82.0f, 83.0f,
|
||||
84.0f, 85.0f, 86.0f, 87.0f,
|
||||
88.0f, 89.0f, 90.0f, 91.0f,
|
||||
92.0f, 93.0f, 94.0f, 95.0f,
|
||||
96.0f, 97.0f, 98.0f, 99.0f,
|
||||
100.0f, 101.0f, 102.0f, 103.0f,
|
||||
104.0f, 105.0f, 106.0f, 107.0f,
|
||||
108.0f, 109.0f, 110.0f, 111.0f,
|
||||
112.0f, 113.0f, 114.0f, 115.0f,
|
||||
116.0f, 117.0f, 118.0f, 119.0f,
|
||||
120.0f, 121.0f, 122.0f, 123.0f,
|
||||
124.0f, 125.0f, 126.0f, 127.0f,
|
||||
128.0f, 129.0f, 130.0f, 131.0f,
|
||||
132.0f, 133.0f, 134.0f, 135.0f,
|
||||
136.0f, 137.0f, 138.0f, 139.0f,
|
||||
140.0f, 141.0f, 142.0f, 143.0f}, // anchors H, W, A, 4
|
||||
std::vector<T>{0.5337073 ,0.86607957,0.55151343,0.21626699,0.4462629, 0.03985678,
|
||||
0.5157072 ,0.9932138 ,0.7565954 ,0.43803605,0.802818 ,0.14834064,
|
||||
0.53932905,0.14314 ,0.3817048 ,0.95075196,0.05516243,0.2567484,
|
||||
0.25508744,0.77438325,0.43561 ,0.2094628 ,0.8299043 ,0.44982538,
|
||||
0.95615596,0.5651084 ,0.11801951,0.05352486,0.9774733 ,0.14439464,
|
||||
0.62644225,0.14370479,0.54161614,0.557915 ,0.53102225,0.0840179,
|
||||
0.7249888 ,0.9843559 ,0.5490522 ,0.53788143,0.822474 ,0.3278008,
|
||||
0.39688024,0.3286012 ,0.5117038 ,0.04743988,0.9408995 ,0.29885054,
|
||||
0.81039643,0.85277915,0.06807619,0.86430097,0.36225632,0.16606331,
|
||||
0.5401001 ,0.7541649 ,0.11998601,0.5131829 ,0.40606487,0.327888 ,
|
||||
0.27721855,0.6378373 ,0.22795396,0.4961256 ,0.3215895 ,0.15607187,
|
||||
0.14782153,0.8908137 ,0.8835288 ,0.834191 ,0.29907143,0.7983525 ,
|
||||
0.755875 ,0.30837986,0.0839176 ,0.26624718,0.04371626,0.09472824,
|
||||
0.20689541,0.37622106,0.1083321 ,0.1342548 ,0.05815459,0.7676379 ,
|
||||
0.8105144 ,0.92348766,0.26761323,0.7183306 ,0.8947588 ,0.19020908,
|
||||
0.42731014,0.7473663 ,0.85775334,0.9340091 ,0.3278848 ,0.755993 ,
|
||||
0.05307213,0.39705503,0.21003333,0.5625373 ,0.66188884,0.80521655,
|
||||
0.6125863 ,0.44678232,0.97802377,0.0204936 ,0.02686367,0.7390654 ,
|
||||
0.74631 ,0.58399844,0.5988792 ,0.37413648,0.5946692 ,0.6955776 ,
|
||||
0.36377597,0.7891322 ,0.40900692,0.99139464,0.50169915,0.41435778,
|
||||
0.17142445,0.26761186,0.31591868,0.14249913,0.12919712,0.5418711 ,
|
||||
0.6523203 ,0.50259084,0.7379765 ,0.01171071,0.94423133,0.00841132,
|
||||
0.97486794,0.2921785 ,0.7633071 ,0.88477814,0.03563205,0.50833166,
|
||||
0.01354555,0.535081 ,0.41366324,0.0694767 ,0.9944055 ,0.9981207}, // deltas N, A * 4, H, W
|
||||
std::vector<T>{0.56637216,0.90457034,0.69827306,0.4353543, 0.47985056,0.42658508,
|
||||
0.14516132,0.08081771,0.1799732 ,0.9229515 ,0.42420176,0.50857586,
|
||||
0.82664067,0.4972319 ,0.3752427 ,0.56731623,0.18241242,0.33252355,
|
||||
0.30608943,0.6572437 ,0.69185436,0.88646156,0.36985755,0.5590753 ,
|
||||
0.5256446 ,0.03342898,0.1344396 ,0.68642473,0.37953874,0.32575172,
|
||||
0.21108444,0.5661886 ,0.45378175,0.62126315,0.26799858,0.37272978}, // scores N, A, H, W
|
||||
std::vector<T>{4.49132, 4.30537, 8.75027, 8.8035,
|
||||
0, 1.01395, 4.66909, 5.14337,
|
||||
135.501, 137.467, 139.81, 141.726,
|
||||
47.2348, 47.8342, 52.5503, 52.3864,
|
||||
126.483, 128.3, 131.625, 133.707}, // ref rois
|
||||
std::vector<T>{0.826641, 0.566372, 0.559075, 0.479851, 0.267999}, // ref scores
|
||||
std::vector<RT>{5}, // ref roiNum
|
||||
"eval_2")
|
||||
};
|
||||
return generateProposalParams;
|
||||
}
|
||||
|
||||
std::vector<GPParams> generateGPCombinedParams() {
|
||||
const std::vector<std::vector<GPParams>> GPTypeParams {
|
||||
generateGPFloatParams<element::Type_t::f32, element::Type_t::i32>(),
|
||||
generateGPFloatParams<element::Type_t::f32, element::Type_t::i64>(),
|
||||
generateGPFloatParams<element::Type_t::f16, element::Type_t::i32>(),
|
||||
generateGPFloatParams<element::Type_t::bf16, element::Type_t::i64>(),
|
||||
};
|
||||
std::vector<GPParams> combinedParams;
|
||||
|
||||
for (const auto& params : GPTypeParams) {
|
||||
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
|
||||
}
|
||||
return combinedParams;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_GenerateProposals_With_Hardcoded_Refs, ReferenceGPLayerTest,
|
||||
testing::ValuesIn(generateGPCombinedParams()), ReferenceGPLayerTest::getTestCaseName);
|
||||
} // namespace
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <ngraph/opsets/opset5.hpp>
|
||||
#include <ngraph/opsets/opset6.hpp>
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
#include <ngraph/opsets/opset9.hpp>
|
||||
#include <ngraph/runtime/reference/convert.hpp>
|
||||
#include <vector>
|
||||
|
||||
@@ -33,6 +34,7 @@ bool fuse_type_to_nms4(const std::shared_ptr<ngraph::Node>& node, ngraph::elemen
|
||||
bool fuse_type_to_nms5(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
bool fuse_type_to_matrix_nms(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
bool fuse_type_to_multiclass_nms(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
bool fuse_type_to_generate_proposals(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
bool fuse_type_to_topk(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
bool fuse_type_to_maxpool(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
bool fuse_type_to_nonzero(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx);
|
||||
@@ -258,6 +260,7 @@ bool ngraph::pass::ConvertPrecision::run_on_model(const std::shared_ptr<ngraph::
|
||||
{opset5::NonMaxSuppression::get_type_info_static(), fuse_type_to_nms5},
|
||||
{opset8::MatrixNms::get_type_info_static(), fuse_type_to_matrix_nms},
|
||||
{opset8::MulticlassNms::get_type_info_static(), fuse_type_to_multiclass_nms},
|
||||
{opset9::GenerateProposals::get_type_info_static(), fuse_type_to_generate_proposals},
|
||||
{opset6::CTCGreedyDecoderSeqLen::get_type_info_static(), fuse_type_to_ctc_greedy_decoder_seq_len},
|
||||
{opset4::TopK::get_type_info_static(), fuse_type_to_topk},
|
||||
{opset8::MaxPool::get_type_info_static(), fuse_type_to_maxpool},
|
||||
@@ -429,6 +432,20 @@ bool fuse_type_to_multiclass_nms(const std::shared_ptr<ngraph::Node>& node, ngra
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fuse_type_to_generate_proposals(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx) {
|
||||
auto generate_proposals = ov::as_type_ptr<opset9::GenerateProposals>(node);
|
||||
if (!generate_proposals) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((idx == 2) && (to == element::i32 || to == element::i64)) {
|
||||
generate_proposals->set_roi_num_type(to);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fuse_type_to_topk(const std::shared_ptr<ngraph::Node>& node, ngraph::element::Type to, size_t idx) {
|
||||
if (auto topk = ov::as_type_ptr<opset4::TopK>(node)) {
|
||||
if (idx == 1 && (to == element::i32 || to == element::i64)) {
|
||||
|
||||
15
src/core/include/ngraph/op/generate_proposals.hpp
Normal file
15
src/core/include/ngraph/op/generate_proposals.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/op/generate_proposals.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace op {
|
||||
namespace v9 {
|
||||
using ov::op::v9::GenerateProposals;
|
||||
} // namespace v9
|
||||
} // namespace op
|
||||
} // namespace ngraph
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "ngraph/op/gather_nd.hpp"
|
||||
#include "ngraph/op/gather_tree.hpp"
|
||||
#include "ngraph/op/gelu.hpp"
|
||||
#include "ngraph/op/generate_proposals.hpp"
|
||||
#include "ngraph/op/greater.hpp"
|
||||
#include "ngraph/op/greater_eq.hpp"
|
||||
#include "ngraph/op/grn.hpp"
|
||||
|
||||
80
src/core/include/openvino/op/generate_proposals.hpp
Normal file
80
src/core/include/openvino/op/generate_proposals.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/op/op.hpp"
|
||||
#include "openvino/op/util/attr_types.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v9 {
|
||||
/// \brief An operation GenerateProposals
|
||||
/// computes ROIs and their scores based on input data.
|
||||
class OPENVINO_API GenerateProposals : public Op {
|
||||
public:
|
||||
OPENVINO_OP("GenerateProposals", "opset9");
|
||||
|
||||
/// \brief Structure that specifies attributes of the operation
|
||||
struct Attributes {
|
||||
// minimum box width & height
|
||||
float min_size;
|
||||
// specifies NMS threshold
|
||||
float nms_threshold;
|
||||
// number of top-n proposals after NMS
|
||||
int64_t post_nms_count;
|
||||
// number of top-n proposals before NMS
|
||||
int64_t pre_nms_count;
|
||||
// specify whether the bbox is normalized or not.
|
||||
// For example if *normalized* is true, width = x_right - x_left
|
||||
// If *normalized* is false, width = x_right - x_left + 1.
|
||||
bool normalized = true;
|
||||
// specify eta parameter for adaptive NMS in generate proposals
|
||||
float nms_eta = 1.0;
|
||||
};
|
||||
|
||||
GenerateProposals() = default;
|
||||
/// \brief Constructs a GenerateProposals operation.
|
||||
///
|
||||
/// \param im_info Input image info
|
||||
/// \param anchors Input anchors
|
||||
/// \param deltas Input deltas
|
||||
/// \param scores Input scores
|
||||
/// \param attrs Operation attributes
|
||||
/// \param roi_num_type roi_num type
|
||||
GenerateProposals(const Output<Node>& im_info,
|
||||
const Output<Node>& anchors,
|
||||
const Output<Node>& deltas,
|
||||
const Output<Node>& scores,
|
||||
const Attributes& attrs,
|
||||
const element::Type& roi_num_type = element::i64);
|
||||
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
|
||||
void validate_and_infer_types() override;
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
const Attributes& get_attrs() const {
|
||||
return m_attrs;
|
||||
}
|
||||
|
||||
const element::Type& get_roi_num_type() const {
|
||||
return m_roi_num_type;
|
||||
}
|
||||
void set_roi_num_type(const element::Type& output_type) {
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
(output_type == ov::element::i64) || (output_type == ov::element::i32),
|
||||
"The third output type must be int64 or int32.");
|
||||
m_roi_num_type = output_type;
|
||||
set_output_type(2, output_type, get_output_partial_shape(2));
|
||||
}
|
||||
|
||||
private:
|
||||
Attributes m_attrs;
|
||||
ov::element::Type m_roi_num_type = ov::element::i64;
|
||||
};
|
||||
} // namespace v9
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "openvino/op/gather_nd.hpp"
|
||||
#include "openvino/op/gather_tree.hpp"
|
||||
#include "openvino/op/gelu.hpp"
|
||||
#include "openvino/op/generate_proposals.hpp"
|
||||
#include "openvino/op/greater.hpp"
|
||||
#include "openvino/op/greater_eq.hpp"
|
||||
#include "openvino/op/grn.hpp"
|
||||
|
||||
@@ -194,3 +194,4 @@ _OPENVINO_OP_REG(RDFT, ov::op::v9)
|
||||
_OPENVINO_OP_REG(Eye, ov::op::v9)
|
||||
_OPENVINO_OP_REG(ROIAlign, ov::op::v9)
|
||||
_OPENVINO_OP_REG(SoftSign, ov::op::v9)
|
||||
_OPENVINO_OP_REG(GenerateProposals, ov::op::v9)
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <ngraph/runtime/host_tensor.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/op/util/op_types.hpp"
|
||||
#include "ngraph/ops.hpp"
|
||||
#include "ngraph/shape_util.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace runtime {
|
||||
namespace reference {
|
||||
void generate_proposals(const std::vector<float>& im_info,
|
||||
const std::vector<float>& anchors,
|
||||
const std::vector<float>& deltas,
|
||||
const std::vector<float>& scores,
|
||||
const op::v9::GenerateProposals::Attributes& attrs,
|
||||
const Shape& im_info_shape,
|
||||
const Shape& anchors_shape,
|
||||
const Shape& deltas_shape,
|
||||
const Shape& scores_shape,
|
||||
std::vector<float>& output_rois,
|
||||
std::vector<float>& output_scores,
|
||||
std::vector<int64_t>& num_rois);
|
||||
|
||||
void generate_proposals_postprocessing(void* prois,
|
||||
void* pscores,
|
||||
void* proi_num,
|
||||
const ngraph::element::Type& output_type,
|
||||
const ngraph::element::Type& roi_num_type,
|
||||
const std::vector<float>& output_rois,
|
||||
const std::vector<float>& output_scores,
|
||||
const std::vector<int64_t>& num_rois,
|
||||
const Shape& output_rois_shape,
|
||||
const Shape& output_scores_shape);
|
||||
|
||||
} // namespace reference
|
||||
} // namespace runtime
|
||||
} // namespace ngraph
|
||||
424
src/core/reference/src/runtime/reference/generate_proposal.cpp
Normal file
424
src/core/reference/src/runtime/reference/generate_proposal.cpp
Normal file
@@ -0,0 +1,424 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "ngraph/runtime/reference/generate_proposal.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#include "ngraph/op/generate_proposals.hpp"
|
||||
#include "ngraph/shape.hpp"
|
||||
|
||||
struct sProposalBox {
|
||||
float x0;
|
||||
float y0;
|
||||
float x1;
|
||||
float y1;
|
||||
float score;
|
||||
float keep;
|
||||
};
|
||||
|
||||
static void generate_proposal_refine_anchors(const std::vector<float>& deltas,
|
||||
const std::vector<float>& scores,
|
||||
const std::vector<float>& anchors,
|
||||
float* proposals,
|
||||
const int64_t anchors_num,
|
||||
const int64_t bottom_H,
|
||||
const int64_t bottom_W,
|
||||
const float img_H,
|
||||
const float img_W,
|
||||
const float min_box_H,
|
||||
const float min_box_W,
|
||||
const float max_delta_log_wh,
|
||||
const float coordinates_offset) {
|
||||
int64_t bottom_area = bottom_H * bottom_W;
|
||||
|
||||
for (int64_t h = 0; h < bottom_H; ++h) {
|
||||
for (int64_t w = 0; w < bottom_W; ++w) {
|
||||
// base index for anchors: anchors shape is [bottom_H, bottom_W, anchors_num, 4]
|
||||
int64_t a_idx = (h * bottom_W + w) * anchors_num * 4;
|
||||
// base index for proposals: proposals shape is [bottom_H, bottom_W, anchors_num, 6]
|
||||
int64_t p_idx = (h * bottom_W + w) * anchors_num * 6;
|
||||
// base index for scores: scores shape is [anchors_num, bottom_H, bottom_W]
|
||||
int64_t sc_idx = h * bottom_W + w;
|
||||
// base index for deltas: anchors shape is [anchors_num, 4, bottom_H, bottom_W]
|
||||
int64_t d_idx = h * bottom_W + w;
|
||||
|
||||
for (int64_t anchor = 0; anchor < anchors_num; ++anchor) {
|
||||
float x0 = anchors[a_idx + 0];
|
||||
float y0 = anchors[a_idx + 1];
|
||||
float x1 = anchors[a_idx + 2];
|
||||
float y1 = anchors[a_idx + 3];
|
||||
|
||||
const float dx = deltas[d_idx + 0 * bottom_area];
|
||||
const float dy = deltas[d_idx + 1 * bottom_area];
|
||||
const float d_log_w = deltas[d_idx + 2 * bottom_area];
|
||||
const float d_log_h = deltas[d_idx + 3 * bottom_area];
|
||||
|
||||
const float score = scores[sc_idx];
|
||||
|
||||
// width & height of box
|
||||
const float ww = x1 - x0 + coordinates_offset;
|
||||
const float hh = y1 - y0 + coordinates_offset;
|
||||
// center location of box
|
||||
const float ctr_x = x0 + 0.5f * ww;
|
||||
const float ctr_y = y0 + 0.5f * hh;
|
||||
|
||||
// new center location according to deltas (dx, dy)
|
||||
const float pred_ctr_x = dx * ww + ctr_x;
|
||||
const float pred_ctr_y = dy * hh + ctr_y;
|
||||
// new width & height according to deltas d(log w), d(log h)
|
||||
const float pred_w = std::exp(std::min(d_log_w, max_delta_log_wh)) * ww;
|
||||
const float pred_h = std::exp(std::min(d_log_h, max_delta_log_wh)) * hh;
|
||||
|
||||
// update upper-left corner location
|
||||
x0 = pred_ctr_x - 0.5f * pred_w;
|
||||
y0 = pred_ctr_y - 0.5f * pred_h;
|
||||
// update lower-right corner location
|
||||
x1 = pred_ctr_x + 0.5f * pred_w - coordinates_offset;
|
||||
y1 = pred_ctr_y + 0.5f * pred_h - coordinates_offset;
|
||||
|
||||
// adjust new corner locations to be within the image region,
|
||||
x0 = std::max<float>(0.0f, std::min<float>(x0, img_W - coordinates_offset));
|
||||
y0 = std::max<float>(0.0f, std::min<float>(y0, img_H - coordinates_offset));
|
||||
x1 = std::max<float>(0.0f, std::min<float>(x1, img_W - coordinates_offset));
|
||||
y1 = std::max<float>(0.0f, std::min<float>(y1, img_H - coordinates_offset));
|
||||
|
||||
// recompute new width & height
|
||||
const float box_w = x1 - x0 + coordinates_offset;
|
||||
const float box_h = y1 - y0 + coordinates_offset;
|
||||
|
||||
proposals[p_idx + 0] = x0;
|
||||
proposals[p_idx + 1] = y0;
|
||||
proposals[p_idx + 2] = x1;
|
||||
proposals[p_idx + 3] = y1;
|
||||
proposals[p_idx + 4] = score;
|
||||
proposals[p_idx + 5] = (min_box_W <= box_w) * (min_box_H <= box_h) * 1.0;
|
||||
|
||||
// update index for next anchor iter
|
||||
a_idx += 4; // anchors shape is [bottom_H, bottom_W, anchors_num, 4], so add 4 for next anchor iter
|
||||
p_idx += 6; // proposals shape is [bottom_H, bottom_W, anchors_num, 6], so add 6 for next anchor iter
|
||||
sc_idx += bottom_area; // scores shape is [anchors_num, bottom_H, bottom_W], so add bottom_H * bottom_W
|
||||
// for next anchor iter
|
||||
d_idx += 4 * bottom_area; // deltas shape is [anchors_num, 4, bottom_H, bottom_W], so add 4 * bottom_H
|
||||
// * bottom_W for next anchor iter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_proposal_unpack_boxes(const float* p_proposals,
|
||||
float* unpacked_boxes,
|
||||
int64_t* is_dead,
|
||||
int64_t pre_nms_topn) {
|
||||
for (int64_t i = 0; i < pre_nms_topn; ++i) {
|
||||
unpacked_boxes[0 * pre_nms_topn + i] = p_proposals[6 * i + 0];
|
||||
unpacked_boxes[1 * pre_nms_topn + i] = p_proposals[6 * i + 1];
|
||||
unpacked_boxes[2 * pre_nms_topn + i] = p_proposals[6 * i + 2];
|
||||
unpacked_boxes[3 * pre_nms_topn + i] = p_proposals[6 * i + 3];
|
||||
unpacked_boxes[4 * pre_nms_topn + i] = p_proposals[6 * i + 4];
|
||||
is_dead[i] = (p_proposals[6 * i + 5] == 1.0) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_proposal_nms_cpu(const int64_t num_boxes,
|
||||
int64_t is_dead[],
|
||||
const float* boxes,
|
||||
int64_t index_out[],
|
||||
int64_t& num_out,
|
||||
const int64_t base_index,
|
||||
const float nms_thresh,
|
||||
const int64_t max_num_out,
|
||||
const float coordinates_offset) {
|
||||
const int64_t num_proposals = num_boxes;
|
||||
int64_t count = 0;
|
||||
|
||||
const float* x0 = boxes + 0 * num_proposals;
|
||||
const float* y0 = boxes + 1 * num_proposals;
|
||||
const float* x1 = boxes + 2 * num_proposals;
|
||||
const float* y1 = boxes + 3 * num_proposals;
|
||||
|
||||
for (int64_t box = 0; box < num_boxes; ++box) {
|
||||
if (is_dead[box])
|
||||
continue;
|
||||
|
||||
index_out[count++] = base_index + box;
|
||||
if (count == max_num_out)
|
||||
break;
|
||||
|
||||
const float x0i = x0[box];
|
||||
const float y0i = y0[box];
|
||||
const float x1i = x1[box];
|
||||
const float y1i = y1[box];
|
||||
|
||||
const float a_width = x1i - x0i;
|
||||
const float a_height = y1i - y0i;
|
||||
const float a_area = (a_width + coordinates_offset) * (a_height + coordinates_offset);
|
||||
|
||||
for (int64_t tail = box + 1; tail < num_boxes; ++tail) {
|
||||
const float x0j = x0[tail];
|
||||
const float y0j = y0[tail];
|
||||
const float x1j = x1[tail];
|
||||
const float y1j = y1[tail];
|
||||
|
||||
const float x0 = std::max(x0i, x0j);
|
||||
const float y0 = std::max(y0i, y0j);
|
||||
const float x1 = std::min(x1i, x1j);
|
||||
const float y1 = std::min(y1i, y1j);
|
||||
|
||||
const float width = x1 - x0 + coordinates_offset;
|
||||
const float height = y1 - y0 + coordinates_offset;
|
||||
const float area = std::max(0.0f, width) * std::max(0.0f, height);
|
||||
|
||||
const float b_width = x1j - x0j;
|
||||
const float b_height = y1j - y0j;
|
||||
const float b_area = (b_width + coordinates_offset) * (b_height + coordinates_offset);
|
||||
|
||||
const float intersection_area = area / (a_area + b_area - area);
|
||||
|
||||
if ((nms_thresh < intersection_area) && (x0i <= x1j) && (y0i <= y1j) && (x0j <= x1i) && (y0j <= y1i))
|
||||
is_dead[tail] = 1;
|
||||
}
|
||||
}
|
||||
num_out = count;
|
||||
}
|
||||
|
||||
static void generate_proposal_fill_output_blobs(const float* proposals,
|
||||
const int64_t* roi_indices,
|
||||
std::vector<float>& rois,
|
||||
std::vector<float>& scores,
|
||||
const int64_t num_proposals,
|
||||
const int64_t num_rois,
|
||||
const int64_t post_nms_topn) {
|
||||
const float* src_x0 = proposals + 0 * num_proposals;
|
||||
const float* src_y0 = proposals + 1 * num_proposals;
|
||||
const float* src_x1 = proposals + 2 * num_proposals;
|
||||
const float* src_y1 = proposals + 3 * num_proposals;
|
||||
const float* src_score = proposals + 4 * num_proposals;
|
||||
|
||||
for (int64_t i = 0; i < num_rois; ++i) {
|
||||
int64_t index = roi_indices[i];
|
||||
rois.push_back(src_x0[index]);
|
||||
rois.push_back(src_y0[index]);
|
||||
rois.push_back(src_x1[index]);
|
||||
rois.push_back(src_y1[index]);
|
||||
scores.push_back(src_score[index]);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ngraph {
|
||||
namespace runtime {
|
||||
namespace reference {
|
||||
|
||||
static void generate_proposals_single_image(const std::vector<float>& im_info,
|
||||
const std::vector<float>& anchors,
|
||||
const std::vector<float>& deltas,
|
||||
const std::vector<float>& scores,
|
||||
const op::v9::GenerateProposals::Attributes& attrs,
|
||||
const Shape& im_info_shape,
|
||||
const Shape& anchors_shape,
|
||||
const Shape& deltas_shape,
|
||||
const Shape& scores_shape,
|
||||
std::vector<float>& output_rois,
|
||||
std::vector<float>& output_scores,
|
||||
int64_t& num_rois) {
|
||||
const int64_t anchors_num = static_cast<int64_t>(scores_shape[1]);
|
||||
|
||||
// bottom shape: batch x (num_anchors) x H x W
|
||||
const int64_t bottom_H = static_cast<int64_t>(deltas_shape[2]);
|
||||
const int64_t bottom_W = static_cast<int64_t>(deltas_shape[3]);
|
||||
|
||||
// input image height & width
|
||||
const float img_H = im_info[0];
|
||||
const float img_W = im_info[1];
|
||||
|
||||
// scale factor for height & width
|
||||
float scale_h = 1.0;
|
||||
float scale_w = 1.0;
|
||||
if (im_info.size() == 3) {
|
||||
scale_h = im_info[2];
|
||||
scale_w = im_info[2];
|
||||
} else if (im_info.size() == 4) {
|
||||
scale_h = im_info[2];
|
||||
scale_w = im_info[3];
|
||||
}
|
||||
|
||||
// minimum box width & height
|
||||
const float min_box_H = attrs.min_size * scale_h;
|
||||
const float min_box_W = attrs.min_size * scale_w;
|
||||
|
||||
const float nms_thresh = attrs.nms_threshold;
|
||||
const int64_t post_nms_topn = attrs.post_nms_count;
|
||||
|
||||
// number of all proposals = num_anchors * H * W
|
||||
const int64_t num_proposals = anchors_num * bottom_H * bottom_W;
|
||||
|
||||
// number of top-n proposals before NMS
|
||||
const int64_t pre_nms_topn = std::min(num_proposals, attrs.pre_nms_count);
|
||||
|
||||
// bbox normalized flag
|
||||
const float coordinates_offset = attrs.normalized ? 0 : 1.0;
|
||||
|
||||
std::vector<sProposalBox> proposals(num_proposals);
|
||||
std::vector<float> unpacked_boxes(5 * pre_nms_topn);
|
||||
std::vector<int64_t> is_dead(pre_nms_topn);
|
||||
|
||||
generate_proposal_refine_anchors(deltas,
|
||||
scores,
|
||||
anchors,
|
||||
reinterpret_cast<float*>(proposals.data()),
|
||||
anchors_num,
|
||||
bottom_H,
|
||||
bottom_W,
|
||||
img_H,
|
||||
img_W,
|
||||
min_box_H,
|
||||
min_box_W,
|
||||
static_cast<const float>(std::log(1000. / 16.)),
|
||||
coordinates_offset);
|
||||
std::partial_sort(proposals.begin(),
|
||||
proposals.begin() + pre_nms_topn,
|
||||
proposals.end(),
|
||||
[](const sProposalBox& struct1, const sProposalBox& struct2) {
|
||||
return (struct1.score > struct2.score);
|
||||
});
|
||||
|
||||
generate_proposal_unpack_boxes(reinterpret_cast<float*>(proposals.data()),
|
||||
unpacked_boxes.data(),
|
||||
is_dead.data(),
|
||||
pre_nms_topn);
|
||||
|
||||
std::vector<int64_t> roi_indices(post_nms_topn);
|
||||
|
||||
generate_proposal_nms_cpu(pre_nms_topn,
|
||||
is_dead.data(),
|
||||
unpacked_boxes.data(),
|
||||
roi_indices.data(),
|
||||
num_rois,
|
||||
0,
|
||||
nms_thresh,
|
||||
post_nms_topn,
|
||||
coordinates_offset);
|
||||
generate_proposal_fill_output_blobs(unpacked_boxes.data(),
|
||||
roi_indices.data(),
|
||||
output_rois,
|
||||
output_scores,
|
||||
pre_nms_topn,
|
||||
num_rois,
|
||||
post_nms_topn);
|
||||
}
|
||||
|
||||
void generate_proposals(const std::vector<float>& im_info,
|
||||
const std::vector<float>& anchors,
|
||||
const std::vector<float>& deltas,
|
||||
const std::vector<float>& scores,
|
||||
const op::v9::GenerateProposals::Attributes& attrs,
|
||||
const Shape& im_info_shape,
|
||||
const Shape& anchors_shape,
|
||||
const Shape& deltas_shape,
|
||||
const Shape& scores_shape,
|
||||
std::vector<float>& output_rois,
|
||||
std::vector<float>& output_scores,
|
||||
std::vector<int64_t>& num_rois) {
|
||||
const auto im_info_size =
|
||||
std::accumulate(im_info_shape.begin() + 1, im_info_shape.end(), 1, std::multiplies<size_t>());
|
||||
const auto deltas_size =
|
||||
std::accumulate(deltas_shape.begin() + 1, deltas_shape.end(), 1, std::multiplies<size_t>());
|
||||
const auto scores_size =
|
||||
std::accumulate(scores_shape.begin() + 1, scores_shape.end(), 1, std::multiplies<size_t>());
|
||||
for (auto i = 0; i < im_info_shape[0]; i++) {
|
||||
std::vector<float> cur_im_info(im_info.begin() + i * im_info_size,
|
||||
im_info.begin() + i * im_info_size + im_info_size);
|
||||
std::vector<float> cur_deltas(deltas.begin() + i * deltas_size, deltas.begin() + i * deltas_size + deltas_size);
|
||||
std::vector<float> cur_scores(scores.begin() + i * scores_size, scores.begin() + i * scores_size + scores_size);
|
||||
std::vector<float> output_roi;
|
||||
std::vector<float> output_score;
|
||||
int64_t num_roi;
|
||||
generate_proposals_single_image(cur_im_info,
|
||||
anchors,
|
||||
cur_deltas,
|
||||
cur_scores,
|
||||
attrs,
|
||||
im_info_shape,
|
||||
anchors_shape,
|
||||
deltas_shape,
|
||||
scores_shape,
|
||||
output_roi,
|
||||
output_score,
|
||||
num_roi);
|
||||
output_rois.insert(output_rois.end(), output_roi.begin(), output_roi.end());
|
||||
output_scores.insert(output_scores.end(), output_score.begin(), output_score.end());
|
||||
num_rois.push_back(num_roi);
|
||||
}
|
||||
}
|
||||
|
||||
void generate_proposals_postprocessing(void* prois,
|
||||
void* pscores,
|
||||
void* proi_num,
|
||||
const ngraph::element::Type& output_type,
|
||||
const ngraph::element::Type& roi_num_type,
|
||||
const std::vector<float>& output_rois,
|
||||
const std::vector<float>& output_scores,
|
||||
const std::vector<int64_t>& num_rois,
|
||||
const Shape& output_rois_shape,
|
||||
const Shape& output_scores_shape) {
|
||||
size_t rois_num = output_rois_shape[0];
|
||||
|
||||
switch (output_type) {
|
||||
case element::Type_t::bf16: {
|
||||
bfloat16* rois_ptr = reinterpret_cast<bfloat16*>(prois);
|
||||
bfloat16* scores_ptr = reinterpret_cast<bfloat16*>(pscores);
|
||||
for (size_t i = 0; i < rois_num; ++i) {
|
||||
rois_ptr[4 * i + 0] = bfloat16(output_rois[4 * i + 0]);
|
||||
rois_ptr[4 * i + 1] = bfloat16(output_rois[4 * i + 1]);
|
||||
rois_ptr[4 * i + 2] = bfloat16(output_rois[4 * i + 2]);
|
||||
rois_ptr[4 * i + 3] = bfloat16(output_rois[4 * i + 3]);
|
||||
scores_ptr[i] = bfloat16(output_scores[i]);
|
||||
}
|
||||
} break;
|
||||
case element::Type_t::f16: {
|
||||
float16* rois_ptr = reinterpret_cast<float16*>(prois);
|
||||
float16* scores_ptr = reinterpret_cast<float16*>(pscores);
|
||||
for (size_t i = 0; i < rois_num; ++i) {
|
||||
rois_ptr[4 * i + 0] = float16(output_rois[4 * i + 0]);
|
||||
rois_ptr[4 * i + 1] = float16(output_rois[4 * i + 1]);
|
||||
rois_ptr[4 * i + 2] = float16(output_rois[4 * i + 2]);
|
||||
rois_ptr[4 * i + 3] = float16(output_rois[4 * i + 3]);
|
||||
scores_ptr[i] = float16(output_scores[i]);
|
||||
}
|
||||
} break;
|
||||
case element::Type_t::f32: {
|
||||
float* rois_ptr = reinterpret_cast<float*>(prois);
|
||||
float* scores_ptr = reinterpret_cast<float*>(pscores);
|
||||
memcpy(rois_ptr, output_rois.data(), shape_size(output_rois_shape) * sizeof(float));
|
||||
memcpy(scores_ptr, output_scores.data(), shape_size(output_scores_shape) * sizeof(float));
|
||||
} break;
|
||||
default:;
|
||||
throw ngraph_error("Unsupported input data type: "
|
||||
"GenerateProposals operation"
|
||||
" supports only fp32, fp16, or bf16 data.");
|
||||
}
|
||||
|
||||
for (auto i = 0; i < num_rois.size(); i++) {
|
||||
switch (roi_num_type) {
|
||||
case element::Type_t::i32: {
|
||||
int32_t* roi_num_ptr = reinterpret_cast<int32_t*>(proi_num);
|
||||
roi_num_ptr[i] = static_cast<int32_t>(num_rois[i]);
|
||||
} break;
|
||||
case element::Type_t::i64: {
|
||||
int64_t* roi_num_ptr = reinterpret_cast<int64_t*>(proi_num);
|
||||
roi_num_ptr[i] = static_cast<int64_t>(num_rois[i]);
|
||||
} break;
|
||||
default:;
|
||||
throw ngraph_error("Unsupported data type on output port 3: "
|
||||
" supports only int32 or int64.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace reference
|
||||
} // namespace runtime
|
||||
} // namespace ngraph
|
||||
@@ -0,0 +1,131 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <openvino/op/generate_proposals.hpp>
|
||||
|
||||
namespace ov {
|
||||
namespace op {
|
||||
|
||||
namespace v9 {
|
||||
template <class T>
|
||||
void shape_infer(const GenerateProposals* op,
|
||||
const std::vector<T>& input_shapes,
|
||||
std::vector<T>& output_shapes) {
|
||||
NODE_VALIDATION_CHECK(op, input_shapes.size() == 4 && output_shapes.size() == 3);
|
||||
|
||||
const auto& im_info_shape = input_shapes[0];
|
||||
const auto& anchors_shape = input_shapes[1];
|
||||
const auto& deltas_shape = input_shapes[2];
|
||||
const auto& scores_shape = input_shapes[3];
|
||||
const auto im_info_shape_rank = im_info_shape.rank();
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
im_info_shape_rank.compatible(2),
|
||||
"The 'input_im_info' input is expected to be a 2D. Got: ",
|
||||
im_info_shape);
|
||||
|
||||
if (im_info_shape_rank.is_static()) {
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
(im_info_shape[1].compatible(3) || im_info_shape[1].compatible(4)),
|
||||
"The 'input_im_info' shape[1] is expected to be a compatible with [3] or [4]. Got: ",
|
||||
im_info_shape);
|
||||
}
|
||||
|
||||
const auto anchors_shape_rank = anchors_shape.rank();
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
anchors_shape_rank.compatible(4),
|
||||
"The 'input_anchors' input is expected to be a 4D. Got: ",
|
||||
anchors_shape);
|
||||
if (anchors_shape_rank.is_static()) {
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
anchors_shape[3].compatible(4),
|
||||
"The fourth dimension of 'input_anchors' should be compatible with 4. Got: ",
|
||||
anchors_shape[3]);
|
||||
}
|
||||
const auto deltas_shape_rank = deltas_shape.rank();
|
||||
const auto scores_shape_rank = scores_shape.rank();
|
||||
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
deltas_shape_rank.compatible(4),
|
||||
"The 'input_deltas' input is expected to be a 4D. Got: ",
|
||||
deltas_shape);
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
scores_shape_rank.compatible(4),
|
||||
"The 'input_scores' input is expected to be a 4D. Got: ",
|
||||
scores_shape);
|
||||
if (deltas_shape_rank.is_static() && scores_shape_rank.is_static()) {
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
deltas_shape[0].compatible(scores_shape[0]),
|
||||
"Batch for inputs 'input_deltas' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
deltas_shape[0],
|
||||
scores_shape[0]);
|
||||
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
deltas_shape[1].compatible(scores_shape[1] * 4),
|
||||
"Anchor number for inputs 'input_deltas' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
deltas_shape[1] / 4,
|
||||
scores_shape[1]);
|
||||
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
deltas_shape[2].compatible(scores_shape[2]),
|
||||
"Heights for inputs 'input_deltas' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
deltas_shape[2],
|
||||
scores_shape[2]);
|
||||
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
deltas_shape[3].compatible(scores_shape[3]),
|
||||
"Width for inputs 'input_deltas' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
deltas_shape[3],
|
||||
scores_shape[3]);
|
||||
|
||||
if (im_info_shape_rank.is_static()) {
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
deltas_shape[0].compatible(im_info_shape[0]),
|
||||
"Batch for inputs 'im_info' and 'input_deltas' should be "
|
||||
"equal. Got: ",
|
||||
deltas_shape[0],
|
||||
im_info_shape[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (scores_shape_rank.is_static() && anchors_shape_rank.is_static()) {
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
anchors_shape[0].compatible(scores_shape[2]),
|
||||
"Heights for inputs 'input_anchors' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
anchors_shape[0],
|
||||
scores_shape[2]);
|
||||
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
anchors_shape[1].compatible(scores_shape[3]),
|
||||
"Width for inputs 'input_anchors' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
anchors_shape[1],
|
||||
scores_shape[3]);
|
||||
|
||||
NODE_VALIDATION_CHECK(op,
|
||||
anchors_shape[2].compatible(scores_shape[1]),
|
||||
"Anchor number for inputs 'input_anchors' and 'input_scores' should be "
|
||||
"equal. Got: ",
|
||||
anchors_shape[2],
|
||||
scores_shape[1]);
|
||||
}
|
||||
|
||||
output_shapes[0] = ov::PartialShape({Dimension::dynamic(), 4});
|
||||
output_shapes[1] = ov::PartialShape::dynamic(1);
|
||||
if (im_info_shape_rank.is_static()) {
|
||||
output_shapes[2] = ov::PartialShape({im_info_shape[0]});
|
||||
} else {
|
||||
output_shapes[2] = ov::PartialShape::dynamic(1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace v9
|
||||
} // namespace op
|
||||
} // namespace ov
|
||||
70
src/core/src/op/generate_proposals.cpp
Normal file
70
src/core/src/op/generate_proposals.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/op/generate_proposals.hpp"
|
||||
|
||||
#include "generate_proposals_shape_inference.hpp"
|
||||
#include "itt.hpp"
|
||||
|
||||
using namespace std;
|
||||
namespace ov {
|
||||
|
||||
op::v9::GenerateProposals::GenerateProposals(const Output<Node>& im_info,
|
||||
const Output<Node>& anchors,
|
||||
const Output<Node>& deltas,
|
||||
const Output<Node>& scores,
|
||||
const Attributes& attrs,
|
||||
const element::Type& roi_num_type)
|
||||
: Op({im_info, anchors, deltas, scores}),
|
||||
m_attrs(attrs),
|
||||
m_roi_num_type(roi_num_type) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
shared_ptr<Node> op::v9::GenerateProposals::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
NGRAPH_OP_SCOPE(v9_GenerateProposals_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
return make_shared<ov::op::v9::GenerateProposals>(new_args.at(0),
|
||||
new_args.at(1),
|
||||
new_args.at(2),
|
||||
new_args.at(3),
|
||||
m_attrs,
|
||||
m_roi_num_type);
|
||||
}
|
||||
|
||||
bool op::v9::GenerateProposals::visit_attributes(AttributeVisitor& visitor) {
|
||||
NGRAPH_OP_SCOPE(v9_GenerateProposals_visit_attributes);
|
||||
visitor.on_attribute("min_size", m_attrs.min_size);
|
||||
visitor.on_attribute("nms_threshold", m_attrs.nms_threshold);
|
||||
visitor.on_attribute("post_nms_count", m_attrs.post_nms_count);
|
||||
visitor.on_attribute("pre_nms_count", m_attrs.pre_nms_count);
|
||||
visitor.on_attribute("normalized", m_attrs.normalized);
|
||||
visitor.on_attribute("nms_eta", m_attrs.nms_eta);
|
||||
visitor.on_attribute("roi_num_type", m_roi_num_type);
|
||||
return true;
|
||||
}
|
||||
|
||||
void op::v9::GenerateProposals::validate_and_infer_types() {
|
||||
NGRAPH_OP_SCOPE(v9_GenerateProposals_validate_and_infer_types);
|
||||
NODE_VALIDATION_CHECK(this, m_attrs.pre_nms_count > 0, "Attribute pre_nms_count must be larger than 0.");
|
||||
NODE_VALIDATION_CHECK(this, m_attrs.post_nms_count > 0, "Attribute post_nms_count must be larger than 0.");
|
||||
NODE_VALIDATION_CHECK(this, m_attrs.nms_eta == 1.0, "Attribute min_size must be 1.0.");
|
||||
|
||||
std::vector<PartialShape> output_shapes = {PartialShape{}, PartialShape{}, PartialShape{}};
|
||||
std::vector<PartialShape> input_shapes = {get_input_partial_shape(0),
|
||||
get_input_partial_shape(1),
|
||||
get_input_partial_shape(2),
|
||||
get_input_partial_shape(3)};
|
||||
shape_infer(this, input_shapes, output_shapes);
|
||||
|
||||
const auto& input_et = get_input_element_type(0);
|
||||
set_output_type(0, input_et, output_shapes[0]);
|
||||
set_output_type(1, input_et, output_shapes[1]);
|
||||
const auto& roi_num_type = get_roi_num_type();
|
||||
NODE_VALIDATION_CHECK(this,
|
||||
(roi_num_type == element::i64) || (roi_num_type == element::i32),
|
||||
"The third output type must be int64 or int32.");
|
||||
set_output_type(2, roi_num_type, output_shapes[2]);
|
||||
}
|
||||
} // namespace ov
|
||||
@@ -127,6 +127,7 @@ set(SRC
|
||||
type_prop/erf.cpp
|
||||
type_prop/exp.cpp
|
||||
type_prop/experimental_detectron_generate_proposals.cpp
|
||||
type_prop/generate_proposals.cpp
|
||||
type_prop/experimental_detectron_roi_feature_extractor.cpp
|
||||
type_prop/experimental_detectron_topkrois.cpp
|
||||
type_prop/strided_slice.cpp
|
||||
@@ -298,6 +299,7 @@ set(SRC
|
||||
visitors/op/exp.cpp
|
||||
visitors/op/experimental_detectron_detection_output.cpp
|
||||
visitors/op/experimental_detectron_generate_proposals.cpp
|
||||
visitors/op/generate_proposals.cpp
|
||||
visitors/op/experimental_detectron_prior_grid_generator.cpp
|
||||
visitors/op/experimental_detectron_topkrois.cpp
|
||||
visitors/op/eye.cpp
|
||||
|
||||
@@ -25,17 +25,31 @@ ie_check_pip_package(paddlepaddle WARNING paddle)
|
||||
set(TEST_PADDLE_MODELS_DIRNAME test_model_zoo/paddle_test_models)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE -D TEST_PADDLE_MODELS_DIRNAME=\"${TEST_PADDLE_MODELS_DIRNAME}/\")
|
||||
|
||||
set(PADDLEDET_OPS_URL "https://raw.githubusercontent.com/PaddlePaddle/PaddleDetection/release/2.1/ppdet/modeling/ops.py")
|
||||
set(PADDLEDET_DIRNAME ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/PaddleDetection/ppdet/modeling/)
|
||||
set(PADDLEDET_OPS_SHA256 "5cc079eda295ed78b58fba8223c51d85a931a7069ecad51c6af5c2fd26b7a8cb")
|
||||
|
||||
DownloadAndCheck(${PADDLEDET_OPS_URL} ${PADDLEDET_DIRNAME}/ops.py PADDLEDET_FATAL PADDLEDET_RESULT ${PADDLEDET_OPS_SHA256})
|
||||
|
||||
# If 'paddlepaddle' is not found, code will still be compiled
|
||||
# but models will not be generated and tests will fail
|
||||
# This is done this way for 'code style' and check cases - cmake shall pass, but CI machine doesn't need to have
|
||||
# 'paddlepaddle' installed to check code style
|
||||
if (paddlepaddle_FOUND)
|
||||
if (paddlepaddle_FOUND AND ${PADDLEDET_RESULT} STREQUAL "ON")
|
||||
set(TEST_PADDLE_MODELS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_PADDLE_MODELS_DIRNAME}/)
|
||||
|
||||
if (WIN32)
|
||||
set(SETENV "set")
|
||||
set(PATHSEP ";")
|
||||
else()
|
||||
set(SETENV "export")
|
||||
set(PATHSEP ":")
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE PADDLE_ALL_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/*.py)
|
||||
set(OUT_FILE ${TEST_PADDLE_MODELS}/generate_done.txt)
|
||||
add_custom_command(OUTPUT ${OUT_FILE}
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
COMMAND ${SETENV} PYTHONPATH=${PADDLEDET_DIRNAME}${PATHSEP}$ENV{PYTHONPATH} && ${PYTHON_EXECUTABLE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_wrapper.py
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_models/gen_scripts
|
||||
${TEST_PADDLE_MODELS}
|
||||
|
||||
@@ -144,6 +144,13 @@ static const std::vector<std::string> models{std::string("argmax"),
|
||||
// (CVS-82724: not support Axis as input),
|
||||
std::string("gelu_erf"),
|
||||
std::string("gelu_tanh"),
|
||||
std::string("generate_proposals_v2_0"),
|
||||
std::string("generate_proposals_v2_1"),
|
||||
std::string("generate_proposals_v2_2"),
|
||||
std::string("generate_proposals_v2_3"),
|
||||
std::string("generate_proposals_v2_4"),
|
||||
std::string("generate_proposals_v2_5"),
|
||||
std::string("generate_proposals_v2_6"),
|
||||
// greater_equal_big_int64(failure due to CPU inference),
|
||||
std::string("greater_equal_big_int64"),
|
||||
std::string("greater_equal_float32"),
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
#
|
||||
# pool2d paddle model generator
|
||||
#
|
||||
import numpy as np
|
||||
from save_model import saveModel
|
||||
import sys
|
||||
|
||||
def generate_proposals_v2(name: str, input_data: dict, attr: dict):
|
||||
scores_np = input_data["scores"]
|
||||
bbox_deltas_np = input_data["bbox_deltas"]
|
||||
im_shape_np = input_data["im_shape"]
|
||||
anchors_np = input_data["anchors"]
|
||||
variances_np = input_data["variances"]
|
||||
|
||||
pre_nms_top_n = attr["pre_nms_top_n"]
|
||||
post_nms_top_n = attr["post_nms_top_n"]
|
||||
nms_thresh = attr["nms_thresh"]
|
||||
min_size = attr["min_size"]
|
||||
pixel_offset = attr["pixel_offset"]
|
||||
|
||||
import paddle
|
||||
from ops import generate_proposals as generate_proposals
|
||||
|
||||
paddle.enable_static()
|
||||
|
||||
with paddle.static.program_guard(paddle.static.Program(), paddle.static.Program()):
|
||||
scores = paddle.static.data(
|
||||
name='scores', shape=scores_np.shape, dtype='float32') # [N, A, H, W]
|
||||
bbox_deltas = paddle.static.data(
|
||||
name='bbox_deltas', shape=bbox_deltas_np.shape, dtype='float32') # [N, 4 * A, H, W]
|
||||
im_shape = paddle.static.data(
|
||||
name='im_shape', shape=im_shape_np.shape, dtype='float32') # [N, 2]
|
||||
anchors = paddle.static.data(
|
||||
name='anchors', shape=anchors_np.shape, dtype='float32') # [H, W, A, 4]
|
||||
variances = paddle.static.data(
|
||||
name='var', shape=variances_np.shape, dtype='float32') # [H, W, A, 4]
|
||||
rois, roi_probs, rois_num = generate_proposals(
|
||||
scores,
|
||||
bbox_deltas,
|
||||
im_shape,
|
||||
anchors,
|
||||
variances,
|
||||
pre_nms_top_n=pre_nms_top_n,
|
||||
post_nms_top_n=post_nms_top_n,
|
||||
nms_thresh=nms_thresh,
|
||||
min_size=min_size,
|
||||
pixel_offset=pixel_offset,
|
||||
return_rois_num=True)
|
||||
|
||||
cpu = paddle.static.cpu_places(1)
|
||||
exe = paddle.static.Executor(cpu[0])
|
||||
# startup program will call initializer to initialize the parameters.
|
||||
exe.run(paddle.static.default_startup_program())
|
||||
|
||||
outs = exe.run(
|
||||
feed={
|
||||
'scores': scores_np,
|
||||
'bbox_deltas': bbox_deltas_np,
|
||||
'im_shape': im_shape_np,
|
||||
'anchors': anchors_np,
|
||||
'var': variances_np
|
||||
},
|
||||
fetch_list=[rois, roi_probs, rois_num],
|
||||
return_numpy=False)
|
||||
|
||||
# Save inputs in order of ngraph function, to facilite Fuzzy test,
|
||||
# which accepts inputs and outputs in this order as well.
|
||||
saveModel(name, exe, feedkeys=['scores', 'bbox_deltas', 'im_shape', 'anchors', 'var'],
|
||||
fetchlist=[rois, roi_probs, rois_num],
|
||||
inputs=[scores_np, bbox_deltas_np, im_shape_np, anchors_np, variances_np],
|
||||
outputs=outs, target_dir=sys.argv[1])
|
||||
|
||||
if __name__ == "__main__":
|
||||
input_data = dict()
|
||||
attr = dict()
|
||||
|
||||
# test case 0
|
||||
input_name = "generate_proposals_v2_0"
|
||||
input_data["scores"] = np.random.rand(1, 3, 4, 4).astype('float32')
|
||||
input_data["bbox_deltas"] = np.random.rand(1, 12, 4, 4).astype('float32')
|
||||
input_data["im_shape"] = np.array([[200, 200]]).astype('float32')
|
||||
input_data["anchors"] = np.reshape(np.arange(4 * 4 * 3 * 4),
|
||||
[4, 4, 3, 4]).astype('float32')
|
||||
input_data["variances"] = np.ones((4, 4, 3, 4)).astype('float32')
|
||||
|
||||
attr["pre_nms_top_n"] = 6000
|
||||
attr["post_nms_top_n"] = 1000
|
||||
attr["nms_thresh"] = 0.699999988079071
|
||||
attr["min_size"] = 0
|
||||
attr["pixel_offset"] = False
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
|
||||
# test case 1
|
||||
input_name = "generate_proposals_v2_1"
|
||||
input_data["variances"] = np.ones((4 * 4 * 3, 4)).astype('float32')
|
||||
input_data["anchors"] = np.reshape(np.arange(4 * 4 * 3 * 4),
|
||||
[4 * 4 * 3, 4]).astype('float32')
|
||||
attr["min_size"] = 4
|
||||
attr["pixel_offset"] = True
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
|
||||
# test case 2
|
||||
input_name = "generate_proposals_v2_2"
|
||||
|
||||
bbox_deltas0 = np.random.rand(1, 12, 1, 4).astype('float32')
|
||||
bbox_deltas1 = np.random.rand(1, 12, 2, 4).astype('float32')
|
||||
input_data["bbox_deltas"] = np.concatenate((bbox_deltas0, bbox_deltas0, bbox_deltas1), axis = 2)
|
||||
|
||||
anchors0 = np.reshape(np.arange(1 * 4 * 3 * 4),
|
||||
[1, 4, 3, 4]).astype('float32')
|
||||
anchors1 = np.reshape(np.arange(3 * 4 * 3 * 4),
|
||||
[3, 4, 3, 4]).astype('float32')
|
||||
input_data["anchors"] = np.concatenate((anchors0, anchors1), axis = 0)
|
||||
|
||||
attr["nms_thresh"] = 0.5
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
|
||||
# test case 3
|
||||
input_name = "generate_proposals_v2_3"
|
||||
attr["nms_thresh"] = 0.7
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
|
||||
# test case 4
|
||||
input_name = "generate_proposals_v2_4"
|
||||
variances_0 = np.ones((11, 4)).astype('float32') * 0.5
|
||||
variances_1 = np.ones((37, 4)).astype('float32')
|
||||
input_data["variances"] = np.concatenate((variances_0, variances_1), axis = 0)
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
|
||||
# test case 5
|
||||
input_name = "generate_proposals_v2_5"
|
||||
input_data["scores"] = np.random.rand(1, 6, 10, 8).astype('float32')
|
||||
input_data["bbox_deltas"] = np.random.rand(1, 24, 10, 8).astype('float32')
|
||||
input_data["im_shape"] = np.array([[1000, 1000]]).astype('float32')
|
||||
input_data["anchors"] = np.reshape(np.arange(10 * 8 * 6 * 4),
|
||||
[10, 8, 6, 4]).astype('float32')
|
||||
input_data["variances"] = np.ones((10, 8, 6, 4)).astype('float32')
|
||||
|
||||
attr["pre_nms_top_n"] = 100
|
||||
attr["post_nms_top_n"] = 60
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
|
||||
# test case 6
|
||||
input_name = "generate_proposals_v2_6"
|
||||
input_data["scores"] = np.random.rand(2, 6, 10, 8).astype('float32')
|
||||
input_data["bbox_deltas"] = np.random.rand(2, 24, 10, 8).astype('float32')
|
||||
input_data["im_shape"] = np.array([[1000, 1000]] * 2).astype('float32')
|
||||
input_data["anchors"] = np.reshape(np.arange(10 * 8 * 6 * 4),
|
||||
[10, 8, 6, 4]).astype('float32')
|
||||
input_data["variances"] = np.ones((10, 8, 6, 4)).astype('float32')
|
||||
|
||||
attr["pre_nms_top_n"] = 100
|
||||
attr["post_nms_top_n"] = 60
|
||||
|
||||
generate_proposals_v2(input_name, input_data, attr)
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "openvino/opsets/opset6.hpp"
|
||||
#include "openvino/opsets/opset7.hpp"
|
||||
#include "openvino/opsets/opset8.hpp"
|
||||
#include "openvino/opsets/opset9.hpp"
|
||||
|
||||
TEST(opset, opset1) {
|
||||
auto op = std::make_shared<ov::opset1::Parameter>();
|
||||
@@ -144,6 +145,22 @@ TEST(opset, opset8_dump) {
|
||||
ASSERT_EQ(167, opset.get_types_info().size());
|
||||
}
|
||||
|
||||
TEST(opset, opset9) {
|
||||
auto op = std::make_shared<ov::opset9::Parameter>();
|
||||
ASSERT_NE(nullptr, op);
|
||||
EXPECT_TRUE(ov::op::util::is_parameter(op));
|
||||
}
|
||||
|
||||
TEST(opset, opset9_dump) {
|
||||
const auto& opset = ov::get_opset9();
|
||||
std::cout << "All opset9 operations: ";
|
||||
for (const auto& t : opset.get_types_info()) {
|
||||
std::cout << t.name << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
ASSERT_EQ(172, opset.get_types_info().size());
|
||||
}
|
||||
|
||||
class MyOpOld : public ov::op::Op {
|
||||
public:
|
||||
static constexpr ov::DiscreteTypeInfo type_info{"MyOpOld", static_cast<uint64_t>(0)};
|
||||
|
||||
@@ -86,7 +86,7 @@ TEST(type_info, find_in_map) {
|
||||
test_map[b] = 1;
|
||||
test_map[c] = 1;
|
||||
|
||||
const auto& opset = ov::get_opset8();
|
||||
const auto& opset = ov::get_opset9();
|
||||
// Reserve memory to avoid reallocation and copy of strings
|
||||
// because type info uses pointers from the original memory
|
||||
vector_names.reserve(opset.size() * 3);
|
||||
|
||||
166
src/core/tests/type_prop/generate_proposals.cpp
Normal file
166
src/core/tests/type_prop/generate_proposals.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "util/type_prop.hpp"
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
using GenerateProposals = op::v9::GenerateProposals;
|
||||
using Attrs = op::v9::GenerateProposals::Attributes;
|
||||
|
||||
TEST(type_prop, generate_proposals) {
|
||||
Attrs attrs;
|
||||
attrs.min_size = 0.0f;
|
||||
attrs.nms_threshold = 0.699999988079071f;
|
||||
attrs.post_nms_count = 1000;
|
||||
attrs.pre_nms_count = 1000;
|
||||
|
||||
const auto dyn_dim = Dimension::dynamic();
|
||||
|
||||
auto im_info = std::make_shared<op::Parameter>(element::f32, Shape{1, 4});
|
||||
auto anchors = std::make_shared<op::Parameter>(element::f32, Shape{200, 336, 3, 4});
|
||||
auto deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 336});
|
||||
auto scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 200, 336});
|
||||
|
||||
auto proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs);
|
||||
|
||||
ASSERT_EQ(proposals->get_output_element_type(0), element::f32);
|
||||
ASSERT_EQ(proposals->get_output_element_type(1), element::f32);
|
||||
ASSERT_EQ(proposals->get_output_element_type(2), element::i64);
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(0), (PartialShape{dyn_dim, 4}));
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(1), (PartialShape{dyn_dim}));
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(2), (PartialShape{1}));
|
||||
|
||||
im_info = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(2));
|
||||
anchors = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(4));
|
||||
deltas = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(4));
|
||||
scores = std::make_shared<op::Parameter>(element::f32, PartialShape::dynamic(4));
|
||||
|
||||
proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs, element::i32);
|
||||
|
||||
ASSERT_EQ(proposals->get_output_element_type(0), element::f32);
|
||||
ASSERT_EQ(proposals->get_output_element_type(1), element::f32);
|
||||
ASSERT_EQ(proposals->get_output_element_type(2), element::i32);
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(0), (PartialShape{dyn_dim, 4}));
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(1), (PartialShape{dyn_dim}));
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(2), (PartialShape{dyn_dim}));
|
||||
|
||||
// assert throw
|
||||
im_info = std::make_shared<op::Parameter>(element::f32, Shape{1, 4});
|
||||
anchors = std::make_shared<op::Parameter>(element::f32, Shape{100, 336, 3, 4});
|
||||
deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 336});
|
||||
scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 200, 336});
|
||||
|
||||
ASSERT_THROW(proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs, element::i32),
|
||||
ngraph::CheckFailure)
|
||||
<< "GenerateProposals node was created with invalid data.";
|
||||
|
||||
im_info = std::make_shared<op::Parameter>(element::f32, Shape{1, 4});
|
||||
anchors = std::make_shared<op::Parameter>(element::f32, Shape{200, 336, 3, 4});
|
||||
deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 300});
|
||||
scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 200, 336});
|
||||
|
||||
ASSERT_THROW(proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs, element::i32),
|
||||
ngraph::CheckFailure)
|
||||
<< "GenerateProposals node was created with invalid data.";
|
||||
|
||||
im_info = std::make_shared<op::Parameter>(element::f32, Shape{1, 4});
|
||||
anchors = std::make_shared<op::Parameter>(element::f32, Shape{200, 336, 3, 4});
|
||||
deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 336});
|
||||
scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 4, 200, 336});
|
||||
|
||||
ASSERT_THROW(proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs, element::i32),
|
||||
ngraph::CheckFailure)
|
||||
<< "GenerateProposals node was created with invalid data.";
|
||||
|
||||
im_info = std::make_shared<op::Parameter>(element::f32, Shape{1, 2});
|
||||
anchors = std::make_shared<op::Parameter>(element::f32, Shape{200, 336, 3, 4});
|
||||
deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 336});
|
||||
scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 4, 200, 336});
|
||||
|
||||
ASSERT_THROW(proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs, element::i32),
|
||||
ngraph::CheckFailure)
|
||||
<< "GenerateProposals node was created with invalid data.";
|
||||
|
||||
im_info = std::make_shared<op::Parameter>(element::f32, Shape{2, 4});
|
||||
anchors = std::make_shared<op::Parameter>(element::f32, Shape{200, 336, 3, 4});
|
||||
deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 336});
|
||||
scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 4, 200, 336});
|
||||
|
||||
ASSERT_THROW(proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs, element::i32),
|
||||
ngraph::CheckFailure)
|
||||
<< "GenerateProposals node was created with invalid data.";
|
||||
}
|
||||
|
||||
TEST(type_prop, generate_proposals_dynamic) {
|
||||
struct ShapesAndAttrs {
|
||||
PartialShape im_info_shape;
|
||||
PartialShape anchors_shape;
|
||||
PartialShape deltas_shape;
|
||||
PartialShape scores_shape;
|
||||
size_t post_nms_count;
|
||||
};
|
||||
|
||||
const auto dyn_dim = Dimension::dynamic();
|
||||
const auto dyn_shape = PartialShape::dynamic();
|
||||
|
||||
std::vector<ShapesAndAttrs> shapes = {
|
||||
{{1, 3}, {200, 336, 3, 4}, {1, 12, 200, 336}, {1, 3, 200, 336}, 1000},
|
||||
{{2, 3}, {200, 336, 3, 4}, {2, 12, 200, 336}, dyn_shape, 500},
|
||||
{{1, 3}, {200, 336, 3, 4}, dyn_shape, {1, 3, 200, 336}, 700},
|
||||
{{2, 3}, {200, 336, 3, 4}, dyn_shape, dyn_shape, 300},
|
||||
{{1, 3}, dyn_shape, {1, 12, 200, 336}, {1, 3, 200, 336}, 200},
|
||||
{{2, 3}, dyn_shape, {2, 12, 200, 336}, dyn_shape, 40},
|
||||
{{1, 3}, dyn_shape, dyn_shape, {1, 3, 200, 336}, 70},
|
||||
{{2, 3}, dyn_shape, dyn_shape, dyn_shape, 60},
|
||||
{dyn_shape, {200, 336, 3, 4}, {1, 12, 200, 336}, {1, 3, 200, 336}, 500},
|
||||
{dyn_shape, {200, 336, 3, 4}, {2, 12, 200, 336}, dyn_shape, 400},
|
||||
{dyn_shape, {200, 336, 3, 4}, dyn_shape, {1, 3, 200, 336}, 350},
|
||||
{dyn_shape, {200, 336, 3, 4}, dyn_shape, dyn_shape, 440},
|
||||
{dyn_shape, dyn_shape, {1, 12, 200, 336}, {1, 3, 200, 336}, 315},
|
||||
{dyn_shape, dyn_shape, {2, 12, 200, 336}, dyn_shape, 130},
|
||||
{dyn_shape, dyn_shape, dyn_shape, {1, 3, 200, 336}, 1000},
|
||||
{dyn_shape, dyn_shape, dyn_shape, dyn_shape, 700},
|
||||
{{1, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {1, 12, 200, 336}, {1, 3, 200, 336}, 540},
|
||||
{{1, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {1, 12, 200, 336}, {dyn_dim, dyn_dim, 200, 336}, 600},
|
||||
{{2, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {dyn_dim, dyn_dim, 200, 336}, {2, 3, 200, 336}, 75},
|
||||
{{1, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {dyn_dim, dyn_dim, 200, 336}, {dyn_dim, dyn_dim, 200, 336}, 80},
|
||||
{{1, 3}, {200, 336, 3, 4}, {1, 12, 200, dyn_dim}, {1, 3, 200, dyn_dim}, 430},
|
||||
{{2, 3}, {200, 336, 3, 4}, {2, 12, dyn_dim, 336}, {2, 3, dyn_dim, 336}, 180},
|
||||
{{1, 3}, {200, 336, 3, 4}, {1, 12, dyn_dim, dyn_dim}, {1, 3, dyn_dim, dyn_dim}, 170},
|
||||
{{1, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {1, 12, 200, dyn_dim}, {1, 3, 200, dyn_dim}, 200},
|
||||
{{2, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {2, 12, dyn_dim, 336}, {2, 3, dyn_dim, 336}, 800},
|
||||
{{1, 3}, {dyn_dim, dyn_dim, dyn_dim, 4}, {1, 12, dyn_dim, dyn_dim}, {1, 3, dyn_dim, dyn_dim}, 560},
|
||||
};
|
||||
|
||||
for (const auto& s : shapes) {
|
||||
Attrs attrs;
|
||||
attrs.min_size = 0.0f;
|
||||
attrs.nms_threshold = 0.699999988079071f;
|
||||
attrs.post_nms_count = static_cast<int64_t>(s.post_nms_count);
|
||||
attrs.pre_nms_count = 1000;
|
||||
|
||||
auto im_info = std::make_shared<op::Parameter>(element::f32, s.im_info_shape);
|
||||
auto anchors = std::make_shared<op::Parameter>(element::f32, s.anchors_shape);
|
||||
auto deltas = std::make_shared<op::Parameter>(element::f32, s.deltas_shape);
|
||||
auto scores = std::make_shared<op::Parameter>(element::f32, s.scores_shape);
|
||||
|
||||
auto proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs);
|
||||
|
||||
ASSERT_EQ(proposals->get_output_element_type(0), element::f32);
|
||||
ASSERT_EQ(proposals->get_output_element_type(1), element::f32);
|
||||
ASSERT_EQ(proposals->get_output_element_type(2), element::i64);
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(0), (PartialShape{dyn_dim, 4}));
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(1), (PartialShape{dyn_dim}));
|
||||
if (s.im_info_shape.rank().is_static()) {
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(2), PartialShape{s.im_info_shape[0]});
|
||||
} else {
|
||||
EXPECT_EQ(proposals->get_output_partial_shape(2), PartialShape::dynamic(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/core/tests/visitors/op/generate_proposals.cpp
Normal file
53
src/core/tests/visitors/op/generate_proposals.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
#include "ngraph/opsets/opset9.hpp"
|
||||
#include "util/visitor.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
using ngraph::test::NodeBuilder;
|
||||
using ngraph::test::ValueMap;
|
||||
|
||||
using GenerateProposals = opset9::GenerateProposals;
|
||||
using Attrs = opset9::GenerateProposals::Attributes;
|
||||
|
||||
TEST(attributes, generate_proposals) {
|
||||
NodeBuilder::get_ops().register_factory<GenerateProposals>();
|
||||
|
||||
Attrs attrs;
|
||||
attrs.min_size = 0.0f;
|
||||
attrs.nms_threshold = 0.699999988079071f;
|
||||
attrs.post_nms_count = 1000;
|
||||
attrs.pre_nms_count = 1000;
|
||||
attrs.normalized = true;
|
||||
attrs.nms_eta = 1.0f;
|
||||
|
||||
auto im_info = std::make_shared<op::Parameter>(element::f32, Shape{1, 4});
|
||||
auto anchors = std::make_shared<op::Parameter>(element::f32, Shape{200, 336, 3, 4});
|
||||
auto deltas = std::make_shared<op::Parameter>(element::f32, Shape{1, 12, 200, 336});
|
||||
auto scores = std::make_shared<op::Parameter>(element::f32, Shape{1, 3, 200, 336});
|
||||
|
||||
auto proposals = std::make_shared<GenerateProposals>(im_info, anchors, deltas, scores, attrs);
|
||||
|
||||
NodeBuilder builder(proposals);
|
||||
|
||||
auto g_proposals = ov::as_type_ptr<GenerateProposals>(builder.create());
|
||||
|
||||
const auto expected_attr_count = 7;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
|
||||
EXPECT_EQ(g_proposals->get_attrs().min_size, proposals->get_attrs().min_size);
|
||||
EXPECT_EQ(g_proposals->get_attrs().nms_threshold, proposals->get_attrs().nms_threshold);
|
||||
EXPECT_EQ(g_proposals->get_attrs().post_nms_count, proposals->get_attrs().post_nms_count);
|
||||
EXPECT_EQ(g_proposals->get_attrs().pre_nms_count, proposals->get_attrs().pre_nms_count);
|
||||
EXPECT_EQ(g_proposals->get_attrs().normalized, proposals->get_attrs().normalized);
|
||||
EXPECT_EQ(g_proposals->get_attrs().nms_eta, proposals->get_attrs().nms_eta);
|
||||
EXPECT_EQ(g_proposals->get_roi_num_type(), proposals->get_roi_num_type());
|
||||
}
|
||||
@@ -37,8 +37,10 @@ inline const ov::OpSet& get_opset_by_name(const std::string& opset_name) {
|
||||
return ov::get_opset7();
|
||||
} else if (opset_name == "opset8") {
|
||||
return ov::get_opset8();
|
||||
} else if (opset_name == "opset9") {
|
||||
return ov::get_opset9();
|
||||
} else if (opset_name.empty() || opset_name == "latest") {
|
||||
return ov::get_opset8();
|
||||
return ov::get_opset9();
|
||||
} else {
|
||||
FRONT_END_GENERAL_CHECK(false, "Unsupported opset name: ", opset_name);
|
||||
}
|
||||
|
||||
@@ -214,6 +214,7 @@ public:
|
||||
m_opsets["opset6"] = ngraph::get_opset6();
|
||||
m_opsets["opset7"] = ngraph::get_opset7();
|
||||
m_opsets["opset8"] = ngraph::get_opset8();
|
||||
m_opsets["opset9"] = ngraph::get_opset9();
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> convert();
|
||||
|
||||
94
src/frontends/paddle/src/op/generate_proposals_v2.cpp
Normal file
94
src/frontends/paddle/src/op/generate_proposals_v2.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "default_opset.hpp"
|
||||
#include "openvino/frontend/paddle/node_context.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace frontend {
|
||||
namespace paddle {
|
||||
namespace op {
|
||||
|
||||
NamedOutputs generate_proposals_v2(const NodeContext& node) {
|
||||
auto bbox_deltas = node.get_input("BboxDeltas"); // [N,4 * A,H,W]
|
||||
auto im_shape = node.get_input("ImShape"); // [N, 2]
|
||||
auto scores = node.get_input("Scores"); // [N,A,H,W]
|
||||
auto anchors = node.get_input("Anchors"); // [H,W,A,4] or [H * W * A, 4]
|
||||
Output<Node> variances;
|
||||
if (node.has_input("Variances"))
|
||||
variances = node.get_input("Variances"); // [H,W,A,4] or [H * W * A, 4]
|
||||
|
||||
// attribute
|
||||
ov::op::v9::GenerateProposals::Attributes attrs;
|
||||
float min_size = node.get_attribute<float>("min_size", 0.1);
|
||||
attrs.min_size = min_size < 1.0f ? 1.0f : min_size;
|
||||
attrs.nms_threshold = node.get_attribute<float>("nms_thresh", 0.5);
|
||||
attrs.pre_nms_count = node.get_attribute<int>("pre_nms_topN", 6000);
|
||||
attrs.post_nms_count = node.get_attribute<int>("post_nms_topN", 1000);
|
||||
attrs.nms_eta = node.get_attribute<float>("eta", 1.0);
|
||||
PADDLE_OP_CHECK(node, (attrs.nms_eta == 1.0), "Only support case of eta == 1.0 currently");
|
||||
attrs.normalized = !node.get_attribute<bool>("pixel_offset", true);
|
||||
|
||||
// reshape anchors from to [H, W, A, 4] if it is [H * W * A, 4]
|
||||
auto scores_shape = std::make_shared<default_opset::ShapeOf>(scores);
|
||||
auto gather_indices = default_opset::Constant::create<int64_t>(ov::element::i64, {3}, {2, 3, 1});
|
||||
auto gather_axis = default_opset::Constant::create<int64_t>(ov::element::i64, {}, {0});
|
||||
auto partial_anchors_shape = std::make_shared<default_opset::Gather>(scores_shape, gather_indices, gather_axis);
|
||||
auto const_4 = default_opset::Constant::create<int64_t>(ov::element::i64, {1}, {4});
|
||||
auto anchors_shape = std::make_shared<default_opset::Concat>(OutputVector{partial_anchors_shape, const_4}, 0);
|
||||
auto reshaped_anchors = std::make_shared<default_opset::Reshape>(anchors, anchors_shape, true);
|
||||
|
||||
auto variances_bbox_deltas = bbox_deltas;
|
||||
if (variances.get_node()) {
|
||||
// Reshape variances to [H, W, A, 4] if it is [H * W * A, 4]
|
||||
auto dim4_variances = std::make_shared<default_opset::Reshape>(variances, anchors_shape, true);
|
||||
// Transpose variances from [H, W, A, 4] to [A*4, H, W]
|
||||
auto reshape_pattern = default_opset::Constant::create<int64_t>(ov::element::i64, {3}, {0, 0, -1});
|
||||
auto reshaped_variances = std::make_shared<default_opset::Reshape>(dim4_variances, reshape_pattern, true);
|
||||
auto transpose_order = default_opset::Constant::create(ov::element::i64, {3}, {2, 0, 1});
|
||||
auto transposed_variances = std::make_shared<default_opset::Transpose>(reshaped_variances, transpose_order);
|
||||
// auto transposed_variances = default_opset::Constant::create(ov::element::f32, {}, {2.0});
|
||||
variances_bbox_deltas = std::make_shared<default_opset::Multiply>(bbox_deltas, transposed_variances);
|
||||
}
|
||||
|
||||
// generate im_info from im_scale
|
||||
auto pads_begin = default_opset::Constant::create<int64_t>(ov::element::i64, {2}, {0, 0});
|
||||
auto pads_end = default_opset::Constant::create<int64_t>(ov::element::i64, {2}, {0, 1});
|
||||
auto im_scale = default_opset::Constant::create(ov::element::f32, {}, {1.0});
|
||||
auto im_info =
|
||||
std::make_shared<default_opset::Pad>(im_shape, pads_begin, pads_end, im_scale, ov::op::PadMode::CONSTANT);
|
||||
|
||||
// input:
|
||||
// 1. im_info: [N, 3] or [N, 4]
|
||||
// 2. anchors: [H, W, A, 4]
|
||||
// 3. deltas: [N, A*4, H, W]
|
||||
// 4. scores: [N, A, H, W]
|
||||
// output:
|
||||
// 1. rois: [proposals_num, 4]
|
||||
// 2. scores: [proposals_num]
|
||||
// 3. roi_num: [N]
|
||||
auto proposal = std::make_shared<ov::op::v9::GenerateProposals>(im_info,
|
||||
reshaped_anchors,
|
||||
variances_bbox_deltas,
|
||||
scores,
|
||||
attrs);
|
||||
proposal->set_roi_num_type(ov::element::i32);
|
||||
|
||||
auto unsqueeze_scalar = default_opset::Constant::create(ov::element::i64, {}, {1});
|
||||
auto probs = std::make_shared<default_opset::Unsqueeze>(proposal->output(1), unsqueeze_scalar);
|
||||
|
||||
// output
|
||||
NamedOutputs named_outputs;
|
||||
named_outputs["RpnRois"] = OutputVector{proposal->output(0)};
|
||||
named_outputs["RpnRoiProbs"] = OutputVector{probs->output(0)};
|
||||
named_outputs["RpnRoisNum"] = OutputVector{proposal->output(2)};
|
||||
|
||||
return named_outputs;
|
||||
}
|
||||
} // namespace op
|
||||
} // namespace paddle
|
||||
} // namespace frontend
|
||||
} // namespace ov
|
||||
@@ -90,6 +90,7 @@ OP_CONVERTER(trilinear_interp_v2);
|
||||
OP_CONVERTER(unsqueeze);
|
||||
OP_CONVERTER(where);
|
||||
OP_CONVERTER(yolo_box);
|
||||
OP_CONVERTER(generate_proposals_v2);
|
||||
} // namespace op
|
||||
std::map<std::string, CreatorFunction> get_supported_ops() {
|
||||
return {{"arg_max", op::argmax},
|
||||
@@ -181,7 +182,8 @@ std::map<std::string, CreatorFunction> get_supported_ops() {
|
||||
{"trilinear_interp_v2", op::trilinear_interp_v2},
|
||||
{"unsqueeze2", op::unsqueeze},
|
||||
{"where", op::where},
|
||||
{"yolo_box", op::yolo_box}};
|
||||
{"yolo_box", op::yolo_box},
|
||||
{"generate_proposals_v2", op::generate_proposals_v2}};
|
||||
};
|
||||
|
||||
} // namespace paddle
|
||||
|
||||
@@ -45,7 +45,7 @@ inline void addInputOutput(cnpy::NpyArray& npy_array, test::TestCase& test_case,
|
||||
if (is_input)
|
||||
test_case.add_input(data);
|
||||
else
|
||||
test_case.add_expected_output(data);
|
||||
test_case.add_expected_output(npy_array.shape, data);
|
||||
}
|
||||
|
||||
static bool ends_with(std::string const& value, std::string const& ending) {
|
||||
|
||||
@@ -182,6 +182,7 @@ const InferenceEngine::details::caseless_unordered_map<std::string, Type> type_t
|
||||
{ "ExperimentalDetectronROIFeatureExtractor", Type::ExperimentalDetectronROIFeatureExtractor},
|
||||
{ "ExperimentalDetectronPriorGridGenerator", Type::ExperimentalDetectronPriorGridGenerator},
|
||||
{ "ExperimentalDetectronGenerateProposalsSingleImage", Type::ExperimentalDetectronGenerateProposalsSingleImage},
|
||||
{ "GenerateProposals", Type::GenerateProposals},
|
||||
{ "ExtractImagePatches", Type::ExtractImagePatches},
|
||||
{ "NonMaxSuppression", Type::NonMaxSuppression},
|
||||
{ "NonMaxSuppressionIEInternal", Type::NonMaxSuppression},
|
||||
@@ -364,6 +365,8 @@ std::string NameFromType(const Type type) {
|
||||
return "ExperimentalDetectronPriorGridGenerator";
|
||||
case Type::ExperimentalDetectronGenerateProposalsSingleImage:
|
||||
return "ExperimentalDetectronGenerateProposalsSingleImage";
|
||||
case Type::GenerateProposals:
|
||||
return "GenerateProposals";
|
||||
case Type::ExtractImagePatches:
|
||||
return "ExtractImagePatches";
|
||||
case Type::NonMaxSuppression:
|
||||
|
||||
@@ -98,6 +98,7 @@ enum class Type {
|
||||
ExperimentalDetectronROIFeatureExtractor,
|
||||
ExperimentalDetectronPriorGridGenerator,
|
||||
ExperimentalDetectronGenerateProposalsSingleImage,
|
||||
GenerateProposals,
|
||||
ExtractImagePatches,
|
||||
NonMaxSuppression,
|
||||
MatrixNms,
|
||||
|
||||
483
src/plugins/intel_cpu/src/nodes/generate_proposals.cpp
Normal file
483
src/plugins/intel_cpu/src/nodes/generate_proposals.cpp
Normal file
@@ -0,0 +1,483 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(HAVE_AVX2)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
#include <ngraph/op/generate_proposals.hpp>
|
||||
#include "ie_parallel.hpp"
|
||||
#include "common/cpu_memcpy.h"
|
||||
#include "generate_proposals.h"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
namespace {
|
||||
|
||||
using namespace InferenceEngine;
|
||||
|
||||
struct Indexer4d {
|
||||
int dim3_;
|
||||
int dim23_;
|
||||
int dim123_;
|
||||
|
||||
explicit Indexer4d(int dim0, int dim1, int dim2, int dim3):
|
||||
dim3_(dim3), dim23_(dim2 * dim3), dim123_(dim1 * dim2 * dim3) {
|
||||
(void)dim0;
|
||||
}
|
||||
|
||||
int operator()(int i, int j, int k, int n) const {
|
||||
return i * dim123_ + j * dim23_ + k * dim3_ + n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void refine_anchors(const float* deltas, const float* scores, const float* anchors,
|
||||
float* proposals, const int anchors_num, const int bottom_H,
|
||||
const int bottom_W, const float img_H, const float img_W,
|
||||
const float min_box_H, const float min_box_W,
|
||||
const float max_delta_log_wh,
|
||||
float coordinates_offset) {
|
||||
Indexer4d delta_idx(anchors_num, 4, bottom_H, bottom_W);
|
||||
Indexer4d score_idx(anchors_num, 1, bottom_H, bottom_W);
|
||||
Indexer4d proposal_idx(bottom_H, bottom_W, anchors_num, 6);
|
||||
Indexer4d anchor_idx(bottom_H, bottom_W, anchors_num, 4);
|
||||
|
||||
parallel_for2d(bottom_H, bottom_W, [&](int h, int w) {
|
||||
for (int anchor = 0; anchor < anchors_num; ++anchor) {
|
||||
int a_idx = anchor_idx(h, w, anchor, 0);
|
||||
float x0 = anchors[a_idx + 0];
|
||||
float y0 = anchors[a_idx + 1];
|
||||
float x1 = anchors[a_idx + 2];
|
||||
float y1 = anchors[a_idx + 3];
|
||||
|
||||
const float dx = deltas[delta_idx(anchor, 0, h, w)];
|
||||
const float dy = deltas[delta_idx(anchor, 1, h, w)];
|
||||
const float d_log_w = deltas[delta_idx(anchor, 2, h, w)];
|
||||
const float d_log_h = deltas[delta_idx(anchor, 3, h, w)];
|
||||
|
||||
const float score = scores[score_idx(anchor, 0, h, w)];
|
||||
|
||||
// width & height of box
|
||||
const float ww = x1 - x0 + coordinates_offset;
|
||||
const float hh = y1 - y0 + coordinates_offset;
|
||||
// center location of box
|
||||
const float ctr_x = x0 + 0.5f * ww;
|
||||
const float ctr_y = y0 + 0.5f * hh;
|
||||
|
||||
// new center location according to deltas (dx, dy)
|
||||
const float pred_ctr_x = dx * ww + ctr_x;
|
||||
const float pred_ctr_y = dy * hh + ctr_y;
|
||||
// new width & height according to deltas d(log w), d(log h)
|
||||
const float pred_w = std::exp(std::min(d_log_w, max_delta_log_wh)) * ww;
|
||||
const float pred_h = std::exp(std::min(d_log_h, max_delta_log_wh)) * hh;
|
||||
|
||||
// update upper-left corner location
|
||||
x0 = pred_ctr_x - 0.5f * pred_w;
|
||||
y0 = pred_ctr_y - 0.5f * pred_h;
|
||||
// update lower-right corner location
|
||||
x1 = pred_ctr_x + 0.5f * pred_w - coordinates_offset;
|
||||
y1 = pred_ctr_y + 0.5f * pred_h - coordinates_offset;
|
||||
|
||||
// adjust new corner locations to be within the image region,
|
||||
x0 = std::max<float>(0.0f, std::min<float>(x0, img_W - coordinates_offset));
|
||||
y0 = std::max<float>(0.0f, std::min<float>(y0, img_H - coordinates_offset));
|
||||
x1 = std::max<float>(0.0f, std::min<float>(x1, img_W - coordinates_offset));
|
||||
y1 = std::max<float>(0.0f, std::min<float>(y1, img_H - coordinates_offset));
|
||||
|
||||
// recompute new width & height
|
||||
const float box_w = x1 - x0 + coordinates_offset;
|
||||
const float box_h = y1 - y0 + coordinates_offset;
|
||||
|
||||
int p_idx = proposal_idx(h, w, anchor, 0);
|
||||
proposals[p_idx + 0] = x0;
|
||||
proposals[p_idx + 1] = y0;
|
||||
proposals[p_idx + 2] = x1;
|
||||
proposals[p_idx + 3] = y1;
|
||||
proposals[p_idx + 4] = score;
|
||||
proposals[p_idx + 5] = (min_box_W <= box_w) * (min_box_H <= box_h) * 1.0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void unpack_boxes(const float* p_proposals, float* unpacked_boxes, int* is_dead, int pre_nms_topn) {
|
||||
parallel_for(pre_nms_topn, [&](size_t i) {
|
||||
unpacked_boxes[0*pre_nms_topn + i] = p_proposals[6*i + 0];
|
||||
unpacked_boxes[1*pre_nms_topn + i] = p_proposals[6*i + 1];
|
||||
unpacked_boxes[2*pre_nms_topn + i] = p_proposals[6*i + 2];
|
||||
unpacked_boxes[3*pre_nms_topn + i] = p_proposals[6*i + 3];
|
||||
unpacked_boxes[4*pre_nms_topn + i] = p_proposals[6*i + 4];
|
||||
is_dead[i] = (p_proposals[6*i + 5] == 1.0) ? 0 : 1;
|
||||
});
|
||||
}
|
||||
|
||||
void nms_cpu(const int num_boxes, int is_dead[],
|
||||
const float* boxes, int index_out[], size_t* const num_out,
|
||||
const int base_index, const float nms_thresh, const int max_num_out,
|
||||
float coordinates_offset) {
|
||||
const int num_proposals = num_boxes;
|
||||
size_t count = 0;
|
||||
|
||||
const float* x0 = boxes + 0 * num_proposals;
|
||||
const float* y0 = boxes + 1 * num_proposals;
|
||||
const float* x1 = boxes + 2 * num_proposals;
|
||||
const float* y1 = boxes + 3 * num_proposals;
|
||||
|
||||
#if defined(HAVE_AVX2)
|
||||
__m256 vc_fone = _mm256_set1_ps(coordinates_offset);
|
||||
__m256i vc_ione = _mm256_set1_epi32(1);
|
||||
__m256 vc_zero = _mm256_set1_ps(0.0f);
|
||||
|
||||
__m256 vc_nms_thresh = _mm256_set1_ps(nms_thresh);
|
||||
#endif
|
||||
|
||||
for (int box = 0; box < num_boxes; ++box) {
|
||||
if (is_dead[box])
|
||||
continue;
|
||||
|
||||
index_out[count++] = base_index + box;
|
||||
if (count == max_num_out)
|
||||
break;
|
||||
|
||||
int tail = box + 1;
|
||||
|
||||
#if defined(HAVE_AVX2)
|
||||
__m256 vx0i = _mm256_set1_ps(x0[box]);
|
||||
__m256 vy0i = _mm256_set1_ps(y0[box]);
|
||||
__m256 vx1i = _mm256_set1_ps(x1[box]);
|
||||
__m256 vy1i = _mm256_set1_ps(y1[box]);
|
||||
|
||||
__m256 vA_width = _mm256_sub_ps(vx1i, vx0i);
|
||||
__m256 vA_height = _mm256_sub_ps(vy1i, vy0i);
|
||||
__m256 vA_area = _mm256_mul_ps(_mm256_add_ps(vA_width, vc_fone), _mm256_add_ps(vA_height, vc_fone));
|
||||
|
||||
for (; tail <= num_boxes - 8; tail += 8) {
|
||||
__m256i *pdst = reinterpret_cast<__m256i*>(is_dead + tail);
|
||||
__m256i vdst = _mm256_loadu_si256(pdst);
|
||||
|
||||
__m256 vx0j = _mm256_loadu_ps(x0 + tail);
|
||||
__m256 vy0j = _mm256_loadu_ps(y0 + tail);
|
||||
__m256 vx1j = _mm256_loadu_ps(x1 + tail);
|
||||
__m256 vy1j = _mm256_loadu_ps(y1 + tail);
|
||||
|
||||
__m256 vx0 = _mm256_max_ps(vx0i, vx0j);
|
||||
__m256 vy0 = _mm256_max_ps(vy0i, vy0j);
|
||||
__m256 vx1 = _mm256_min_ps(vx1i, vx1j);
|
||||
__m256 vy1 = _mm256_min_ps(vy1i, vy1j);
|
||||
|
||||
__m256 vwidth = _mm256_add_ps(_mm256_sub_ps(vx1, vx0), vc_fone);
|
||||
__m256 vheight = _mm256_add_ps(_mm256_sub_ps(vy1, vy0), vc_fone);
|
||||
__m256 varea = _mm256_mul_ps(_mm256_max_ps(vc_zero, vwidth), _mm256_max_ps(vc_zero, vheight));
|
||||
|
||||
__m256 vB_width = _mm256_sub_ps(vx1j, vx0j);
|
||||
__m256 vB_height = _mm256_sub_ps(vy1j, vy0j);
|
||||
__m256 vB_area = _mm256_mul_ps(_mm256_add_ps(vB_width, vc_fone), _mm256_add_ps(vB_height, vc_fone));
|
||||
|
||||
__m256 vdivisor = _mm256_sub_ps(_mm256_add_ps(vA_area, vB_area), varea);
|
||||
__m256 vintersection_area = _mm256_div_ps(varea, vdivisor);
|
||||
|
||||
__m256 vcmp_0 = _mm256_cmp_ps(vx0i, vx1j, _CMP_LE_OS);
|
||||
__m256 vcmp_1 = _mm256_cmp_ps(vy0i, vy1j, _CMP_LE_OS);
|
||||
__m256 vcmp_2 = _mm256_cmp_ps(vx0j, vx1i, _CMP_LE_OS);
|
||||
__m256 vcmp_3 = _mm256_cmp_ps(vy0j, vy1i, _CMP_LE_OS);
|
||||
__m256 vcmp_4 = _mm256_cmp_ps(vc_nms_thresh, vintersection_area, _CMP_LT_OS);
|
||||
|
||||
vcmp_0 = _mm256_and_ps(vcmp_0, vcmp_1);
|
||||
vcmp_2 = _mm256_and_ps(vcmp_2, vcmp_3);
|
||||
vcmp_4 = _mm256_and_ps(vcmp_4, vcmp_0);
|
||||
vcmp_4 = _mm256_and_ps(vcmp_4, vcmp_2);
|
||||
|
||||
_mm256_storeu_si256(pdst, _mm256_blendv_epi8(vdst, vc_ione, _mm256_castps_si256(vcmp_4)));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; tail < num_boxes; ++tail) {
|
||||
float res = 0.0f;
|
||||
|
||||
const float x0i = x0[box];
|
||||
const float y0i = y0[box];
|
||||
const float x1i = x1[box];
|
||||
const float y1i = y1[box];
|
||||
|
||||
const float x0j = x0[tail];
|
||||
const float y0j = y0[tail];
|
||||
const float x1j = x1[tail];
|
||||
const float y1j = y1[tail];
|
||||
|
||||
if (x0i <= x1j && y0i <= y1j && x0j <= x1i && y0j <= y1i) {
|
||||
// overlapped region (= box)
|
||||
const float x0 = std::max<float>(x0i, x0j);
|
||||
const float y0 = std::max<float>(y0i, y0j);
|
||||
const float x1 = std::min<float>(x1i, x1j);
|
||||
const float y1 = std::min<float>(y1i, y1j);
|
||||
|
||||
// intersection area
|
||||
const float width = std::max<float>(0.0f, x1 - x0 + coordinates_offset);
|
||||
const float height = std::max<float>(0.0f, y1 - y0 + coordinates_offset);
|
||||
const float area = width * height;
|
||||
|
||||
// area of A, B
|
||||
const float A_area = (x1i - x0i + coordinates_offset) * (y1i - y0i + coordinates_offset);
|
||||
const float B_area = (x1j - x0j + coordinates_offset) * (y1j - y0j + coordinates_offset);
|
||||
|
||||
// IoU
|
||||
res = area / (A_area + B_area - area);
|
||||
}
|
||||
|
||||
if (nms_thresh < res)
|
||||
is_dead[tail] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
*num_out = count;
|
||||
}
|
||||
|
||||
|
||||
void fill_output_blobs(const float* proposals, const int* roi_indices,
|
||||
float* rois, float* scores, uint8_t* roi_num,
|
||||
const int num_proposals, const size_t num_rois, const int post_nms_topn,
|
||||
Precision roi_num_type) {
|
||||
const float *src_x0 = proposals + 0 * num_proposals;
|
||||
const float *src_y0 = proposals + 1 * num_proposals;
|
||||
const float *src_x1 = proposals + 2 * num_proposals;
|
||||
const float *src_y1 = proposals + 3 * num_proposals;
|
||||
const float *src_score = proposals + 4 * num_proposals;
|
||||
|
||||
parallel_for(num_rois, [&](size_t i) {
|
||||
int index = roi_indices[i];
|
||||
rois[i * 4 + 0] = src_x0[index];
|
||||
rois[i * 4 + 1] = src_y0[index];
|
||||
rois[i * 4 + 2] = src_x1[index];
|
||||
rois[i * 4 + 3] = src_y1[index];
|
||||
scores[i] = src_score[index];
|
||||
});
|
||||
|
||||
if (roi_num_type == Precision::I32) {
|
||||
int32_t num = static_cast<int32_t>(num_rois);
|
||||
memcpy(roi_num, &num, sizeof(int32_t));
|
||||
} else if (roi_num_type == Precision::I64) {
|
||||
int64_t num = static_cast<int64_t>(num_rois);
|
||||
memcpy(roi_num, &num, sizeof(int64_t));
|
||||
} else {
|
||||
IE_THROW() << "Incorrect element type of roi_num!";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool GenerateProposals::isSupportedOperation
|
||||
(const std::shared_ptr<const ngraph::Node>& op, std::string& errorMessage) noexcept {
|
||||
try {
|
||||
if (!ngraph::as_type_ptr<const ngraph::op::v9::GenerateProposals>(op)) {
|
||||
errorMessage = "Node is not an instance of the Proposal from the operations set v0.";
|
||||
return false;
|
||||
}
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GenerateProposals::GenerateProposals
|
||||
(const std::shared_ptr<ngraph::Node>& op, const dnnl::engine& eng,
|
||||
WeightsSharing::Ptr &cache) : Node(op, eng, cache) {
|
||||
std::string errorMessage;
|
||||
if (!isSupportedOperation(op, errorMessage)) {
|
||||
IE_THROW(NotImplemented) << errorMessage;
|
||||
}
|
||||
|
||||
if (auto proposalOp = ngraph::as_type_ptr<const ngraph::op::v9::GenerateProposals>(op)) {
|
||||
auto proposalAttrs = proposalOp->get_attrs();
|
||||
|
||||
min_size_ = proposalAttrs.min_size;
|
||||
nms_thresh_ = proposalAttrs.nms_threshold;
|
||||
pre_nms_topn_ = proposalAttrs.pre_nms_count;
|
||||
post_nms_topn_ = proposalAttrs.post_nms_count;
|
||||
coordinates_offset_ = proposalAttrs.normalized ? 0 : 1.0;
|
||||
}
|
||||
|
||||
roi_indices_.resize(post_nms_topn_);
|
||||
}
|
||||
|
||||
void GenerateProposals::initSupportedPrimitiveDescriptors() {
|
||||
if (!supportedPrimitiveDescriptors.empty())
|
||||
return;
|
||||
|
||||
auto roiNumPrecision = getOriginalOutputPrecisionAtPort(OUTPUT_ROI_NUM);
|
||||
addSupportedPrimDesc({{LayoutType::ncsp, Precision::FP32},
|
||||
{LayoutType::ncsp, Precision::FP32},
|
||||
{LayoutType::ncsp, Precision::FP32},
|
||||
{LayoutType::ncsp, Precision::FP32}},
|
||||
{{LayoutType::ncsp, Precision::FP32},
|
||||
{LayoutType::ncsp, Precision::FP32},
|
||||
{LayoutType::ncsp, roiNumPrecision}},
|
||||
impl_desc_type::ref_any);
|
||||
}
|
||||
|
||||
void GenerateProposals::executeDynamicImpl(dnnl::stream strm) {
|
||||
execute(strm);
|
||||
}
|
||||
|
||||
void GenerateProposals::execute(dnnl::stream strm) {
|
||||
try {
|
||||
if (inputShapes.size() != 4 || outputShapes.size() != 3) {
|
||||
IE_THROW() << "Incorrect number of input or output edges!";
|
||||
}
|
||||
|
||||
size_t anchor_dims_size = 1;
|
||||
const auto &anchorDims = getParentEdgeAt(INPUT_ANCHORS)->getMemory().getStaticDims();
|
||||
for (size_t i = 0; i < anchorDims.size(); i++) {
|
||||
anchor_dims_size *= anchorDims[i];
|
||||
}
|
||||
|
||||
size_t deltas_dims_size = 1;
|
||||
const auto &deltaDims = getParentEdgeAt(INPUT_DELTAS)->getMemory().getStaticDims();
|
||||
for (size_t i = 1; i < deltaDims.size(); i++) {
|
||||
deltas_dims_size *= deltaDims[i];
|
||||
}
|
||||
if (anchor_dims_size != deltas_dims_size)
|
||||
IE_THROW() << "'Anchors' blob size for GenerateProposals is incompatible with 'deltas' blob size!";
|
||||
|
||||
size_t score_dims_size = 1;
|
||||
const auto &scoreDims = getParentEdgeAt(INPUT_SCORES)->getMemory().getStaticDims();
|
||||
for (size_t i = 1; i < scoreDims.size(); i++) {
|
||||
score_dims_size *= scoreDims[i];
|
||||
}
|
||||
if (deltas_dims_size != (4 * score_dims_size))
|
||||
IE_THROW() << "'Deltas' blob size for GenerateProposals is incompatible with 'scores' blob size!";
|
||||
|
||||
size_t im_info_dims_size = 1;
|
||||
const auto &infoDims = getParentEdgeAt(INPUT_IM_INFO)->getMemory().getStaticDims();
|
||||
for (size_t i = 1; i < infoDims.size(); i++) {
|
||||
im_info_dims_size *= infoDims[i];
|
||||
}
|
||||
|
||||
// Prepare memory
|
||||
const float *p_deltas_item = reinterpret_cast<const float *>(getParentEdgeAt(INPUT_DELTAS)->getMemoryPtr()->GetPtr());
|
||||
const float *p_scores_item = reinterpret_cast<const float *>(getParentEdgeAt(INPUT_SCORES)->getMemoryPtr()->GetPtr());
|
||||
const float *p_anchors_item = reinterpret_cast<const float *>(getParentEdgeAt(INPUT_ANCHORS)->getMemoryPtr()->GetPtr());
|
||||
const float *p_img_info_cpu = reinterpret_cast<const float *>(getParentEdgeAt(INPUT_IM_INFO)->getMemoryPtr()->GetPtr());
|
||||
|
||||
const int anchors_num = scoreDims[1];
|
||||
|
||||
// bottom shape: N x (num_anchors) x H x W
|
||||
const int bottom_H = deltaDims[2];
|
||||
const int bottom_W = deltaDims[3];
|
||||
|
||||
// number of all proposals = num_anchors * H * W
|
||||
const int num_proposals = anchors_num * bottom_H * bottom_W;
|
||||
|
||||
// number of top-n proposals before NMS
|
||||
const int pre_nms_topn = std::min<int>(num_proposals, pre_nms_topn_);
|
||||
|
||||
// number of final RoIs
|
||||
size_t num_rois = 0;
|
||||
|
||||
// enumerate all proposals
|
||||
// num_proposals = num_anchors * H * W
|
||||
// (x1, y1, x2, y2, score) for each proposal
|
||||
// NOTE: for bottom, only foreground scores are passed
|
||||
struct ProposalBox {
|
||||
float x0;
|
||||
float y0;
|
||||
float x1;
|
||||
float y1;
|
||||
float score;
|
||||
float keep;
|
||||
};
|
||||
std::vector<ProposalBox> proposals_(num_proposals);
|
||||
std::vector<float> unpacked_boxes(5 * pre_nms_topn);
|
||||
std::vector<int> is_dead(pre_nms_topn);
|
||||
|
||||
// Execute
|
||||
size_t batch_size = scoreDims[0];
|
||||
size_t total_num_rois = 0;
|
||||
std::vector<float> roi_item, score_item;
|
||||
std::vector<int64_t> roi_num(batch_size);
|
||||
uint8_t* p_roi_num = reinterpret_cast<uint8_t*>(&roi_num[0]);
|
||||
auto roi_num_type = getOriginalOutputPrecisionAtPort(OUTPUT_ROI_NUM);
|
||||
const auto roi_num_item_size = roi_num_type == Precision::I32 ? sizeof(int32_t) : sizeof(int64_t);
|
||||
for (size_t n = 0; n < batch_size; ++n) {
|
||||
// input image height & width
|
||||
const float img_H = p_img_info_cpu[0];
|
||||
const float img_W = p_img_info_cpu[1];
|
||||
// scale factor for height & width
|
||||
float scale_h = 1.0;
|
||||
float scale_w = 1.0;
|
||||
if (im_info_dims_size == 3) {
|
||||
scale_h = p_img_info_cpu[2];
|
||||
scale_w = p_img_info_cpu[2];
|
||||
} else if (im_info_dims_size == 4) {
|
||||
scale_h = p_img_info_cpu[2];
|
||||
scale_w = p_img_info_cpu[3];
|
||||
}
|
||||
// minimum box width & height
|
||||
const float min_box_H = min_size_ * scale_h;
|
||||
const float min_box_W = min_size_ * scale_w;
|
||||
|
||||
refine_anchors(p_deltas_item, p_scores_item, p_anchors_item,
|
||||
reinterpret_cast<float *>(&proposals_[0]), anchors_num, bottom_H,
|
||||
bottom_W, img_H, img_W,
|
||||
min_box_H, min_box_W,
|
||||
static_cast<const float>(log(1000. / 16.)),
|
||||
coordinates_offset_);
|
||||
std::partial_sort(proposals_.begin(), proposals_.begin() + pre_nms_topn, proposals_.end(),
|
||||
[](const ProposalBox &struct1, const ProposalBox &struct2) {
|
||||
return (struct1.score > struct2.score);
|
||||
});
|
||||
|
||||
unpack_boxes(reinterpret_cast<float *>(&proposals_[0]), &unpacked_boxes[0], &is_dead[0], pre_nms_topn);
|
||||
nms_cpu(pre_nms_topn, &is_dead[0], &unpacked_boxes[0], &roi_indices_[0], &num_rois, 0,
|
||||
nms_thresh_, post_nms_topn_, coordinates_offset_);
|
||||
|
||||
size_t new_num_rois = total_num_rois + num_rois;
|
||||
roi_item.resize(new_num_rois * 4);
|
||||
score_item.resize(new_num_rois);
|
||||
|
||||
fill_output_blobs(&unpacked_boxes[0], &roi_indices_[0], &roi_item[total_num_rois * 4], &score_item[total_num_rois],
|
||||
p_roi_num, pre_nms_topn, num_rois, post_nms_topn_, roi_num_type);
|
||||
p_deltas_item += deltas_dims_size;
|
||||
p_scores_item += score_dims_size;
|
||||
p_img_info_cpu += im_info_dims_size;
|
||||
total_num_rois = new_num_rois;
|
||||
p_roi_num += roi_num_item_size;
|
||||
}
|
||||
// copy to out memory
|
||||
redefineOutputMemory({VectorDims{total_num_rois, 4}, VectorDims{total_num_rois}, VectorDims{batch_size}});
|
||||
float *p_roi_item = reinterpret_cast<float *>(getChildEdgesAtPort(OUTPUT_ROIS)[0]->getMemoryPtr()->GetPtr());
|
||||
float *p_roi_score_item = reinterpret_cast<float *>(getChildEdgesAtPort(OUTPUT_SCORES)[0]->getMemoryPtr()->GetPtr());
|
||||
uint8_t* p_roi_num_item = reinterpret_cast<uint8_t *>(getChildEdgesAtPort(OUTPUT_ROI_NUM)[0]->getMemoryPtr()->GetPtr());
|
||||
memcpy(p_roi_item, &roi_item[0], roi_item.size() * sizeof(float));
|
||||
memcpy(p_roi_score_item, &score_item[0], score_item.size() * sizeof(float));
|
||||
memcpy(p_roi_num_item, &roi_num[0], getChildEdgesAtPort(OUTPUT_ROI_NUM)[0]->getMemoryPtr()->GetSize());
|
||||
} catch (const std::exception &e) {
|
||||
std::string errorMsg = e.what();
|
||||
IE_THROW() << errorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
bool GenerateProposals::created() const {
|
||||
return getType() == Type::GenerateProposals;
|
||||
}
|
||||
|
||||
bool GenerateProposals::needShapeInfer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GenerateProposals::needPrepareParams() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
} // namespace intel_cpu
|
||||
} // namespace ov
|
||||
59
src/plugins/intel_cpu/src/nodes/generate_proposals.h
Normal file
59
src/plugins/intel_cpu/src/nodes/generate_proposals.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ie_common.h>
|
||||
#include <node.h>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_cpu {
|
||||
namespace node {
|
||||
|
||||
class GenerateProposals : public Node {
|
||||
public:
|
||||
GenerateProposals(const std::shared_ptr<ngraph::Node>& op,
|
||||
const dnnl::engine& eng, WeightsSharing::Ptr &cache);
|
||||
|
||||
void getSupportedDescriptors() override {};
|
||||
void initSupportedPrimitiveDescriptors() override;
|
||||
void execute(dnnl::stream strm) override;
|
||||
bool created() const override;
|
||||
|
||||
bool needShapeInfer() const override;
|
||||
bool needPrepareParams() const override;
|
||||
void executeDynamicImpl(dnnl::stream strm) override;
|
||||
static bool isSupportedOperation(const std::shared_ptr<const ngraph::Node>& op, std::string& errorMessage) noexcept;
|
||||
|
||||
private:
|
||||
// Inputs:
|
||||
// im_info, shape [N, 3] or [N, 4]
|
||||
// anchors, shape [H, W, A, 4]
|
||||
// deltas, shape [N, A * 4, H, W]
|
||||
// scores, shape [N, A, H, W]
|
||||
// Outputs:
|
||||
// rois, shape [rois_num, 4]
|
||||
// scores, shape [rois_num]
|
||||
// roi_num, shape [N]
|
||||
|
||||
const int INPUT_IM_INFO {0};
|
||||
const int INPUT_ANCHORS {1};
|
||||
const int INPUT_DELTAS {2};
|
||||
const int INPUT_SCORES {3};
|
||||
const int OUTPUT_ROIS {0};
|
||||
const int OUTPUT_SCORES {1};
|
||||
const int OUTPUT_ROI_NUM {2};
|
||||
|
||||
float min_size_;
|
||||
int pre_nms_topn_;
|
||||
int post_nms_topn_;
|
||||
float nms_thresh_;
|
||||
float coordinates_offset_;
|
||||
|
||||
std::vector<int> roi_indices_;
|
||||
};
|
||||
|
||||
} // namespace node
|
||||
} // namespace intel_cpu
|
||||
} // namespace ov
|
||||
@@ -76,6 +76,7 @@
|
||||
#include "nodes/depth_to_space.h"
|
||||
#include "nodes/input.h"
|
||||
#include "nodes/experimental_detectron_generate_proposals_single_image.h"
|
||||
#include "nodes/generate_proposals.h"
|
||||
#include "nodes/embedding_bag_packed_sum.h"
|
||||
#include "nodes/reduce.h"
|
||||
#include "nodes/if.h"
|
||||
@@ -132,6 +133,7 @@ Node::NodesFactory::NodesFactory()
|
||||
INTEL_CPU_NODE(Select, Type::Select);
|
||||
INTEL_CPU_NODE(ShapeOf, Type::ShapeOf);
|
||||
INTEL_CPU_NODE(ExperimentalDetectronGenerateProposalsSingleImage, Type::ExperimentalDetectronGenerateProposalsSingleImage);
|
||||
INTEL_CPU_NODE(GenerateProposals, Type::GenerateProposals);
|
||||
INTEL_CPU_NODE(ReverseSequence, Type::ReverseSequence);
|
||||
INTEL_CPU_NODE(FakeQuantize, Type::FakeQuantize);
|
||||
INTEL_CPU_NODE(NonMaxSuppression, Type::NonMaxSuppression);
|
||||
|
||||
@@ -930,6 +930,142 @@ TEST_F(NGraphReshapeTests, ReshapeEDGenerateProposalsSingleImage_opset6) {
|
||||
ASSERT_NO_THROW(network.reshape(newShapes));
|
||||
}
|
||||
|
||||
TEST_F(NGraphReshapeTests, ReshapeGenerateProposals) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="GenerateProposals" version="10">
|
||||
<layers>
|
||||
<layer name="in0" type="Parameter" id="0" version="opset1">
|
||||
<data shape="8,3" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>8</dim>
|
||||
<dim>3</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="in1" type="Parameter" id="1" version="opset1">
|
||||
<data shape="50,84,3,4" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>50</dim>
|
||||
<dim>84</dim>
|
||||
<dim>3</dim>
|
||||
<dim>4</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="in2" type="Parameter" id="2" version="opset1">
|
||||
<data shape="8,12,50,84" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>8</dim>
|
||||
<dim>12</dim>
|
||||
<dim>50</dim>
|
||||
<dim>84</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="in3" type="Parameter" id="3" version="opset1">
|
||||
<data shape="8,3,50,84" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>8</dim>
|
||||
<dim>3</dim>
|
||||
<dim>50</dim>
|
||||
<dim>84</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="4" name="1133" type="GenerateProposals" version="opset9">
|
||||
<data min_size="0.0" nms_threshold="0.699999988079071" post_nms_count="1000" pre_nms_count="1000" roi_num_type="i32"/>
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>8</dim>
|
||||
<dim>3</dim>
|
||||
</port>
|
||||
<port id="1">
|
||||
<dim>50</dim>
|
||||
<dim>84</dim>
|
||||
<dim>3</dim>
|
||||
<dim>4</dim>
|
||||
</port>
|
||||
<port id="2">
|
||||
<dim>8</dim>
|
||||
<dim>12</dim>
|
||||
<dim>50</dim>
|
||||
<dim>84</dim>
|
||||
</port>
|
||||
<port id="3">
|
||||
<dim>8</dim>
|
||||
<dim>3</dim>
|
||||
<dim>50</dim>
|
||||
<dim>84</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="4" precision="FP32">
|
||||
<dim>-1</dim>
|
||||
<dim>4</dim>
|
||||
</port>
|
||||
<port id="5" precision="FP32">
|
||||
<dim>-1</dim>
|
||||
</port>
|
||||
<port id="6" precision="I32">
|
||||
<dim>8</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="out_0" type="Result" id="5" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>-1</dim>
|
||||
<dim>4</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
<layer name="out_1" type="Result" id="6" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>-1</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
<layer name="out_2" type="Result" id="7" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="I32">
|
||||
<dim>8</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="4" to-port="0"/>
|
||||
<edge from-layer="1" from-port="0" to-layer="4" to-port="1"/>
|
||||
<edge from-layer="2" from-port="0" to-layer="4" to-port="2"/>
|
||||
<edge from-layer="3" from-port="0" to-layer="4" to-port="3"/>
|
||||
<edge from-layer="4" from-port="4" to-layer="5" to-port="0"/>
|
||||
<edge from-layer="4" from-port="5" to-layer="6" to-port="0"/>
|
||||
<edge from-layer="4" from-port="6" to-layer="7" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
InferenceEngine::Core ie;
|
||||
Blob::Ptr weights;
|
||||
auto network = ie.ReadNetwork(model, weights);
|
||||
InferenceEngine::ICNNNetwork::InputShapes newShapes;
|
||||
newShapes["in1"] = {100, 100, 4, 4};
|
||||
newShapes["in2"] = {8, 16, 100, 100};
|
||||
newShapes["in3"] = {8, 4, 100, 100};
|
||||
ASSERT_NO_THROW(network.reshape(newShapes));
|
||||
|
||||
InferenceEngine::ICNNNetwork::InputShapes newShapes2;
|
||||
newShapes2["in0"] = {2, 4};
|
||||
newShapes2["in1"] = {100, 100, 4, 4};
|
||||
newShapes2["in2"] = {2, 16, 100, 100};
|
||||
newShapes2["in3"] = {2, 4, 100, 100};
|
||||
ASSERT_NO_THROW(network.reshape(newShapes2));
|
||||
}
|
||||
|
||||
TEST_F(NGraphReshapeTests, ReshapeEDROIFeatureExtractor) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="ExperimentalDetectronROIFeatureExtractor" version="10">
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include "single_layer_tests/generate_proposals.hpp"
|
||||
#include "common_test_utils/ov_tensor_utils.hpp"
|
||||
|
||||
using namespace ov::test;
|
||||
using namespace ov::test::subgraph;
|
||||
|
||||
namespace {
|
||||
|
||||
const std::vector<float> min_size = { 1 };
|
||||
const std::vector<float> nms_threshold = { 0.699999988079071 };
|
||||
const std::vector<int64_t> post_nms_count = { 6 };
|
||||
const std::vector<int64_t> pre_nms_count = { 1000 };
|
||||
|
||||
const std::vector<std::pair<std::string, std::vector<ov::Tensor>>> inputTensors = {
|
||||
{
|
||||
"empty",
|
||||
{
|
||||
// 3
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 3}, {1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f}),
|
||||
// 2 x 6 x 3 x 4 = 144
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 6, 3, 4}, std::vector<float>(144, 1.0f)),
|
||||
// 2 x 12 x 2 x 6 = 144 * 2
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 12, 2, 6}, std::vector<float>(288, 1.0f)),
|
||||
// {2 x 3 x 2 x 6} = 36 * 2
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 3, 2, 6}, {
|
||||
5.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 4.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 8.0f, 1.0f,
|
||||
5.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 4.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 8.0f, 1.0f})
|
||||
}
|
||||
},
|
||||
{
|
||||
"filled",
|
||||
{
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 3}, {150.0, 150.0, 0.0, 150.0, 150.0, 0.0}),
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 6, 3, 4}, {
|
||||
12.0, 68.0, 102.0, 123.0, 46.0, 80.0, 79.0, 128.0, 33.0, 71.0, 127.0, 86.0, 33.0, 56.0, 150.0, 73.0,
|
||||
5.0, 41.0, 93.0, 150.0, 74.0, 66.0, 106.0, 115.0, 17.0, 37.0, 87.0, 150.0, 31.0, 27.0, 150.0, 39.0,
|
||||
29.0, 23.0, 112.0, 123.0, 41.0, 37.0, 103.0, 150.0, 8.0, 46.0, 98.0, 111.0, 7.0, 69.0, 114.0, 150.0,
|
||||
70.0, 21.0, 150.0, 125.0, 54.0, 19.0, 132.0, 68.0, 62.0, 8.0, 150.0, 101.0, 57.0, 81.0, 150.0, 97.0,
|
||||
79.0, 29.0, 109.0, 130.0, 12.0, 63.0, 100.0, 150.0, 17.0, 33.0, 113.0, 150.0, 90.0, 78.0, 150.0, 111.0,
|
||||
47.0, 68.0, 150.0, 71.0, 66.0, 103.0, 111.0, 150.0, 4.0, 17.0, 112.0, 94.0, 12.0, 8.0, 119.0, 98.0,
|
||||
54.0, 56.0, 120.0, 150.0, 56.0, 29.0, 150.0, 31.0, 42.0, 3.0, 139.0, 92.0, 41.0, 65.0, 150.0, 130.0,
|
||||
49.0, 13.0, 143.0, 30.0, 40.0, 60.0, 150.0, 150.0, 23.0, 73.0, 24.0, 115.0, 56.0, 84.0, 107.0, 108.0,
|
||||
63.0, 8.0, 142.0, 125.0, 78.0, 37.0, 93.0, 144.0, 40.0, 34.0, 150.0, 46.0, 30.0, 21.0, 150.0, 120.0}),
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 12, 2, 6}, {
|
||||
9.062256, 10.883133, 9.8441105, 12.694285, 0.41781136, 8.749107, 14.990341, 6.587644, 1.4206103,
|
||||
13.299262, 12.432549, 2.736371, 0.22732796, 6.3361835, 12.268727, 2.1009045, 4.771589, 2.5131326,
|
||||
5.610736, 9.3604145, 4.27379, 8.317948, 0.60510135, 6.7446275, 1.0207708, 1.1352817, 1.5785321,
|
||||
1.718335, 1.8093798, 0.99247587, 1.3233583, 1.7432803, 1.8534478, 1.2593061, 1.7394226, 1.7686696,
|
||||
1.647999, 1.7611449, 1.3119122, 0.03007332, 1.1106564, 0.55669737, 0.2546148, 1.9181818, 0.7134989,
|
||||
2.0407224, 1.7211134, 1.8565536, 14.562747, 2.8786168, 0.5927796, 0.2064463, 7.6794515, 8.672126,
|
||||
10.139171, 8.002429, 7.002932, 12.6314945, 10.550842, 0.15784842, 0.3194304, 10.752157, 3.709805,
|
||||
11.628928, 0.7136225, 14.619964, 15.177284, 2.2824087, 15.381494, 0.16618137, 7.507227, 11.173228,
|
||||
0.4923559, 1.8227729, 1.4749299, 1.7833921, 1.2363617, -0.23659119, 1.5737582, 1.779316, 1.9828427,
|
||||
1.0482665, 1.4900246, 1.3563544, 1.5341306, 0.7634312, 4.6216766e-05, 1.6161222, 1.7512476, 1.9363779,
|
||||
0.9195784, 1.4906164, -0.03244795, 0.681073, 0.6192401, 1.8033613, 14.146055, 3.4043705, 15.292292,
|
||||
3.5295358, 11.138999, 9.952057, 5.633434, 12.114562, 9.427372, 12.384038, 9.583308, 8.427233,
|
||||
15.293704, 3.288159, 11.64898, 9.350885, 2.0037227, 13.523184, 4.4176426, 6.1057625, 14.400079,
|
||||
8.248259, 11.815807, 15.713364, 1.0023532, 1.3203261, 1.7100681, 0.7407832, 1.09448, 1.7188418,
|
||||
1.4412547, 1.4862992, 0.74790007, 0.31571656, 0.6398838, 2.0236106, 1.1869069, 1.7265586, 1.2624544,
|
||||
0.09934269, 1.3508598, 0.85212964, -0.38968498, 1.7059708, 1.6533034, 1.7400402, 1.8123854, -0.43063712,
|
||||
9.062256, 10.883133, 9.8441105, 12.694285, 0.41781136, 8.749107, 14.990341, 6.587644, 1.4206103,
|
||||
13.299262, 12.432549, 2.736371, 0.22732796, 6.3361835, 12.268727, 2.1009045, 4.771589, 2.5131326,
|
||||
5.610736, 9.3604145, 4.27379, 8.317948, 0.60510135, 6.7446275, 1.0207708, 1.1352817, 1.5785321,
|
||||
1.718335, 1.8093798, 0.99247587, 1.3233583, 1.7432803, 1.8534478, 1.2593061, 1.7394226, 1.7686696,
|
||||
1.647999, 1.7611449, 1.3119122, 0.03007332, 1.1106564, 0.55669737, 0.2546148, 1.9181818, 0.7134989,
|
||||
2.0407224, 1.7211134, 1.8565536, 14.562747, 2.8786168, 0.5927796, 0.2064463, 7.6794515, 8.672126,
|
||||
10.139171, 8.002429, 7.002932, 12.6314945, 10.550842, 0.15784842, 0.3194304, 10.752157, 3.709805,
|
||||
11.628928, 0.7136225, 14.619964, 15.177284, 2.2824087, 15.381494, 0.16618137, 7.507227, 11.173228,
|
||||
0.4923559, 1.8227729, 1.4749299, 1.7833921, 1.2363617, -0.23659119, 1.5737582, 1.779316, 1.9828427,
|
||||
1.0482665, 1.4900246, 1.3563544, 1.5341306, 0.7634312, 4.6216766e-05, 1.6161222, 1.7512476, 1.9363779,
|
||||
0.9195784, 1.4906164, -0.03244795, 0.681073, 0.6192401, 1.8033613, 14.146055, 3.4043705, 15.292292,
|
||||
3.5295358, 11.138999, 9.952057, 5.633434, 12.114562, 9.427372, 12.384038, 9.583308, 8.427233,
|
||||
15.293704, 3.288159, 11.64898, 9.350885, 2.0037227, 13.523184, 4.4176426, 6.1057625, 14.400079,
|
||||
8.248259, 11.815807, 15.713364, 1.0023532, 1.3203261, 1.7100681, 0.7407832, 1.09448, 1.7188418,
|
||||
1.4412547, 1.4862992, 0.74790007, 0.31571656, 0.6398838, 2.0236106, 1.1869069, 1.7265586, 1.2624544,
|
||||
0.09934269, 1.3508598, 0.85212964, -0.38968498, 1.7059708, 1.6533034, 1.7400402, 1.8123854, -0.43063712}),
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 3, 2, 6}, {
|
||||
0.7719922, 0.35906568, 0.29054508, 0.18124384, 0.5604661, 0.84750974, 0.98948747, 0.009793862, 0.7184191,
|
||||
0.5560748, 0.6952493, 0.6732593, 0.3306898, 0.6790913, 0.41128764, 0.34593266, 0.94296855, 0.7348507,
|
||||
0.24478768, 0.94024557, 0.05405676, 0.06466125, 0.36244348, 0.07942984, 0.10619422, 0.09412837, 0.9053611,
|
||||
0.22870538, 0.9237487, 0.20986171, 0.5067282, 0.29709867, 0.53138554, 0.189101, 0.4786443, 0.88421875,
|
||||
0.7719922, 0.35906568, 0.29054508, 0.18124384, 0.5604661, 0.84750974, 0.98948747, 0.009793862, 0.7184191,
|
||||
0.5560748, 0.6952493, 0.6732593, 0.3306898, 0.6790913, 0.41128764, 0.34593266, 0.94296855, 0.7348507,
|
||||
0.24478768, 0.94024557, 0.05405676, 0.06466125, 0.36244348, 0.07942984, 0.10619422, 0.09412837, 0.9053611,
|
||||
0.22870538, 0.9237487, 0.20986171, 0.5067282, 0.29709867, 0.53138554, 0.189101, 0.4786443, 0.88421875}),
|
||||
}
|
||||
},
|
||||
{
|
||||
"filled2",
|
||||
{
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 3}, {200.0, 200.0, 4.0, 200.0, 200.0, 4.0}),
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 6, 3, 4}, {0.0f, 1.0f, 2.0f, 3.0f,
|
||||
4.0f, 5.0f, 6.0f, 7.0f,
|
||||
8.0f, 9.0f, 10.0f, 11.0f,
|
||||
12.0f, 13.0f, 14.0f, 15.0f,
|
||||
16.0f, 17.0f, 18.0f, 19.0f,
|
||||
20.0f, 21.0f, 22.0f, 23.0f,
|
||||
24.0f, 25.0f, 26.0f, 27.0f,
|
||||
28.0f, 29.0f, 30.0f, 31.0f,
|
||||
32.0f, 33.0f, 34.0f, 35.0f,
|
||||
36.0f, 37.0f, 38.0f, 39.0f,
|
||||
40.0f, 41.0f, 42.0f, 43.0f,
|
||||
44.0f, 45.0f, 46.0f, 47.0f,
|
||||
48.0f, 49.0f, 50.0f, 51.0f,
|
||||
52.0f, 53.0f, 54.0f, 55.0f,
|
||||
56.0f, 57.0f, 58.0f, 59.0f,
|
||||
60.0f, 61.0f, 62.0f, 63.0f,
|
||||
64.0f, 65.0f, 66.0f, 67.0f,
|
||||
68.0f, 69.0f, 70.0f, 71.0f,
|
||||
72.0f, 73.0f, 74.0f, 75.0f,
|
||||
76.0f, 77.0f, 78.0f, 79.0f,
|
||||
80.0f, 81.0f, 82.0f, 83.0f,
|
||||
84.0f, 85.0f, 86.0f, 87.0f,
|
||||
88.0f, 89.0f, 90.0f, 91.0f,
|
||||
92.0f, 93.0f, 94.0f, 95.0f,
|
||||
96.0f, 97.0f, 98.0f, 99.0f,
|
||||
100.0f, 101.0f, 102.0f, 103.0f,
|
||||
104.0f, 105.0f, 106.0f, 107.0f,
|
||||
108.0f, 109.0f, 110.0f, 111.0f,
|
||||
112.0f, 113.0f, 114.0f, 115.0f,
|
||||
116.0f, 117.0f, 118.0f, 119.0f,
|
||||
120.0f, 121.0f, 122.0f, 123.0f,
|
||||
124.0f, 125.0f, 126.0f, 127.0f,
|
||||
128.0f, 129.0f, 130.0f, 131.0f,
|
||||
132.0f, 133.0f, 134.0f, 135.0f,
|
||||
136.0f, 137.0f, 138.0f, 139.0f,
|
||||
140.0f, 141.0f, 142.0f, 143.0f}),
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 12, 2, 6}, {
|
||||
0.5337073, 0.86607957, 0.55151343, 0.21626699, 0.4462629, 0.03985678,
|
||||
0.5157072, 0.9932138, 0.7565954, 0.43803605, 0.802818, 0.14834064,
|
||||
0.53932905, 0.14314, 0.3817048, 0.95075196, 0.05516243, 0.2567484,
|
||||
0.25508744, 0.77438325, 0.43561, 0.2094628, 0.8299043, 0.44982538,
|
||||
0.95615596, 0.5651084, 0.11801951, 0.05352486, 0.9774733, 0.14439464,
|
||||
0.62644225, 0.14370479, 0.54161614, 0.557915, 0.53102225, 0.0840179,
|
||||
0.7249888, 0.9843559, 0.5490522, 0.53788143, 0.822474, 0.3278008,
|
||||
0.39688024, 0.3286012, 0.5117038, 0.04743988, 0.9408995, 0.29885054,
|
||||
0.81039643, 0.85277915, 0.06807619, 0.86430097, 0.36225632, 0.16606331,
|
||||
0.5401001, 0.7541649, 0.11998601, 0.5131829, 0.40606487, 0.327888,
|
||||
0.27721855, 0.6378373, 0.22795396, 0.4961256, 0.3215895, 0.15607187,
|
||||
0.14782153, 0.8908137, 0.8835288, 0.834191, 0.29907143, 0.7983525,
|
||||
0.755875, 0.30837986, 0.0839176, 0.26624718, 0.04371626, 0.09472824,
|
||||
0.20689541, 0.37622106, 0.1083321, 0.1342548, 0.05815459, 0.7676379,
|
||||
0.8105144, 0.92348766, 0.26761323, 0.7183306, 0.8947588, 0.19020908,
|
||||
0.42731014, 0.7473663, 0.85775334, 0.9340091, 0.3278848, 0.755993,
|
||||
0.05307213, 0.39705503, 0.21003333, 0.5625373, 0.66188884, 0.80521655,
|
||||
0.6125863, 0.44678232, 0.97802377, 0.0204936, 0.02686367, 0.7390654,
|
||||
0.74631, 0.58399844, 0.5988792, 0.37413648, 0.5946692, 0.6955776,
|
||||
0.36377597, 0.7891322, 0.40900692, 0.99139464, 0.50169915, 0.41435778,
|
||||
0.17142445, 0.26761186, 0.31591868, 0.14249913, 0.12919712, 0.5418711,
|
||||
0.6523203, 0.50259084, 0.7379765, 0.01171071, 0.94423133, 0.00841132,
|
||||
0.97486794, 0.2921785, 0.7633071, 0.88477814, 0.03563205, 0.50833166,
|
||||
0.01354555, 0.535081, 0.41366324, 0.0694767, 0.9944055, 0.9981207,
|
||||
0.5337073, 0.86607957, 0.55151343, 0.21626699, 0.4462629, 0.03985678,
|
||||
0.5157072, 0.9932138, 0.7565954, 0.43803605, 0.802818, 0.14834064,
|
||||
0.53932905, 0.14314, 0.3817048, 0.95075196, 0.05516243, 0.2567484,
|
||||
0.25508744, 0.77438325, 0.43561, 0.2094628, 0.8299043, 0.44982538,
|
||||
0.95615596, 0.5651084, 0.11801951, 0.05352486, 0.9774733, 0.14439464,
|
||||
0.62644225, 0.14370479, 0.54161614, 0.557915, 0.53102225, 0.0840179,
|
||||
0.7249888, 0.9843559, 0.5490522, 0.53788143, 0.822474, 0.3278008,
|
||||
0.39688024, 0.3286012, 0.5117038, 0.04743988, 0.9408995, 0.29885054,
|
||||
0.81039643, 0.85277915, 0.06807619, 0.86430097, 0.36225632, 0.16606331,
|
||||
0.5401001, 0.7541649, 0.11998601, 0.5131829, 0.40606487, 0.327888,
|
||||
0.27721855, 0.6378373, 0.22795396, 0.4961256, 0.3215895, 0.15607187,
|
||||
0.14782153, 0.8908137, 0.8835288, 0.834191, 0.29907143, 0.7983525,
|
||||
0.755875, 0.30837986, 0.0839176, 0.26624718, 0.04371626, 0.09472824,
|
||||
0.20689541, 0.37622106, 0.1083321, 0.1342548, 0.05815459, 0.7676379,
|
||||
0.8105144, 0.92348766, 0.26761323, 0.7183306, 0.8947588, 0.19020908,
|
||||
0.42731014, 0.7473663, 0.85775334, 0.9340091, 0.3278848, 0.755993,
|
||||
0.05307213, 0.39705503, 0.21003333, 0.5625373, 0.66188884, 0.80521655,
|
||||
0.6125863, 0.44678232, 0.97802377, 0.0204936, 0.02686367, 0.7390654,
|
||||
0.74631, 0.58399844, 0.5988792, 0.37413648, 0.5946692, 0.6955776,
|
||||
0.36377597, 0.7891322, 0.40900692, 0.99139464, 0.50169915, 0.41435778,
|
||||
0.17142445, 0.26761186, 0.31591868, 0.14249913, 0.12919712, 0.5418711,
|
||||
0.6523203, 0.50259084, 0.7379765, 0.01171071, 0.94423133, 0.00841132,
|
||||
0.97486794, 0.2921785, 0.7633071, 0.88477814, 0.03563205, 0.50833166,
|
||||
0.01354555, 0.535081, 0.41366324, 0.0694767, 0.9944055, 0.9981207}),
|
||||
ov::test::utils::create_tensor<float>(ov::element::f32, ov::Shape{2, 3, 2, 6}, {
|
||||
0.56637216, 0.90457034, 0.69827306, 0.4353543, 0.47985056, 0.42658508,
|
||||
0.14516132, 0.08081771, 0.1799732, 0.9229515, 0.42420176, 0.50857586,
|
||||
0.82664067, 0.4972319, 0.3752427, 0.56731623, 0.18241242, 0.33252355,
|
||||
0.30608943, 0.6572437, 0.69185436, 0.88646156, 0.36985755, 0.5590753,
|
||||
0.5256446, 0.03342898, 0.1344396, 0.68642473, 0.37953874, 0.32575172,
|
||||
0.21108444, 0.5661886, 0.45378175, 0.62126315, 0.26799858, 0.37272978,
|
||||
0.56637216, 0.90457034, 0.69827306, 0.4353543, 0.47985056, 0.42658508,
|
||||
0.14516132, 0.08081771, 0.1799732, 0.9229515, 0.42420176, 0.50857586,
|
||||
0.82664067, 0.4972319, 0.3752427, 0.56731623, 0.18241242, 0.33252355,
|
||||
0.30608943, 0.6572437, 0.69185436, 0.88646156, 0.36985755, 0.5590753,
|
||||
0.5256446, 0.03342898, 0.1344396, 0.68642473, 0.37953874, 0.32575172,
|
||||
0.21108444, 0.5661886, 0.45378175, 0.62126315, 0.26799858, 0.37272978}),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const std::vector<std::vector<InputShape>> dynamicInputShape = {
|
||||
// im_info / anchors / deltas / scores
|
||||
static_shapes_to_test_representation({{2, 3}, {2, 6, 3, 4}, {2, 12, 2, 6}, {2, 3, 2, 6}}),
|
||||
{
|
||||
{{-1, -1}, {{2, 3}}},
|
||||
{{-1, -1, -1, -1}, {{2, 6, 3, 4}}},
|
||||
{{-1, -1, -1, -1}, {{2, 12, 2, 6}}},
|
||||
{{-1, -1, -1, -1}, {{2, 3, 2, 6}}}
|
||||
},
|
||||
{
|
||||
{{{1, 3}, {3, 6}}, {{2, 3}}},
|
||||
{{{2, 4}, {6, 12}, {3, 6}, {4, 8}}, {{2, 6, 3, 4}}},
|
||||
{{{1, 3}, {12, 24}, {2, 4}, {6, 12}}, {{2, 12, 2, 6}}},
|
||||
{{{1, 3}, {3, 6}, {2, 4}, {6, 12}}, {{2, 3, 2, 6}}}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_GenerateProposalsLayerTest,
|
||||
GenerateProposalsLayerTest,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(dynamicInputShape),
|
||||
::testing::ValuesIn(min_size),
|
||||
::testing::ValuesIn(nms_threshold),
|
||||
::testing::ValuesIn(post_nms_count),
|
||||
::testing::ValuesIn(pre_nms_count),
|
||||
::testing::ValuesIn(inputTensors),
|
||||
::testing::Values(ov::element::Type_t::f32),
|
||||
::testing::Values(ov::element::Type_t::i32),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
GenerateProposalsLayerTest::getTestCaseName);
|
||||
} // namespace
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_test_classes/single_layer/generate_proposals.hpp>
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace subgraph {
|
||||
|
||||
TEST_P(GenerateProposalsLayerTest, GenerateProposalsLayerTests) {
|
||||
run();
|
||||
}
|
||||
|
||||
} // namespace subgraph
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "ngraph_functions/utils/ngraph_helpers.hpp"
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace subgraph {
|
||||
|
||||
typedef std::tuple<
|
||||
std::vector<InputShape>, // Input shapes
|
||||
float, // min_size: minimum box width & height
|
||||
float, // nms_threshold: specifies NMS threshold
|
||||
int64_t, // post_nms_count: number of top-n proposals after NMS
|
||||
int64_t, // pre_nms_count: number of top-n proposals after NMS
|
||||
std::pair<std::string, std::vector<ov::Tensor>>, // input tensors
|
||||
ElementType, // Network precision
|
||||
ElementType, // roi_num precision
|
||||
std::string // Device name>;
|
||||
> GenerateProposalsTestParams;
|
||||
|
||||
class GenerateProposalsLayerTest :
|
||||
public testing::WithParamInterface<GenerateProposalsTestParams>,
|
||||
virtual public SubgraphBaseTest {
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void generate_inputs(const std::vector<ngraph::Shape>& targetInputStaticShapes) override;
|
||||
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<GenerateProposalsTestParams>& obj);
|
||||
};
|
||||
} // namespace subgraph
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,115 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "shared_test_classes/single_layer/generate_proposals.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "common_test_utils/ov_tensor_utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
namespace subgraph {
|
||||
|
||||
namespace {
|
||||
std::ostream& operator <<(
|
||||
std::ostream& ss,
|
||||
const ov::op::v9::GenerateProposals::Attributes& attributes) {
|
||||
ss << "score_threshold=" << attributes.min_size << "_";
|
||||
ss << "nms_threshold=" << attributes.nms_threshold << "_";
|
||||
ss << "max_delta_log_wh=" << attributes.post_nms_count << "_";
|
||||
ss << "num_classes=" << attributes.pre_nms_count;
|
||||
return ss;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string GenerateProposalsLayerTest::getTestCaseName(
|
||||
const testing::TestParamInfo<GenerateProposalsTestParams>& obj) {
|
||||
std::vector<InputShape> inputShapes;
|
||||
ov::op::v9::GenerateProposals::Attributes attributes;
|
||||
std::pair<std::string, std::vector<ov::Tensor>> inputTensors;
|
||||
ElementType netPrecision;
|
||||
ElementType roiNumPrecision;
|
||||
std::string targetName;
|
||||
std::tie(
|
||||
inputShapes,
|
||||
attributes.min_size,
|
||||
attributes.nms_threshold,
|
||||
attributes.post_nms_count,
|
||||
attributes.pre_nms_count,
|
||||
inputTensors,
|
||||
netPrecision,
|
||||
roiNumPrecision,
|
||||
targetName) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
using ov::test::operator<<;
|
||||
result << "im_info=" << inputShapes[0] << "_";
|
||||
result << "anchors=" << inputShapes[1] << "_";
|
||||
result << "deltas=" << inputShapes[2] << "_";
|
||||
result << "scores=" << inputShapes[3] << "_";
|
||||
|
||||
using ov::test::subgraph::operator<<;
|
||||
result << "attributes={" << attributes << "}_";
|
||||
result << "inputTensors=" << inputTensors.first << "_";
|
||||
result << "netPRC=" << netPrecision << "_";
|
||||
result << "roiNumPRC=" << roiNumPrecision << "_";
|
||||
result << "trgDev=" << targetName;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void GenerateProposalsLayerTest::SetUp() {
|
||||
std::vector<InputShape> inputShapes;
|
||||
ov::op::v9::GenerateProposals::Attributes attributes;
|
||||
std::pair<std::string, std::vector<ov::Tensor>> inputTensors;
|
||||
ElementType netPrecision;
|
||||
ElementType roiNumPrecision;
|
||||
std::string targetName;
|
||||
std::tie(
|
||||
inputShapes,
|
||||
attributes.min_size,
|
||||
attributes.nms_threshold,
|
||||
attributes.post_nms_count,
|
||||
attributes.pre_nms_count,
|
||||
inputTensors,
|
||||
netPrecision,
|
||||
roiNumPrecision,
|
||||
targetName) = this->GetParam();
|
||||
|
||||
inType = outType = netPrecision;
|
||||
targetDevice = targetName;
|
||||
|
||||
init_input_shapes(inputShapes);
|
||||
|
||||
auto params = ngraph::builder::makeDynamicParams(netPrecision, {inputDynamicShapes});
|
||||
auto paramsOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(params));
|
||||
auto generateProposals = std::make_shared<ov::op::v9::GenerateProposals>(
|
||||
params[0], // im_info
|
||||
params[1], // anchors
|
||||
params[2], // deltas
|
||||
params[3], // scores
|
||||
attributes,
|
||||
roiNumPrecision);
|
||||
function = std::make_shared<ov::Model>(
|
||||
ov::OutputVector{generateProposals->output(0),
|
||||
generateProposals->output(1),
|
||||
generateProposals->output(2)},
|
||||
"GenerateProposals");
|
||||
}
|
||||
|
||||
void GenerateProposalsLayerTest::generate_inputs(const std::vector<ngraph::Shape>& targetInputStaticShapes) {
|
||||
auto inputTensors = std::get<5>(GetParam());
|
||||
|
||||
inputs.clear();
|
||||
const auto& funcInputs = function->inputs();
|
||||
for (auto i = 0ul; i < funcInputs.size(); ++i) {
|
||||
if (targetInputStaticShapes[i] != inputTensors.second[i].get_shape()) {
|
||||
throw Exception("input shape is different from tensor shape");
|
||||
}
|
||||
|
||||
inputs.insert({funcInputs[i].get_node_shared_ptr(), inputTensors.second[i]});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace subgraph
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
Reference in New Issue
Block a user