From 77236a1e6c16123fadbd3cdd9f705ea1e4feb665 Mon Sep 17 00:00:00 2001 From: Vladimir Gavrilov Date: Wed, 26 May 2021 17:49:33 +0300 Subject: [PATCH] Implement reference nGraph implementation for the operation "ExperimentalDetectronTopKROIs" (#5675) * Started to write nGraph reference implementation of the operation ExperimentalDetectronTopKROIs. * Written cpp-file for the nGraph reference implementation of the operation ExperimentalDetectronTopKROIs. * Code style fixes. * Started to write evaluate() (in evaluates_map.cpp) for the nGraph operation ExperimentalDetectronsTopKROIs. * Code style fixes. * Written evaluate() for ExperimentalDetectronTopKROIs. * Small fixes. * Written test for ExperimentalDetectronTopKROIs evaluation. * Small fix. * Fixed Apache license header. * Some changes. * int64_t was replaced with size_t in the body of ngraph::runtime::reference::experimental_detectron_topk_rois(). * Added more test for evaluation of ExperimentalDetectronTopKROIs. --- .../experimental_detectron_topk_rois.hpp | 51 +++++++++++ ngraph/test/CMakeLists.txt | 1 + .../experimental_detectron_topk_rois.in.cpp | 88 +++++++++++++++++++ .../runtime/interpreter/evaluates_map.cpp | 18 ++++ .../runtime/interpreter/opset_int_tbl.hpp | 1 + 5 files changed, 159 insertions(+) create mode 100644 ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_topk_rois.hpp create mode 100644 ngraph/test/backend/experimental_detectron_topk_rois.in.cpp diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_topk_rois.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_topk_rois.hpp new file mode 100644 index 00000000000000..6ad5d6c506bbaf --- /dev/null +++ b/ngraph/core/reference/include/ngraph/runtime/reference/experimental_detectron_topk_rois.hpp @@ -0,0 +1,51 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include +#include +#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 + { + template + void experimental_detectron_topk_rois(const T* input_rois, + const T* input_probs, + const Shape& input_rois_shape, + const Shape& input_probs_shape, + size_t max_rois, + T* output_rois) + { + const size_t input_rois_num = input_rois_shape[0]; + const size_t top_rois_num = std::min(max_rois, input_rois_num); + + std::vector idx(input_rois_num); + std::iota(idx.begin(), idx.end(), 0); + std::sort(idx.begin(), idx.end(), [&input_probs](size_t i1, size_t i2) { + return input_probs[i1] > input_probs[i2]; + }); + + for (size_t i = 0; i < top_rois_num; ++i) + { + output_rois[0] = input_rois[4 * idx[i] + 0]; + output_rois[1] = input_rois[4 * idx[i] + 1]; + output_rois[2] = input_rois[4 * idx[i] + 2]; + output_rois[3] = input_rois[4 * idx[i] + 3]; + output_rois += 4; + } + } + } // namespace reference + } // namespace runtime +} // namespace ngraph diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index 86ad351de894a9..82788abdb40e72 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -350,6 +350,7 @@ set(MULTI_TEST_SRC backend/divide.in.cpp backend/deformable_convolution.in.cpp backend/dyn_reshape.in.cpp + backend/experimental_detectron_topk_rois.in.cpp backend/strided_slice.in.cpp backend/dynamic.in.cpp backend/elu.in.cpp diff --git a/ngraph/test/backend/experimental_detectron_topk_rois.in.cpp b/ngraph/test/backend/experimental_detectron_topk_rois.in.cpp new file mode 100644 index 00000000000000..c224228a6195df --- /dev/null +++ b/ngraph/test/backend/experimental_detectron_topk_rois.in.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2018-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "gtest/gtest.h" +#include "ngraph/ngraph.hpp" +#include "ngraph/runtime/tensor.hpp" +#include "runtime/backend.hpp" +#include "util/all_close.hpp" +#include "util/all_close_f.hpp" +#include "util/engine/test_engines.hpp" +#include "util/known_element_types.hpp" +#include "util/ndarray.hpp" +#include "util/test_case.hpp" +#include "util/test_control.hpp" +#include "util/test_tools.hpp" + +using namespace std; +using namespace ngraph; + +static string s_manifest = "${MANIFEST}"; + +using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME}); + +using ExperimentalTopK = op::v6::ExperimentalDetectronTopKROIs; + +NGRAPH_TEST(${BACKEND_NAME}, experimental_detectron_topk_rois_eval) +{ + size_t num_rois = 1; + + const auto input_rois_shape = Shape{2, 4}; + const auto input_probs_shape = Shape{2}; + const auto output_shape = Shape{1, 4}; + + auto input_rois = std::make_shared(element::f32, input_rois_shape); + auto input_probs = std::make_shared(element::f32, input_probs_shape); + auto topk_rois = std::make_shared(input_rois, input_probs, num_rois); + auto f = std::make_shared(topk_rois, ParameterVector{input_rois, input_probs}); + + auto backend = runtime::Backend::create("${BACKEND_NAME}"); + auto topk_rois_output = backend->create_tensor(element::f32, output_shape); + + std::vector input_rois_data = {1.0f, 1.0f, 3.0f, 4.0f, 2.0f, 1.0f, 5.0f, 7.0f}; + std::vector input_probs_data = {0.5f, 0.3f}; + std::vector expected_result = {1.0, 1.0, 3.0, 4.0}; + + auto backend_input_rois_data = backend->create_tensor(element::f32, input_rois_shape); + copy_data(backend_input_rois_data, input_rois_data); + auto backend_input_probs_data = backend->create_tensor(element::f32, input_probs_shape); + copy_data(backend_input_probs_data, input_probs_data); + + auto handle = backend->compile(f); + handle->call({topk_rois_output}, {backend_input_rois_data, backend_input_probs_data}); + + ASSERT_TRUE(test::all_close_f(read_vector(topk_rois_output), expected_result)); +} + +NGRAPH_TEST(${BACKEND_NAME}, experimental_detectron_topk_rois_eval_2) +{ + size_t num_rois = 2; + + const auto input_rois_shape = Shape{4, 4}; + const auto input_probs_shape = Shape{4}; + const auto output_shape = Shape{2, 4}; + + auto input_rois = std::make_shared(element::f32, input_rois_shape); + auto input_probs = std::make_shared(element::f32, input_probs_shape); + auto topk_rois = std::make_shared(input_rois, input_probs, num_rois); + auto f = std::make_shared(topk_rois, ParameterVector{input_rois, input_probs}); + + auto backend = runtime::Backend::create("${BACKEND_NAME}"); + auto topk_rois_output = backend->create_tensor(element::f32, output_shape); + + std::vector input_rois_data = {1.0f, 1.0f, 4.0f, 5.0f, 3.0f, 2.0f, 7.0f, 9.0f, + 10.0f, 15.0f, 13.0f, 17.0f, 13.0f, 10.0f, 18.0f, 15.0f}; + std::vector input_probs_data = {0.1f, 0.7f, 0.5f, 0.9f}; + std::vector expected_result = {13.0f, 10.0f, 18.0f, 15.0f, 3.0f, 2.0f, 7.0f, 9.0f}; + + auto backend_input_rois_data = backend->create_tensor(element::f32, input_rois_shape); + copy_data(backend_input_rois_data, input_rois_data); + auto backend_input_probs_data = backend->create_tensor(element::f32, input_probs_shape); + copy_data(backend_input_probs_data, input_probs_data); + + auto handle = backend->compile(f); + handle->call({topk_rois_output}, {backend_input_rois_data, backend_input_probs_data}); + + ASSERT_TRUE(test::all_close_f(read_vector(topk_rois_output), expected_result)); +} diff --git a/ngraph/test/runtime/interpreter/evaluates_map.cpp b/ngraph/test/runtime/interpreter/evaluates_map.cpp index b737d94e021a0a..62f951c5dd7475 100644 --- a/ngraph/test/runtime/interpreter/evaluates_map.cpp +++ b/ngraph/test/runtime/interpreter/evaluates_map.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -2076,6 +2077,23 @@ namespace return true; } + template + bool evaluate(const shared_ptr& op, + const HostTensorVector& outputs, + const HostTensorVector& inputs) + { + using T = typename element_type_traits::value_type; + size_t max_rois = op->get_max_rois(); + outputs[0]->set_shape(Shape{max_rois, 4}); + runtime::reference::experimental_detectron_topk_rois(inputs[0]->get_data_ptr(), + inputs[1]->get_data_ptr(), + inputs[0]->get_shape(), + inputs[1]->get_shape(), + max_rois, + outputs[0]->get_data_ptr()); + return true; + } + template bool evaluate(const shared_ptr& op, const HostTensorVector& outputs, diff --git a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp index 16907f55ff79dd..898dd662c7204b 100644 --- a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp +++ b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp @@ -85,6 +85,7 @@ NGRAPH_OP(RNNSequence, op::v5) NGRAPH_OP(Round, op::v5) NGRAPH_OP(CTCGreedyDecoderSeqLen, op::v6) +NGRAPH_OP(ExperimentalDetectronTopKROIs, op::v6) NGRAPH_OP(GatherElements, op::v6) NGRAPH_OP(MVN, ngraph::op::v6)