**Inputs**:
-* **1**: 4D input tensor of any type and shape `[N, C, H, W]`. `H` and `W` should be divisible by `stride`. Required.
+* **1**: 4D input tensor of any type and shape `[N, C, H, W]`. `H` and `W` should be divisible by `stride` and `C >= (stride*stride)`. **Required.**
**Outputs**:
**Example**
```xml
-<layer id="89" name="ExtractImagePatches" type="ReorgYolo">
+<layer id="89" name="reorg" type="ReorgYolo">
<data stride="2"/>
<input>
<port id="0">
</port>
</output>
</layer>
-```
\ No newline at end of file
+```
using namespace testing;
-TEST(TransformationTests, ConvertExtractImagePatchesToReorgYoloTests1) {
- std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
- {
- auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3, 10, 10});
-
- auto sizes = ngraph::Shape{5, 5};
- auto strides = ngraph::Strides{5, 5};
- auto rates = ngraph::Shape{1, 1};
- ngraph::op::PadType auto_pad = ngraph::op::PadType::VALID;
-
- auto eip = std::make_shared<ngraph::opset3::ExtractImagePatches>(input, sizes, strides, rates, auto_pad);
-
- f = std::make_shared<ngraph::Function>(ngraph::NodeVector{eip}, ngraph::ParameterVector{input});
-
- ngraph::pass::Manager manager;
- manager.register_pass<ngraph::pass::InitNodeInfo>();
- manager.register_pass<ngraph::pass::ConvertExtractImagePatchesToReorgYolo>();
- manager.run_passes(f);
- ASSERT_NO_THROW(check_rt_info(f));
- }
-
- {
- auto input = std::make_shared<ngraph::opset1::Parameter>(ngraph::element::f32, ngraph::Shape{1, 3, 10, 10});
- auto strides = ngraph::Strides{5, 5};
- auto reorg_yolo = std::make_shared<ngraph::opset3::ReorgYolo>(input, strides);
-
- f_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{reorg_yolo}, ngraph::ParameterVector{input});
- }
-
- auto res = compare_functions(f, f_ref);
- ASSERT_TRUE(res.first) << res.second;
-}
+// TODO: bug 39971, remove ConvertExtractImagePatchesToReorgYolo transformation
TEST(TransformationTests, ConvertExtractImagePatchesToReorgYoloTestsNegative1) {
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
--- /dev/null
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include <vector>
+
+#include "single_layer_tests/reorg_yolo.hpp"
+#include "common_test_utils/test_constants.hpp"
+
+using namespace LayerTestsDefinitions;
+
+const std::vector<ngraph::Shape> inShapes_caffe_yolov2 = {
+ {1, 64, 26, 26},
+};
+
+const std::vector<ngraph::Shape> inShapes = {
+ {1, 4, 4, 4},
+ {1, 8, 4, 4},
+ {1, 9, 3, 3},
+ {1, 24, 34, 62},
+ {2, 8, 4, 4},
+};
+
+const std::vector<size_t> strides = {
+ 2, 3
+};
+
+const auto testCase_caffe_yolov2 = ::testing::Combine(
+ ::testing::ValuesIn(inShapes_caffe_yolov2),
+ ::testing::Values(strides[0]),
+ ::testing::Values(InferenceEngine::Precision::FP32),
+ ::testing::Values(CommonTestUtils::DEVICE_CPU)
+);
+
+const auto testCase_smallest = ::testing::Combine(
+ ::testing::Values(inShapes[0]),
+ ::testing::Values(strides[0]),
+ ::testing::Values(InferenceEngine::Precision::FP32),
+ ::testing::Values(CommonTestUtils::DEVICE_CPU)
+);
+
+const auto testCase_stride_2 = ::testing::Combine(
+ ::testing::Values(inShapes[1]),
+ ::testing::Values(strides[0]),
+ ::testing::Values(InferenceEngine::Precision::FP32),
+ ::testing::Values(CommonTestUtils::DEVICE_CPU)
+);
+
+const auto testCase_stride_3 = ::testing::Combine(
+ ::testing::Values(inShapes[2]),
+ ::testing::Values(strides[1]),
+ ::testing::Values(InferenceEngine::Precision::FP32),
+ ::testing::Values(CommonTestUtils::DEVICE_CPU)
+);
+
+const auto testCase_smaller_h = ::testing::Combine(
+ ::testing::Values(inShapes[4]),
+ ::testing::Values(strides[0]),
+ ::testing::Values(InferenceEngine::Precision::FP32),
+ ::testing::Values(CommonTestUtils::DEVICE_CPU)
+);
+
+const auto testCase_batch_2 = ::testing::Combine(
+ ::testing::Values(inShapes[3]),
+ ::testing::Values(strides[0]),
+ ::testing::Values(InferenceEngine::Precision::FP32),
+ ::testing::Values(CommonTestUtils::DEVICE_CPU)
+);
+
+INSTANTIATE_TEST_CASE_P(smoke_TestsReorgYolo_caffe_YoloV2, ReorgYoloLayerTest, testCase_caffe_yolov2, ReorgYoloLayerTest::getTestCaseName);
+INSTANTIATE_TEST_CASE_P(smoke_TestsReorgYolo_stride_2_smallest, ReorgYoloLayerTest, testCase_smallest, ReorgYoloLayerTest::getTestCaseName);
+INSTANTIATE_TEST_CASE_P(smoke_TestsReorgYolo_stride_2, ReorgYoloLayerTest, testCase_stride_2, ReorgYoloLayerTest::getTestCaseName);
+INSTANTIATE_TEST_CASE_P(smoke_TestsReorgYolo_stride_3, ReorgYoloLayerTest, testCase_stride_3, ReorgYoloLayerTest::getTestCaseName);
+INSTANTIATE_TEST_CASE_P(smoke_TestsReorgYolo_smaller_h, ReorgYoloLayerTest, testCase_smaller_h, ReorgYoloLayerTest::getTestCaseName);
+INSTANTIATE_TEST_CASE_P(smoke_TestsReorgYolo_batch_2, ReorgYoloLayerTest, testCase_batch_2, ReorgYoloLayerTest::getTestCaseName);
--- /dev/null
+// Copyright (C) 2019 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include <tuple>
+#include <string>
+#include <vector>
+
+#include "functional_test_utils/layer_test_utils.hpp"
+#include "ngraph_functions/builders.hpp"
+#include "ngraph_functions/utils/ngraph_helpers.hpp"
+
+namespace LayerTestsDefinitions {
+
+using ReorgYoloParamsTuple = typename std::tuple<
+ ngraph::Shape, // Input Shape
+ size_t, // stride
+ InferenceEngine::Precision, // Network precision
+ std::string>; // Device name
+
+class ReorgYoloLayerTest : public testing::WithParamInterface<ReorgYoloParamsTuple>,
+ virtual public LayerTestsUtils::LayerTestsCommon {
+public:
+ static std::string getTestCaseName(const testing::TestParamInfo<ReorgYoloParamsTuple> &obj);
+
+protected:
+ void SetUp() override;
+};
+
+} // namespace LayerTestsDefinitions
--- /dev/null
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include "ie_core.hpp"
+
+#include "common_test_utils/common_utils.hpp"
+#include "functional_test_utils/blob_utils.hpp"
+#include "functional_test_utils/precision_utils.hpp"
+#include "functional_test_utils/plugin_cache.hpp"
+#include "functional_test_utils/skip_tests_config.hpp"
+
+#include "single_layer_tests/reorg_yolo.hpp"
+
+namespace LayerTestsDefinitions {
+
+std::string ReorgYoloLayerTest::getTestCaseName(const testing::TestParamInfo<ReorgYoloParamsTuple> &obj) {
+ ngraph::Shape inputShape;
+ size_t stride;
+ InferenceEngine::Precision netPrecision;
+ std::string targetName;
+ std::tie(inputShape, stride, netPrecision, targetName) = obj.param;
+ std::ostringstream result;
+ result << "IS=" << inputShape << "_";
+ result << "stride=" << stride << "_";
+ result << "netPRC=" << netPrecision.name() << "_";
+ result << "targetDevice=" << targetName << "_";
+ return result.str();
+}
+
+void ReorgYoloLayerTest::SetUp() {
+ ngraph::Shape inputShape;
+ size_t stride;
+ InferenceEngine::Precision netPrecision;
+ std::tie(inputShape, stride, netPrecision, targetDevice) = this->GetParam();
+ auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
+ auto param = std::make_shared<ngraph::op::Parameter>(ngraph::element::f32, inputShape);
+ auto reorg_yolo = std::make_shared<ngraph::op::v0::ReorgYolo>(param, stride);
+ function = std::make_shared<ngraph::Function>(std::make_shared<ngraph::opset1::Result>(reorg_yolo), ngraph::ParameterVector{param}, "ReorgYolo");
+}
+
+TEST_P(ReorgYoloLayerTest, CompareWithRefs) {
+ Run();
+};
+
+} // namespace LayerTestsDefinitions
/// \brief Constructs a ReorgYolo operation
///
/// \param input Input
- /// \param strides Stride to reorganize input by
+ /// \param stride Stride to reorganize input by
+ ReorgYolo(const Output<Node>& input, const size_t stride);
+
+ // Constructor with `strides` for backward compatibility
ReorgYolo(const Output<Node>& input, const Strides& strides);
void validate_and_infer_types() override;
--- /dev/null
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#pragma once
+
+#include <cmath>
+#include <cstddef>
+
+#include "ngraph/shape.hpp"
+
+namespace ngraph
+{
+ namespace runtime
+ {
+ namespace reference
+ {
+ void reorg_yolo(const char* arg,
+ char* out,
+ const Shape& in_shape,
+ int64_t stride,
+ const size_t elem_size);
+ }
+ }
+}
--- /dev/null
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <cmath>
+#include <stdio.h>
+
+#include "ngraph/runtime/reference/reorg_yolo.hpp"
+#include "ngraph/shape.hpp"
+
+using namespace ngraph;
+
+namespace ngraph
+{
+ namespace runtime
+ {
+ namespace reference
+ {
+ void reorg_yolo(const char* arg,
+ char* out,
+ const Shape& in_shape,
+ int64_t stride,
+ const size_t elem_size)
+ {
+ // [N, C, H, W]
+ size_t in_N = in_shape[0];
+ size_t in_C = in_shape[1];
+ size_t in_H = in_shape[2];
+ size_t in_W = in_shape[3];
+
+ // Inference output shape logic:
+ // in_shape [N,C,H,W] -> out_shape [N, C*(stride*stride), H/stride, W/stride]
+ // ReorgYolo implementation calculates new indices like for backprop:
+ // in_shape [N,C,H,W] -> out_shape [N, C/(stride*stride), H*stride, W*stride]
+
+ size_t impl_out_C = in_C / (stride * stride);
+ if (impl_out_C == 0)
+ {
+ throw ngraph_error(
+ "ReorgYolo. For [N, C, H, W] input shape, C >= (stride*stride) is "
+ "required.");
+ }
+ size_t impl_out_H = in_H * stride;
+ size_t impl_out_W = in_W * stride;
+
+ for (size_t n = 0; n < in_N; ++n)
+ {
+ for (size_t c = 0; c < in_C; ++c)
+ {
+ for (size_t h = 0; h < in_H; ++h)
+ {
+ for (size_t w = 0; w < in_W; ++w)
+ {
+ size_t offset = c / impl_out_C;
+ size_t impl_c = c % impl_out_C;
+ size_t impl_h = h * stride + offset / stride;
+ size_t impl_w = w * stride + offset % stride;
+
+ size_t arg_index =
+ ((n * impl_out_C + impl_c) * impl_out_H + impl_h) * impl_out_W +
+ impl_w;
+ size_t dest_index = ((n * in_C + c) * in_H + h) * in_W + w;
+
+ arg_index *= elem_size;
+ dest_index *= elem_size;
+
+ std::copy(arg + arg_index,
+ arg + (arg_index + elem_size),
+ out + dest_index);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
//*****************************************************************************
#include "ngraph/op/reorg_yolo.hpp"
+#include "ngraph/runtime/reference/reorg_yolo.hpp"
using namespace std;
using namespace ngraph;
constructor_validate_and_infer_types();
}
+op::ReorgYolo::ReorgYolo(const Output<Node>& input, const size_t stride)
+ : Op({input})
+ , m_strides(std::vector<size_t>{stride, stride})
+{
+ constructor_validate_and_infer_types();
+}
+
void op::ReorgYolo::validate_and_infer_types()
{
+ NODE_VALIDATION_CHECK(this, !m_strides.empty(), "Stride attribute is required.");
+
auto input_et = get_input_element_type(0);
if (get_input_partial_shape(0).is_static())
{
auto input_shape = get_input_partial_shape(0).to_shape();
- Shape output_shape{input_shape[0], input_shape[1]};
+ NODE_VALIDATION_CHECK(
+ this, input_shape.size() == 4, "[N, C, H, W] input shape is required.");
+
+ NODE_VALIDATION_CHECK(this,
+ (input_shape[2] % m_strides[0]) == 0,
+ "For [N, C, H, W] input shape, H should be divisible by stride.");
+
+ NODE_VALIDATION_CHECK(this,
+ (input_shape[3] % m_strides[0]) == 0,
+ "For [N, C, H, W] input shape, W should be divisible by stride.");
+ NODE_VALIDATION_CHECK(this,
+ input_shape[1] >= (m_strides[0] * m_strides[0]),
+ "For [N, C, H, W] input shape, C >= (stride*stride) is required.");
+
+ Shape output_shape{input_shape[0], input_shape[1]};
for (size_t i = 2; i < input_shape.size(); i++)
{
output_shape.push_back(input_shape[i] / m_strides[0]);
type_prop/read_value.cpp
type_prop/reduce_l1.cpp
type_prop/reduce_l2.cpp
+ type_prop/reorg_yolo.cpp
type_prop/replace_slice.cpp
type_prop/reshape.cpp
type_prop/reverse.cpp
backend/reduce_prod.in.cpp
backend/reduce_sum.in.cpp
backend/relu.in.cpp
+ backend/reorg_yolo.in.cpp
backend/replace_slice.in.cpp
backend/reshape.in.cpp
backend/reverse_sequence.in.cpp
EXPECT_EQ(g_op->get_eps(), op->get_eps());
}
-TEST(attributes, reorg_yolo_op)
+TEST(attributes, reorg_yolo_op_stride)
{
FactoryRegistry<Node>::get().register_factory<opset3::ReorgYolo>();
- const auto data = make_shared<op::Parameter>(element::i32, Shape{2, 3, 4, 5});
+ const auto data = make_shared<op::Parameter>(element::i32, Shape{1, 64, 26, 26});
+
+ const auto op = make_shared<op::v0::ReorgYolo>(data, 2);
+ NodeBuilder builder(op);
+ const auto g_op = as_type_ptr<op::v0::ReorgYolo>(builder.create());
+
+ EXPECT_EQ(g_op->get_strides(), op->get_strides());
+}
+
+TEST(attributes, reorg_yolo_op_strides)
+{
+ FactoryRegistry<Node>::get().register_factory<opset3::ReorgYolo>();
+ const auto data = make_shared<op::Parameter>(element::i32, Shape{1, 64, 26, 26});
- const auto op = make_shared<opset3::ReorgYolo>(data, Strides{2});
+ const auto op = make_shared<op::v0::ReorgYolo>(data, Strides{2});
NodeBuilder builder(op);
- const auto g_op = as_type_ptr<opset3::ReorgYolo>(builder.create());
+ const auto g_op = as_type_ptr<op::v0::ReorgYolo>(builder.create());
EXPECT_EQ(g_op->get_strides(), op->get_strides());
}
--- /dev/null
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include <algorithm>
+#include <cinttypes>
+#include <cmath>
+#include <cstdlib>
+#include <random>
+#include <string>
+
+// clang-format off
+#ifdef ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
+#define DEFAULT_FLOAT_TOLERANCE_BITS ${BACKEND_NAME}_FLOAT_TOLERANCE_BITS
+#endif
+
+#ifdef ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
+#define DEFAULT_DOUBLE_TOLERANCE_BITS ${BACKEND_NAME}_DOUBLE_TOLERANCE_BITS
+#endif
+// clang-format on
+
+#include "gtest/gtest.h"
+#include "ngraph/ngraph.hpp"
+#include "util/engine/test_engines.hpp"
+#include "util/test_case.hpp"
+#include "util/test_control.hpp"
+#include "util/type_prop.hpp"
+
+using namespace std;
+using namespace ngraph;
+
+static string s_manifest = "${MANIFEST}";
+using TestEngine = test::ENGINE_CLASS_NAME(${BACKEND_NAME});
+
+NGRAPH_TEST(${BACKEND_NAME}, reorg_yolo_stride_2)
+{
+ // in_shape [N,C,H,W]
+ const auto in_shape = Shape{1, 8, 4, 4};
+ auto p = make_shared<op::Parameter>(element::f32, in_shape);
+ size_t stride = 2;
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(p, Strides{stride});
+ auto fun = make_shared<Function>(OutputVector{reorg_yolo}, ParameterVector{p});
+
+ std::vector<float> inputs(128);
+ std::iota(inputs.begin(), inputs.end(), 0);
+ std::vector<float> expected_result{
+ 0, 2, 4, 6, 16, 18, 20, 22, 32, 34, 36, 38, 48, 50, 52, 54,
+ 64, 66, 68, 70, 80, 82, 84, 86, 96, 98, 100, 102, 112, 114, 116, 118,
+ 1, 3, 5, 7, 17, 19, 21, 23, 33, 35, 37, 39, 49, 51, 53, 55,
+ 65, 67, 69, 71, 81, 83, 85, 87, 97, 99, 101, 103, 113, 115, 117, 119,
+ 8, 10, 12, 14, 24, 26, 28, 30, 40, 42, 44, 46, 56, 58, 60, 62,
+ 72, 74, 76, 78, 88, 90, 92, 94, 104, 106, 108, 110, 120, 122, 124, 126,
+ 9, 11, 13, 15, 25, 27, 29, 31, 41, 43, 45, 47, 57, 59, 61, 63,
+ 73, 75, 77, 79, 89, 91, 93, 95, 105, 107, 109, 111, 121, 123, 125, 127};
+ // in_shape [N,C,H,W] -> out_shape [N, C*stride*stride, H/stride, W/stride]
+ Shape expected_shape = Shape{
+ in_shape[0], in_shape[1] * stride * stride, in_shape[2] / stride, in_shape[3] / stride};
+
+ auto test_case = test::TestCase<TestEngine>(fun);
+ test_case.add_input<float>(inputs);
+ test_case.add_expected_output<float>(expected_shape, expected_result);
+ test_case.run();
+}
+
+NGRAPH_TEST(${BACKEND_NAME}, reorg_yolo_stride_3)
+{
+ // in_shape [N,C,H,W]
+ const auto in_shape = Shape{1, 9, 3, 3};
+ auto p = make_shared<op::Parameter>(element::f32, in_shape);
+ size_t stride = 3;
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(p, Strides{stride});
+ auto fun = make_shared<Function>(OutputVector{reorg_yolo}, ParameterVector{p});
+
+ std::vector<float> inputs(81);
+ std::iota(inputs.begin(), inputs.end(), 0);
+ std::vector<float> expected_result{
+ 0, 3, 6, 27, 30, 33, 54, 57, 60, 1, 4, 7, 28, 31, 34, 55, 58, 61, 2, 5, 8,
+ 29, 32, 35, 56, 59, 62, 9, 12, 15, 36, 39, 42, 63, 66, 69, 10, 13, 16, 37, 40, 43,
+ 64, 67, 70, 11, 14, 17, 38, 41, 44, 65, 68, 71, 18, 21, 24, 45, 48, 51, 72, 75, 78,
+ 19, 22, 25, 46, 49, 52, 73, 76, 79, 20, 23, 26, 47, 50, 53, 74, 77, 80};
+ // in_shape [N,C,H,W] -> out_shape [N, C*stride*stride, H/stride, W/stride]
+ Shape expected_shape = Shape{
+ in_shape[0], in_shape[1] * stride * stride, in_shape[2] / stride, in_shape[3] / stride};
+
+ auto test_case = test::TestCase<TestEngine>(fun);
+ test_case.add_input<float>(inputs);
+ test_case.add_expected_output<float>(expected_shape, expected_result);
+ test_case.run();
+}
#include "ngraph/runtime/reference/product.hpp"
#include "ngraph/runtime/reference/quantize.hpp"
#include "ngraph/runtime/reference/relu.hpp"
+#include "ngraph/runtime/reference/reorg_yolo.hpp"
#include "ngraph/runtime/reference/replace_slice.hpp"
#include "ngraph/runtime/reference/reshape.hpp"
#include "ngraph/runtime/reference/result.hpp"
pbox->get_attrs());
break;
}
+ case OP_TYPEID::ReorgYolo_v0:
+ {
+ const op::v0::ReorgYolo* reorg_yolo = static_cast<const op::v0::ReorgYolo*>(&node);
+ runtime::reference::reorg_yolo(args[0]->get_data_ptr<char>(),
+ out[0]->get_data_ptr<char>(),
+ args[0]->get_shape(),
+ reorg_yolo->get_strides().at(0),
+ args[0]->get_element_type().size());
+ break;
+ }
case OP_TYPEID::Quantize:
{
const op::Quantize* quantize = static_cast<const op::Quantize*>(&node);
#define ID_SUFFIX(NAME) NAME##_v0
NGRAPH_OP(CTCGreedyDecoder, ngraph::op::v0)
NGRAPH_OP(DetectionOutput, op::v0)
+NGRAPH_OP(ReorgYolo, op::v0)
NGRAPH_OP(RNNCell, op::v0)
#undef ID_SUFFIX
--- /dev/null
+//*****************************************************************************
+// Copyright 2017-2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//*****************************************************************************
+
+#include "gtest/gtest.h"
+#include "ngraph/ngraph.hpp"
+#include "util/type_prop.hpp"
+
+using namespace std;
+using namespace ngraph;
+
+TEST(type_prop, reorg_yolo_stride_2)
+{
+ const auto in_shape = Shape{1, 64, 26, 26};
+ size_t stride = 2;
+ auto data_param = make_shared<op::Parameter>(element::f32, in_shape);
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(data_param, stride);
+
+ // in_shape [N,C,H,W] -> out_shape [N, C*stride*stride, H/stride, W/stride]
+ Shape expected_shape = Shape{1, 256, 13, 13};
+
+ EXPECT_EQ(reorg_yolo->get_output_shape(0), expected_shape);
+}
+
+TEST(type_prop, reorg_yolo_stride_2_batch_2)
+{
+ const auto in_shape = Shape{2, 64, 26, 26};
+ size_t stride = 2;
+ auto data_param = make_shared<op::Parameter>(element::f32, in_shape);
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(data_param, stride);
+
+ // in_shape [N,C,H,W] -> out_shape [N, C*stride*stride, H/stride, W/stride]
+ Shape expected_shape = Shape{2, 256, 13, 13};
+
+ EXPECT_EQ(reorg_yolo->get_output_shape(0), expected_shape);
+}
+
+TEST(type_prop, reorg_yolo_stride_2_smaller_H)
+{
+ const auto in_shape = Shape{1, 24, 34, 62};
+ size_t stride = 2;
+ auto data_param = make_shared<op::Parameter>(element::f32, in_shape);
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(data_param, stride);
+
+ // in_shape [N,C,H,W] -> out_shape [N, C*stride*stride, H/stride, W/stride]
+ Shape expected_shape = Shape{1, 96, 17, 31};
+ EXPECT_EQ(reorg_yolo->get_output_shape(0), expected_shape);
+}
+
+TEST(type_prop, reorg_yolo_stride_3)
+{
+ const auto in_shape = Shape{1, 9, 3, 3};
+ size_t stride = 3;
+ auto data_param = make_shared<op::Parameter>(element::f32, in_shape);
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(data_param, stride);
+
+ // in_shape [N,C,H,W] -> out_shape [N, C*stride*stride, H/stride, W/stride]
+ Shape expected_shape = Shape{
+ in_shape[0], in_shape[1] * stride * stride, in_shape[2] / stride, in_shape[3] / stride};
+
+ EXPECT_EQ(reorg_yolo->get_output_shape(0), expected_shape);
+}
+
+TEST(type_prop, reorg_yolo_catch_small_shape_stride)
+{
+ const auto in_shape = Shape{1, 1, 4, 4};
+ size_t stride = 2;
+ auto data_param = make_shared<op::Parameter>(element::f32, in_shape);
+ try
+ {
+ // Throw error test: For [N, C, H, W] input shape, C >= (stride*stride) is required.
+ auto reorg_yolo = make_shared<op::v0::ReorgYolo>(data_param, stride);
+
+ // Should have thrown, so fail if it didn't
+ FAIL() << "Incompatible stride was not detected.";
+ }
+ catch (const ngraph_error& error)
+ {
+ EXPECT_HAS_SUBSTRING(error.what(), std::string("stride"));
+ }
+ catch (...)
+ {
+ FAIL() << "Stride size check failed for unexpected reason.";
+ }
+}