diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_region_yolo_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_region_yolo_node.cpp index d530c051a6444b..af1159bb07d195 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_region_yolo_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_region_yolo_node.cpp @@ -369,31 +369,38 @@ inline void MKLDNNRegionYoloNode::calculate_logistic(size_t start_index, int cou void MKLDNNRegionYoloNode::execute(mkldnn::stream strm) { auto inputDesc = getParentEdgeAt(0)->getDesc(); auto outputDesc = getChildEdgeAt(0)->getDesc(); - size_t mask_size = mask.size(); - size_t IW = (inputDesc.getDims().size() > 3) ? inputDesc.getDims()[3] : 1; - size_t IH = (inputDesc.getDims().size() > 2) ? inputDesc.getDims()[2] : 1; - size_t IC = (inputDesc.getDims().size() > 1) ? inputDesc.getDims()[1] : 1; size_t B = (inputDesc.getDims().size() > 0) ? inputDesc.getDims()[0] : 1; + size_t IC = (inputDesc.getDims().size() > 1) ? inputDesc.getDims()[1] : 1; + size_t IH = (inputDesc.getDims().size() > 2) ? inputDesc.getDims()[2] : 1; + size_t IW = (inputDesc.getDims().size() > 3) ? inputDesc.getDims()[3] : 1; + size_t mask_size = mask.size(); int end_index = 0; int num_ = 0; + int output_size = 0; if (do_softmax) { // Region layer (Yolo v2) end_index = IW * IH; num_ = num; + output_size = B * IH * IW * IC; // different shape combinations with the same overall size; } else { // Yolo layer (Yolo v3) end_index = IW * IH * (classes + 1); num_ = mask_size; + output_size = B * IH * IW * mask_size * (classes + coords + 1); } + + if (output_size != getChildEdgeAt(0)->getMemoryPtr()->GetElementsCount()) + IE_THROW() << "Incorrect layer configuration or output dimensions. " << output_size << " != " << getChildEdgeAt(0)->getMemoryPtr()->GetElementsCount(); + size_t inputs_size = IH * IW * num_ * (classes + coords + 1); size_t total_size = 2 * IH * IW; const auto *src_data = reinterpret_cast(getParentEdgeAt(0)->getMemoryPtr()->GetPtr()); auto *dst_data = reinterpret_cast(getChildEdgeAt(0)->getMemoryPtr()->GetPtr()); - cpu_convert(src_data, dst_data, inputDesc.getPrecision(), outputDesc.getPrecision(), B * IC * IH * IW); + cpu_convert(src_data, dst_data, inputDesc.getPrecision(), outputDesc.getPrecision(), output_size); for (int b = 0; b < B; b++) { for (int n = 0; n < num_; n++) { diff --git a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/region_yolo.cpp b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/region_yolo.cpp index 46a364178df0ce..4c88cf8d884873 100644 --- a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/region_yolo.cpp +++ b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/region_yolo.cpp @@ -69,11 +69,14 @@ class RegionYoloCPULayerTest : public testing::WithParamInterface(ngPrc, inputShape); - auto region_yolo = std::make_shared(param, attributes.coordinates, attributes.classes, attributes.num_regions, - attributes.do_softmax, mask, attributes.start_axis, attributes.end_axis); - function = std::make_shared(std::make_shared(region_yolo), ngraph::ParameterVector{param}, "RegionYolo"); + const auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(inPrc); + auto paramRegionYolo = ngraph::builder::makeParams(ngPrc, {inputShape}); + + const auto region_yolo = std::make_shared(paramRegionYolo[0], + attributes.coordinates, attributes.classes, attributes.num_regions, + attributes.do_softmax, mask, attributes.start_axis, attributes.end_axis); + + function = makeNgraphFunction(ngPrc, paramRegionYolo, region_yolo, "RegionYolo"); } }; @@ -99,7 +102,10 @@ const std::vector inShapes_mxnet = { {1, 75, 26, 26}, {1, 75, 16, 16}, {1, 75, 13, 13}, - {1, 75, 8, 8} + {1, 75, 8, 8}, + {1, 303, 7, 7}, + {1, 303, 14, 14}, + {1, 303, 28, 28}, }; const std::vector inShapes_v3 = { @@ -158,4 +164,4 @@ INSTANTIATE_TEST_CASE_P(smoke_TestsRegionYolov3CPU, RegionYoloCPULayerTest, test INSTANTIATE_TEST_CASE_P(smoke_TestsRegionYoloMxnetCPU, RegionYoloCPULayerTest, testCase_yolov3_mxnet, RegionYoloCPULayerTest::getTestCaseName); INSTANTIATE_TEST_CASE_P(smoke_TestsRegionYoloCaffeCPU, RegionYoloCPULayerTest, testCase_yolov2_caffe, RegionYoloCPULayerTest::getTestCaseName); } // namespace -} // namespace CPULayerTestsDefinitions \ No newline at end of file +} // namespace CPULayerTestsDefinitions diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/region_yolo.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/region_yolo.hpp index 7c8c32f40731c4..fff204cd209b62 100644 --- a/ngraph/core/reference/include/ngraph/runtime/reference/region_yolo.hpp +++ b/ngraph/core/reference/include/ngraph/runtime/reference/region_yolo.hpp @@ -86,24 +86,27 @@ namespace ngraph const auto mask_size = mask.size(); - std::copy(input, input + shape_size(input_shape), output); - int num_regions = 0; int end_index = 0; + int output_size = 0; if (do_softmax) { // Region layer (Yolo v2) num_regions = regions; end_index = width * height; + output_size = shape_size(input_shape); } else { // Yolo layer (Yolo v3) num_regions = mask_size; end_index = width * height * (classes + 1); + output_size = width * height * num_regions * (classes + coords + 1); } + std::copy(input, input + output_size, output); + const int inputs_size = width * height * num_regions * (classes + coords + 1); for (int batch_idx = 0; batch_idx < batches; batch_idx++) diff --git a/ngraph/test/backend/region_yolo.in.cpp b/ngraph/test/backend/region_yolo.in.cpp index 77292e74e6332d..0275b421db55d5 100644 --- a/ngraph/test/backend/region_yolo.in.cpp +++ b/ngraph/test/backend/region_yolo.in.cpp @@ -70,3 +70,44 @@ NGRAPH_TEST(${BACKEND_NAME}, region_yolo_v3_mxnet) shape, TEST_FILES, "region_out_yolov3_mxnet.data"); test_case.run_with_tolerance_as_fp(1.0e-4f); } + +NGRAPH_TEST(${BACKEND_NAME}, region_yolo_v3_mxnet_2) +{ + const size_t num = 1; + const size_t coords = 4; + const size_t classes = 1; + const size_t batch = 1; + const size_t channels = 8; + const size_t width = 2; + const size_t height = 2; + const std::vector mask{0}; + const int axis = 1; + const int end_axis = 3; + + Shape input_shape{batch, channels, height, width}; + Shape output_shape{batch, (classes + coords + 1) * mask.size(), height, width}; + + const auto A = make_shared(element::f32, input_shape); + const auto R = make_shared(A, coords, classes, num, false, mask, axis, end_axis); + const auto f = make_shared(R, ParameterVector{A}); + + EXPECT_EQ(R->get_output_shape(0), output_shape); + + auto test_case = test::TestCase(f); + std::vector input { + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f + }; + + std::vector output { + 0.52497f, 0.54983f, 0.57444f, 0.59868f, 0.62245f, 0.64565f, 0.66818f, 0.68997f, + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, + 0.52497f, 0.54983f, 0.57444f, 0.59868f, 0.62245f, 0.64565f, 0.66818f, 0.68997f, + }; + + test_case.add_input(input); + test_case.add_expected_output(output); + test_case.run_with_tolerance_as_fp(1.0e-4f); +}