Skip to content

Commit

Permalink
[CPU]: Added ROIAlignRotated basic impl. (#23844)
Browse files Browse the repository at this point in the history
### Details:
 - Added basic implementation of ROIAlignRotated
- It uses implementation from core::reference - the goal was just to add
support for the op, not the optimized implementation.
- No unit tests added, since impl is already tested by core::reference
and functional tests.

### Tickets:
 - [CVS-135847](https://jira.devtools.intel.com/browse/CVS-135847)

---------

Co-authored-by: Pawel Raasz <[email protected]>
  • Loading branch information
pkowalc1 and praasz authored May 15, 2024
1 parent 3302535 commit cf5bf71
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/core/include/openvino/opsets/opset14_tbl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,4 @@ _OPENVINO_OP_REG(FakeConvert, ov::op::v13)
// New operations added in opset14
_OPENVINO_OP_REG(ConvertPromoteTypes, ov::op::v14)
_OPENVINO_OP_REG(Inverse, ov::op::v14)
_OPENVINO_OP_REG(ROIAlignRotated, ov::op::v14)
2 changes: 1 addition & 1 deletion src/core/tests/opset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ INSTANTIATE_TEST_SUITE_P(opset,
OpsetTestParams{ov::get_opset11, 177},
OpsetTestParams{ov::get_opset12, 178},
OpsetTestParams{ov::get_opset13, 186},
OpsetTestParams{ov::get_opset14, 188},
OpsetTestParams{ov::get_opset14, 189},
OpsetTestParams{ov::get_opset15, 5}),
OpsetTestNameGenerator{});

Expand Down
5 changes: 3 additions & 2 deletions src/frontends/onnx/tests/onnx_import.in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6617,8 +6617,9 @@ OPENVINO_TEST(${BACKEND_NAME}, onnx_model_mish_activation) {
}

OPENVINO_TEST(${BACKEND_NAME}, onnx_model_mmdeploy_roi_align_rotated) {
if (std::string("${BACKEND_NAME}") != std::string("INTERPRETER")) {
return; //< Skip this test for non-INTERPRETER backends, since op is not yet implemented on those backends.
if (!(std::string("${BACKEND_NAME}") == std::string("INTERPRETER") ||
std::string("${BACKEND_NAME}") == std::string("IE_CPU"))) {
return; //< Skip this test for not-yet-implemented on those backends.
}

auto model = convert_model("mmdeploy_roi_align_rotated.onnx");
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/intel_cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ if (ENABLE_SNIPPETS_LIBXSMM_TPP)
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE $<TARGET_PROPERTY:xsmm,INCLUDE_DIRECTORIES>)
endif ()
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE $<TARGET_PROPERTY:dnnl,INCLUDE_DIRECTORIES>)

# Temporal solution to use template reference implementations in cases where optimizied implementation
# is not (yet) needed.
target_include_directories(${TARGET_NAME} PRIVATE $<TARGET_PROPERTY:openvino::reference,INTERFACE_INCLUDE_DIRECTORIES>)

# Cross compiled function
# TODO: The same for proposal, proposalONNX, topk
cross_compiled_file(${TARGET_NAME}
Expand Down Expand Up @@ -256,6 +261,7 @@ if(BUILD_SHARED_LIBS)
$<TARGET_PROPERTY:openvino::itt,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::shape_inference,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::snippets,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::reference,INTERFACE_INCLUDE_DIRECTORIES>
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
$<TARGET_PROPERTY:openvino::conditional_compilation,INTERFACE_INCLUDE_DIRECTORIES>)
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/intel_cpu/src/cpu_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ static const TypeToNameMap& get_type_to_name_tbl() {
{"Slice", Type::StridedSlice},
{"Tile", Type::Tile},
{"ROIAlign", Type::ROIAlign},
{"ROIAlignRotated", Type::ROIAlignRotated},
{"ROIPooling", Type::ROIPooling},
{"PSROIPooling", Type::PSROIPooling},
{"DeformablePSROIPooling", Type::PSROIPooling},
Expand Down Expand Up @@ -280,6 +281,7 @@ std::string NameFromType(const Type type) {
CASE(NonZero);
CASE(Tile);
CASE(ROIAlign);
CASE(ROIAlignRotated);
CASE(ROIPooling);
CASE(PSROIPooling);
CASE(DepthToSpace);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/intel_cpu/src/cpu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum class Type {
NonZero,
Tile,
ROIAlign,
ROIAlignRotated,
ROIPooling,
PSROIPooling,
BatchToSpace,
Expand Down
108 changes: 108 additions & 0 deletions src/plugins/intel_cpu/src/nodes/roi_align_rotated.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "roi_align_rotated.h"

#include <openvino/opsets/opset14.hpp>

#include "common/cpu_convert.h"
#include "openvino/reference/roi_align.hpp"

namespace ov {
namespace intel_cpu {
namespace node {

ROIAlignRotated::ROIAlignRotated(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context)
: Node(op, context, NgraphShapeInferFactory(op, EMPTY_PORT_MASK)) {
const auto roiAlign = ov::as_type_ptr<const ov::opset14::ROIAlignRotated>(op);
pooledH = roiAlign->get_pooled_h();
pooledW = roiAlign->get_pooled_w();
spatialScale = roiAlign->get_spatial_scale();
samplingRatio = roiAlign->get_sampling_ratio();
clockwiseMode = roiAlign->get_clockwise_mode();
}

void ROIAlignRotated::getSupportedDescriptors() {
// Validation is already done in the ov::opset14::ROIAlignRotated.
}

void ROIAlignRotated::initSupportedPrimitiveDescriptors() {
if (!supportedPrimitiveDescriptors.empty())
return;

ov::element::Type inputPrec0 = getOriginalInputPrecisionAtPort(0);
ov::element::Type outputPrec = getOriginalOutputPrecisionAtPort(0);

addSupportedPrimDesc(
{{LayoutType::ncsp, inputPrec0}, {LayoutType::ncsp, ov::element::f32}, {LayoutType::ncsp, ov::element::i32}},
{{LayoutType::ncsp, outputPrec}},
impl_desc_type::ref);
}

bool ROIAlignRotated::created() const {
return getType() == Type::ROIAlignRotated;
}

bool ROIAlignRotated::needPrepareParams() const {
return false;
}

void ROIAlignRotated::executeDynamicImpl(dnnl::stream strm) {
execute(strm);
}

template <ov::element::Type_t OV_TYPE>
void ROIAlignRotated::executeImpl() {
using T = typename ov::element_type_traits<OV_TYPE>::value_type;

const size_t batch_indices_size = getSrcMemoryAtPort(2)->getShape().getElementsCount();

std::vector<int64_t> batch_indices_vec_scaled_up(batch_indices_size);
cpu_convert(getSrcMemoryAtPort(2)->getData(),
batch_indices_vec_scaled_up.data(),
getSrcMemoryAtPort(2)->getPrecision(),
ov::element::i64,
batch_indices_size);

ov::reference::roi_align<T, ov::reference::roi_policy::ROIAlignRotatedOpDefPolicy>(
getSrcDataAtPortAs<const T>(0),
getSrcDataAtPortAs<const T>(1),
batch_indices_vec_scaled_up.data(),
getDstDataAtPortAs<T>(0),
ov::Shape{getSrcMemoryAtPort(0)->getStaticDims()},
ov::Shape{getSrcMemoryAtPort(1)->getStaticDims()},
ov::Shape{getSrcMemoryAtPort(2)->getStaticDims()},
ov::Shape{getDstMemoryAtPort(0)->getStaticDims()},
pooledH,
pooledW,
samplingRatio,
spatialScale,
ov::op::v3::ROIAlign::PoolingMode::AVG,
ov::op::v9::ROIAlign::AlignedMode::ASYMMETRIC,
clockwiseMode);
}

void ROIAlignRotated::execute(dnnl::stream) {
const ov::element::Type type = getOriginalInputPrecisionAtPort(0);
executeImpl<ov::element::f32>();

#define CASE(OV_TYPE) \
case ov::element::OV_TYPE: \
executeImpl<ov::element::OV_TYPE>(); \
break;

switch (type) {
CASE(bf16);
CASE(f16);
CASE(f32);
CASE(f64);
default:
OPENVINO_THROW("[ROIAlignRotated]: Unhandled data type ", type, " in execute()");
}
#undef CASE
}

} // namespace node
} // namespace intel_cpu
} // namespace ov
37 changes: 37 additions & 0 deletions src/plugins/intel_cpu/src/nodes/roi_align_rotated.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "node.h"

namespace ov {
namespace intel_cpu {
namespace node {

class ROIAlignRotated : public Node {
public:
ROIAlignRotated(const std::shared_ptr<ov::Node>& op, const GraphContext::CPtr context);

void getSupportedDescriptors() override;
void initSupportedPrimitiveDescriptors() override;
void execute(dnnl::stream strm) override;
bool created() const override;
bool needPrepareParams() const override;
void executeDynamicImpl(dnnl::stream strm) override;

private:
template <ov::element::Type_t OV_TYPE>
void executeImpl();

int pooledH;
int pooledW;
int samplingRatio;
float spatialScale;
bool clockwiseMode;
};

} // namespace node
} // namespace intel_cpu
} // namespace ov
2 changes: 2 additions & 0 deletions src/plugins/intel_cpu/src/nodes_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#include "nodes/reverse_sequence.h"
#include "nodes/rnn.h"
#include "nodes/roi_align.h"
#include "nodes/roi_align_rotated.h"
#include "nodes/roi_pooling.h"
#include "nodes/roll.h"
#include "nodes/rope.h"
Expand Down Expand Up @@ -194,6 +195,7 @@ Node::NodesFactory::NodesFactory() : Factory("NodesFactory") {
INTEL_CPU_NODE(NonMaxSuppression, Type::NonMaxSuppression);
INTEL_CPU_NODE(ROIPooling, Type::ROIPooling);
INTEL_CPU_NODE(ROIAlign, Type::ROIAlign);
INTEL_CPU_NODE(ROIAlignRotated, Type::ROIAlignRotated);
INTEL_CPU_NODE(TopK, Type::TopK);
INTEL_CPU_NODE(Proposal, Type::Proposal);
INTEL_CPU_NODE(RegionYolo, Type::RegionYolo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,19 @@ std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v9::ROIAlign>&
return std::make_shared<ov::Model>(results, params, "ROIAlignGraph");
}

std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v14::ROIAlignRotated>& node) {
ov::ParameterVector params{std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::Shape{{1, 1, 16, 16}})};
const auto coords = std::make_shared<ov::op::v0::Constant>(
ov::element::f32,
ov::Shape{1, static_cast<size_t>(node->get_rois_input_second_dim_size())},
std::vector<float>(node->get_rois_input_second_dim_size(), 0));
const auto roisIdx =
std::make_shared<ov::op::v0::Constant>(ov::element::i32, ov::Shape{1}, std::vector<int32_t>{0});
auto new_node = std::make_shared<ov::op::v14::ROIAlignRotated>(params.at(0), coords, roisIdx, 2, 2, 2, 1, true);
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(new_node)};
return std::make_shared<ov::Model>(results, params, "ROIAlignRotatedGraph");
}

std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v0::ROIPooling> &node) {
ov::ParameterVector params{std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::Shape{{1, 3, 8, 8}}),
std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::Shape{{1, 5}})};
Expand Down

0 comments on commit cf5bf71

Please sign in to comment.