From ef70e5187c3374a92616f1ff9a985e89a960238f Mon Sep 17 00:00:00 2001 From: Jozef Daniecki Date: Mon, 19 Apr 2021 13:12:09 +0200 Subject: [PATCH] Deformable convolution (#4312) * Add deformable_convolution unit tests * add 2D unit test * Add unit-tests for 3D deformable_convolution * create shared test class for deformable_convolution * create single layer test for cpu plugin * create single layer test for serialization * add deformable_convolution to opset1 * create empty evaluate method * add group and deformable_group to parameters * Create impl for generateInput method * add deformable_val to deformable_conv paramset * create additional unit-tests * Remove 3D single layer tests * Update GenerateInput and SetUp method * Update parameters values for SLT * Update GenerateInput method and create Validate method * Create additional parameters set for cpu plugin SLT * Create unit-test with padding and add it to disabled * add interpreter unit tests to manifest * style-apply * create file for reference impl * Update year of copyright and make Validate an override method * Update parameters names for serialization single layer tests * Update parameters names for functional single layer tests * add failing unit tests for interpreter to manifest * make tests parameters more readable * style-apply * Include deformable_convolution inside evaluates_map * add support for groups parameter for reference impl * style-apply * remove DeformableConvolutionParams struct * fix bug with filter * fix bug with offset type * Update interpreter manifest * impl evalute method * style-apply * Update year * Update test names * add utils func for deformable convolution operation * fix filter group count * add calculation of index of offset * Update offsets in unit test * add support for multiple input channels * add padding tests * add padding support * style apply * update copyright year * create validation check helper * Update convolve function name * update copyright year * style-apply * remove integer type from serialize layer tests * add tests for deformable_groups * fix bug with group > 1 * style-apply * add group unit test * create additional group tests * fix bug with groups attribute * Enhance dynamic shape inference of validate and infer types method * Add type_prop unit tests * Fix broken op create test in python api * fix bug with shapes in group tests * update deformable_convolution method * add unit test with 2 groups and 2 defromable groups * Fix code style. * Update UT manifests with current test status. * Refactored backend test: names, removed duplication, add TOODs * Add missing test cases in 'integral offsets' group. * Fixed group attribute. * Update interprer manifest to disable tests with integer offsets. * Fix style. * Remove changes in operator class. * Revert "Enhance dynamic shape inference of validate and infer types method" This reverts commit 2f9ce2ccd4e9a7b1143ebe497015972c0922e8aa. * Revert "Add type_prop unit tests" This reverts commit 944af98b8c5f4a5055c26f7585b93b34dc74055e. * Revert "Fix broken op create test in python api" This reverts commit 72fbfc29679fd719b0f3cad74701d443a1ee51bb. * Fix op class. * Convert implementation to 2D. * Simplify implementation. * Fix centos build. * Reimplemented offsets handling. * Fixed integral offsets test cases. * Fixed deformable group attribute. * Add bilinear interpolation. * Refactoring regarding tolerance_bits. * Fix groups & def_groups test case. * Add more unit tests for group & defgroup attribute. * Remove debug code. * Minor refactoring. * Add integer types to SLT. * Revert "Add integer types to SLT." This reverts commit 2fefe8926da65171f64a2dc679ab548415736213. * Add tests with real number offsets. * Refactored bilinear_interpolation(). * Turned on SLT. Additionally refactored and offset input set to range <0,2>. * Update headers with short version. * Fix SLT offests generation with int offsets. * Add integer types to SLT. * Fix grup + def_group test case. * Add ticket to address IE_CPU backend test failures * Enable real resolution for deformable values * Add op to list of trusted operations in python script * Fix comparison of integer expressions of different signedness compilation error * Add comment with closing namespace and empty lines Co-authored-by: pszmel Co-authored-by: ggalieroc --- .../single_layer/deformable_convolution.cpp | 68 + .../deformable_convolution.cpp | 92 + .../deformable_convolution.hpp | 15 + .../single_layer/deformable_convolution.hpp | 53 + .../single_layer/deformable_convolution.cpp | 84 + .../layer_tests_summary/summarize.py | 1 + .../reference/deformable_convolution.hpp | 234 ++ ngraph/core/src/op/deformable_convolution.cpp | 9 +- ngraph/test/CMakeLists.txt | 1 + .../backend/deformable_convolution.in.cpp | 2622 +++++++++++++++++ ngraph/test/runtime/ie/unit_test.manifest | 11 + .../runtime/interpreter/evaluates_map.cpp | 32 + .../runtime/interpreter/opset_int_tbl.hpp | 1 + ngraph/test/type_prop/convolution.cpp | 80 - .../test/type_prop/deformable_convolution.cpp | 88 +- 15 files changed, 3305 insertions(+), 86 deletions(-) create mode 100644 inference-engine/tests/functional/inference_engine/serialization/single_layer/deformable_convolution.cpp create mode 100644 inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp create mode 100644 inference-engine/tests/functional/plugin/shared/include/single_layer_tests/deformable_convolution.hpp create mode 100644 inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/deformable_convolution.hpp create mode 100644 inference-engine/tests/functional/shared_test_classes/src/single_layer/deformable_convolution.cpp create mode 100644 ngraph/core/reference/include/ngraph/runtime/reference/deformable_convolution.hpp create mode 100644 ngraph/test/backend/deformable_convolution.in.cpp diff --git a/inference-engine/tests/functional/inference_engine/serialization/single_layer/deformable_convolution.cpp b/inference-engine/tests/functional/inference_engine/serialization/single_layer/deformable_convolution.cpp new file mode 100644 index 00000000000..99b6f398d5f --- /dev/null +++ b/inference-engine/tests/functional/inference_engine/serialization/single_layer/deformable_convolution.cpp @@ -0,0 +1,68 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "shared_test_classes/single_layer/deformable_convolution.hpp" + +using namespace LayerTestsDefinitions; + +namespace { +TEST_P(DeformableConvolutionLayerTest, Serialize) { + Serialize(); +} + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP16, + InferenceEngine::Precision::I32, InferenceEngine::Precision::I16}; +const std::vector> offsets = {{1, 18, 28, 28}}; +const std::vector> filters = {{1, 1, 3, 3}}; +const std::vector> strides = {{1, 1}}; +const std::vector> padBegins = {{0, 0}}; +const std::vector> padEnds ={{0, 0}}; +const std::vector> dilations = {{1, 1}}; +const std::vector groups = {1}; +const std::vector defor_groups = {1}; +const std::vector numOutChannels = {1}; + +const auto conv2DParams_ExplicitPadding = ::testing::Combine( + ::testing::ValuesIn(offsets), ::testing::ValuesIn(filters), + ::testing::ValuesIn(strides), ::testing::ValuesIn(padBegins), + ::testing::ValuesIn(padEnds), ::testing::ValuesIn(dilations), + ::testing::ValuesIn(groups), ::testing::ValuesIn(defor_groups), + ::testing::ValuesIn(numOutChannels), + ::testing::Values(ngraph::op::PadType::EXPLICIT)); +const auto conv2DParams_AutoPadValid = ::testing::Combine( + ::testing::ValuesIn(offsets), ::testing::ValuesIn(filters), + ::testing::ValuesIn(strides), + ::testing::Values(std::vector({0, 0})), + ::testing::Values(std::vector({0, 0})), + ::testing::ValuesIn(dilations), ::testing::ValuesIn(groups), + ::testing::ValuesIn(defor_groups), ::testing::ValuesIn(numOutChannels), + ::testing::Values(ngraph::op::PadType::VALID)); + +INSTANTIATE_TEST_CASE_P( + smoke_DeformableConvolution2D_Serialization_ExplicitPadding, DeformableConvolutionLayerTest, + ::testing::Combine( + conv2DParams_ExplicitPadding, ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 1, 28, 28})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + DeformableConvolutionLayerTest::getTestCaseName); + +INSTANTIATE_TEST_CASE_P( + smoke_DeformableConvolution2D__Serialization_AutoPadValid, DeformableConvolutionLayerTest, + ::testing::Combine( + conv2DParams_AutoPadValid, ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 1, 28, 28})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + DeformableConvolutionLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp new file mode 100644 index 00000000000..e54812fe516 --- /dev/null +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/deformable_convolution.cpp @@ -0,0 +1,92 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include "common_test_utils/test_constants.hpp" +#include "single_layer_tests/deformable_convolution.hpp" + +using namespace LayerTestsDefinitions; + +namespace { + +const std::vector netPrecisions = { + InferenceEngine::Precision::FP32, InferenceEngine::Precision::FP16, + InferenceEngine::Precision::I32, InferenceEngine::Precision::I16}; + +/* ============= 2D DeformableConvolution ============= */ +const std::vector> deformable_vals = {{1, 18, 28, 28}}; +const std::vector> kernels = {{1, 1, 3, 3}}; +const std::vector> strides = {{1, 1}}; +const std::vector> padBegins = {{0, 0}}; +const std::vector> padEnds ={{0, 0}}; +const std::vector> dilations = {{1, 1}}; +const std::vector groups = {1}; +const std::vector defor_groups = {1}; +const std::vector numOutChannels = {1, 5}; +const std::vector multiple_defor_groups = {4}; +const std::vector> deform_vals = {{1, 200, 220, 220}}; +const std::vector> kernel = {{64, 4, 5, 5}}; + +const auto deformableConv2DParams_ExplicitPadding = ::testing::Combine( + ::testing::ValuesIn(deformable_vals), + ::testing::ValuesIn(kernels), ::testing::ValuesIn(strides), + ::testing::ValuesIn(padBegins), ::testing::ValuesIn(padEnds), + ::testing::ValuesIn(dilations), ::testing::ValuesIn(groups), + ::testing::ValuesIn(defor_groups), ::testing::ValuesIn(numOutChannels), + ::testing::Values(ngraph::op::PadType::EXPLICIT)); +const auto deformableConv2DParams_AutoPadValid = ::testing::Combine( + ::testing::ValuesIn(deformable_vals), + ::testing::ValuesIn(kernels), ::testing::ValuesIn(strides), + ::testing::Values(std::vector({0, 0})), + ::testing::Values(std::vector({0, 0})), + ::testing::ValuesIn(dilations), ::testing::ValuesIn(groups), + ::testing::ValuesIn(defor_groups), ::testing::ValuesIn(numOutChannels), + ::testing::Values(ngraph::op::PadType::VALID)); + +const auto deformableConv2DParams_DeformableGroups_AutoPadExplicit = ::testing::Combine( + ::testing::ValuesIn(deform_vals), + ::testing::ValuesIn(kernel), ::testing::ValuesIn(strides), + ::testing::Values(std::vector({0, 0})), + ::testing::Values(std::vector({0, 0})), + ::testing::ValuesIn(dilations), ::testing::ValuesIn(groups), + ::testing::ValuesIn(multiple_defor_groups), ::testing::ValuesIn(numOutChannels), + ::testing::Values(ngraph::op::PadType::EXPLICIT)); + +INSTANTIATE_TEST_CASE_P( + smoke_DeformableConvolution2D_ExplicitPadding, DeformableConvolutionLayerTest, + ::testing::Combine( + deformableConv2DParams_ExplicitPadding, ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 1, 30, 30})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + DeformableConvolutionLayerTest::getTestCaseName); + +INSTANTIATE_TEST_CASE_P( + smoke_DeformableConvolution2D_AutoPadValid, DeformableConvolutionLayerTest, + ::testing::Combine( + deformableConv2DParams_AutoPadValid, ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 1, 30, 30})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + DeformableConvolutionLayerTest::getTestCaseName); + +INSTANTIATE_TEST_CASE_P( + smoke_DeformableConvolution2D_DeformableGroups_ExplicitPadding, DeformableConvolutionLayerTest, + ::testing::Combine( + deformableConv2DParams_DeformableGroups_AutoPadExplicit, ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 4, 224, 224})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + DeformableConvolutionLayerTest::getTestCaseName); +} // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/deformable_convolution.hpp b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/deformable_convolution.hpp new file mode 100644 index 00000000000..f67e8a12364 --- /dev/null +++ b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/deformable_convolution.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "shared_test_classes/single_layer/deformable_convolution.hpp" + +namespace LayerTestsDefinitions { + +TEST_P(DeformableConvolutionLayerTest, CompareWithRefs) { + Run(); +} + +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/deformable_convolution.hpp b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/deformable_convolution.hpp new file mode 100644 index 00000000000..bc7a614a106 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/deformable_convolution.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +#include "shared_test_classes/base/layer_test_utils.hpp" +#include "ngraph_functions/builders.hpp" +#include "ngraph_functions/utils/ngraph_helpers.hpp" + +namespace LayerTestsDefinitions { + +// ! [test_convolution:definition] +typedef std::tuple< + InferenceEngine::SizeVector, // Deformable values size + InferenceEngine::SizeVector, // Kernel size + InferenceEngine::SizeVector, // Strides + std::vector, // Pad begin + std::vector, // Pad end + InferenceEngine::SizeVector, // Dilation + size_t, // Groups + size_t, // Deformable groups + size_t, // Num out channels + ngraph::op::PadType // Padding type +> deformableConvSpecificParams; +typedef std::tuple< + deformableConvSpecificParams, + InferenceEngine::Precision, // Net precision + InferenceEngine::Precision, // Input precision + InferenceEngine::Precision, // Output precision + InferenceEngine::Layout, // Input layout + InferenceEngine::Layout, // Output layout + InferenceEngine::SizeVector, // Input shapes + LayerTestsUtils::TargetDevice // Device name +> deformableConvLayerTestParamsSet; + +class DeformableConvolutionLayerTest : public testing::WithParamInterface, + virtual public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + InferenceEngine::Blob::Ptr GenerateInput(const InferenceEngine::InputInfo &info) const override; + +protected: + void SetUp() override; +}; +// ! [test_convolution:definition] + +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/shared_test_classes/src/single_layer/deformable_convolution.cpp b/inference-engine/tests/functional/shared_test_classes/src/single_layer/deformable_convolution.cpp new file mode 100644 index 00000000000..c902e5a9ba1 --- /dev/null +++ b/inference-engine/tests/functional/shared_test_classes/src/single_layer/deformable_convolution.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "shared_test_classes/single_layer/deformable_convolution.hpp" + +namespace LayerTestsDefinitions { + +std::string DeformableConvolutionLayerTest::getTestCaseName(testing::TestParamInfo obj) { + deformableConvSpecificParams convParams; + InferenceEngine::Precision netPrecision; + InferenceEngine::Precision inPrc, outPrc; + InferenceEngine::Layout inLayout, outLayout; + InferenceEngine::SizeVector inputShapes; + std::string targetDevice; + std::tie(convParams, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShapes, targetDevice) = + obj.param; + ngraph::op::PadType padType; + InferenceEngine::SizeVector offsets, filter, stride, dilation; + std::vector padBegin, padEnd; + size_t groups, deformable_groups, convOutChannels; + std::tie(offsets, filter, stride, padBegin, padEnd, dilation, groups, deformable_groups, convOutChannels, padType) = convParams; + + std::ostringstream result; + result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_"; + result << "DV" << CommonTestUtils::vec2str(offsets) << "_"; + result << "K" << CommonTestUtils::vec2str(filter) << "_"; + result << "S" << CommonTestUtils::vec2str(stride) << "_"; + result << "PB" << CommonTestUtils::vec2str(padBegin) << "_"; + result << "PE" << CommonTestUtils::vec2str(padEnd) << "_"; + result << "D=" << CommonTestUtils::vec2str(dilation) << "_"; + result << "G=" << groups << "_"; + result << "DG=" << deformable_groups << "_"; + result << "O=" << convOutChannels << "_"; + result << "AP=" << padType << "_"; + result << "netPRC=" << netPrecision.name() << "_"; + result << "inPRC=" << inPrc.name() << "_"; + result << "outPRC=" << outPrc.name() << "_"; + result << "inL=" << inLayout << "_"; + result << "outL=" << outLayout << "_"; + result << "trgDev=" << targetDevice; + return result.str(); +} + +InferenceEngine::Blob::Ptr DeformableConvolutionLayerTest::GenerateInput(const InferenceEngine::InputInfo &info) const { + InferenceEngine::Blob::Ptr blobPtr; + const std::string& name = info.name(); + if (name == "a_data") { + blobPtr = LayerTestsUtils::LayerTestsCommon::GenerateInput(info); + } else if (name == "b_offset_vals") { + blobPtr = FuncTestUtils::createAndFillBlobFloat(info.getTensorDesc(), 2, 0, 10); + } else if (name == "c_filter_vals") { + blobPtr = LayerTestsUtils::LayerTestsCommon::GenerateInput(info); + } + return blobPtr; +} + +void DeformableConvolutionLayerTest::SetUp() { + deformableConvSpecificParams convParams; + std::vector inputShape; + InferenceEngine::Precision netPrecision; + std::tie(convParams, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, targetDevice) = + this->GetParam(); + ngraph::op::PadType padType; + InferenceEngine::SizeVector offsets, filter, stride, dilation; + std::vector padBegin, padEnd; + size_t groups, deformable_groups, convOutChannels; + std::tie(offsets, filter, stride, padBegin, padEnd, dilation, groups, deformable_groups, convOutChannels, padType) = convParams; + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + auto params = ngraph::builder::makeParams(ngPrc, {inputShape, offsets, filter}); + auto paramOuts = ngraph::helpers::convert2OutputVector( + ngraph::helpers::castOps2Nodes(params)); + auto data = std::make_shared(ngPrc, ngraph::Shape(inputShape)); + data->set_friendly_name("a_data"); + auto offset_vals = std::make_shared(ngPrc, ngraph::Shape(offsets)); + offset_vals->set_friendly_name("b_offset_vals"); + auto filter_vals = std::make_shared(ngPrc, ngraph::Shape(filter)); + filter_vals->set_friendly_name("c_filter_vals"); + auto deformable_conv = std::make_shared(data, offset_vals, filter_vals, + stride, padBegin, padEnd, dilation, padType, groups, deformable_groups); + ngraph::ResultVector results{std::make_shared(deformable_conv)}; + function = std::make_shared(results, ngraph::ParameterVector{data, offset_vals, filter_vals}, "deformable_convolution"); +} +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/summarize.py b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/summarize.py index 0c85fb0991f..edb0c5fab9d 100644 --- a/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/summarize.py +++ b/inference-engine/tests/ie_test_utils/functional_test_utils/layer_tests_summary/summarize.py @@ -38,6 +38,7 @@ verified_operations = [ 'Concat-0', 'ConvertLike-1', 'Convolution-1', + 'DeformableConvolution-1', 'DetectionOutput-0', 'Divide-1', 'ExperimentalDetectronDetectionOutput-6', diff --git a/ngraph/core/reference/include/ngraph/runtime/reference/deformable_convolution.hpp b/ngraph/core/reference/include/ngraph/runtime/reference/deformable_convolution.hpp new file mode 100644 index 00000000000..d2a9e867f8e --- /dev/null +++ b/ngraph/core/reference/include/ngraph/runtime/reference/deformable_convolution.hpp @@ -0,0 +1,234 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "ngraph/runtime/reference/convolution.hpp" + +namespace ngraph +{ + namespace runtime + { + namespace reference + { + namespace def_conv_impl + { + inline void validate_params(const Shape& in_shape, + const Shape& o_shape, + const Shape& f_shape, + const Strides& strides, + const Strides& dilations, + const CoordinateDiff& pads_begin, + const CoordinateDiff& pads_end) + { + // this implementation supports 2D deformable convolutions + NGRAPH_CHECK(in_shape.size() == 4, "Unsupported input rank: ", in_shape); + + NGRAPH_CHECK(o_shape.size() == 4, "Unsupported offset rank: ", o_shape); + + NGRAPH_CHECK(f_shape.size() == 4, "Unsupported kernel rank: ", f_shape); + + const auto spatial_dims = in_shape.size() - 2; + NGRAPH_CHECK(strides.size() == spatial_dims, + "Strides not definied for all and only spatial dimensions"); + + NGRAPH_CHECK(dilations.size() == spatial_dims, + "Dilations not defined for all and only spatial dimensions"); + + NGRAPH_CHECK((pads_begin.size() == pads_end.size()) && + (pads_begin.size() == spatial_dims), + "Pads not defined for all and only spatial dimensions"); + } + + inline Shape shape_reduce(const Shape& s) { return Shape(++s.begin(), s.end()); } + + inline Shape shape_scale(Shape s, size_t groups) + { + s[0] /= groups; + return s; + } + + template + inline float bilinear_interpolation(const inputType* data, + const float x_idx, + const float y_idx, + const int x_size, + const int y_size) + { + const int x1 = std::max(static_cast(std::floor(x_idx)), 0); + const int x2 = std::min(static_cast(std::ceil(x_idx)), x_size - 1); + const int y1 = std::max(static_cast(std::floor(y_idx)), 0); + const int y2 = std::min(static_cast(std::ceil(y_idx)), y_size - 1); + + const float distX = x_idx - x1; + const float distY = y_idx - y1; + + const float value11 = data[y1 * x_size + x1]; + const float value12 = data[y2 * x_size + x1]; + const float value21 = data[y1 * x_size + x2]; + const float value22 = data[y2 * x_size + x2]; + + const float value = (1 - distX) * (1 - distY) * value11 + + (1 - distX) * distY * value12 + + distX * (1 - distY) * value21 + distX * distY * value22; + return value; + } + + template + void convolve_2D_channels(const ConvolutionParams& p, + const int64_t deformable_groups, + const T* batch, + const Shape& batch_shape, + const T* offsets, + const Shape& offset_shape, + const T* filter, + const Shape& filter_shape, + T* out) + { + const int input_size_y = batch_shape[1]; + const int input_size_x = batch_shape[2]; + const int filter_size_y = filter_shape[1]; + const int filter_size_x = filter_shape[2]; + const int dilated_filter_size_y = + filter_size_y + (filter_size_y - 1) * (p.dilation[0] - 1); + const int dilated_filter_size_x = + filter_size_x + (filter_size_x - 1) * (p.dilation[1] - 1); + + const int input_channel_size = shape_size(shape_reduce(batch_shape)); + const int filter_channel_size = shape_size(shape_reduce(filter_shape)); + const int offsets_size = shape_size(offset_shape); + const int offsets_spatial_size = shape_size(shape_reduce(offset_shape)); + const int offsets_channel_size = 2 * offsets_spatial_size; + const int filter_channels_count = filter_shape[0]; + + int out_idx = 0; + for (int i_y = -p.pads_begin[0]; + i_y <= (p.pads_end[0] + input_size_y - dilated_filter_size_y); + i_y += p.strides[0]) + { + for (int i_x = -p.pads_begin[1]; + i_x <= (p.pads_end[1] + input_size_x - dilated_filter_size_x); + i_x += p.strides[1]) + { + auto input_channel = batch; + auto filter_channel = filter; + T sum = 0; + auto group_offsets_channel = offsets; + for (int dg = 0; dg < deformable_groups; dg++) + { + for (int fc = 0; fc < filter_channels_count / deformable_groups; + fc++) + { + auto offsets_channel = group_offsets_channel; + for (int f_y = 0; f_y < filter_size_y; ++f_y) + { + for (int f_x = 0; f_x < filter_size_x; ++f_x) + { + T y_offset = offsets_channel[out_idx]; + T x_offset = + offsets_channel[offsets_spatial_size + out_idx]; + T rel_i_y = i_y + (f_y * p.dilation[0]) + y_offset; + T rel_i_x = i_x + (f_x * p.dilation[1]) + x_offset; + + offsets_channel += offsets_channel_size; + bool padding = !(in_range(rel_i_x, {0, input_size_x}) && + in_range(rel_i_y, {0, input_size_y})); + if (padding) + continue; + + int f_buf_idx = (f_y * filter_size_x) + f_x; + sum += bilinear_interpolation(input_channel, + rel_i_x, + rel_i_y, + input_size_x, + input_size_y) * + filter_channel[f_buf_idx]; + } + } + input_channel += input_channel_size; + filter_channel += filter_channel_size; + } + group_offsets_channel += offsets_size / deformable_groups; + } + out[out_idx++] = sum; + } + } + } + + } // namespace def_conv_impl + template + void deformable_convolution(const T* in, + const T* offsets, + const T* filters, + T* out, + const Shape& in_shape, + const Shape& o_shape, + const Shape& f_shape, + const Shape& out_shape, + const Strides& strides, + const Strides& dilation, + const CoordinateDiff& pads_begin, + const CoordinateDiff& pads_end, + const int64_t groups, + const int64_t deformable_groups) + + { + using namespace def_conv_impl; + + validate_params( + in_shape, o_shape, f_shape, strides, dilation, pads_begin, pads_end); + + // here we are converting all param types to int's to avoid arithmetic issues + // (e.g signed + unsigned) in indexes calculation later + ConvolutionParams params{strides, dilation, pads_begin, pads_end}; + const size_t groups_count = static_cast(groups); + + const size_t batches_count = in_shape[in_batch_axis]; + const Shape group_in_shape = shape_scale(shape_reduce(in_shape), groups); + const size_t group_in_size = shape_size(group_in_shape); + + const Shape group_offset_shape = shape_scale(shape_reduce(o_shape), groups); + const size_t group_offset_size = shape_size(group_offset_shape); + const size_t group_offset_batch_size = shape_size(shape_reduce(o_shape)); + const size_t deformable_groups_per_group = + std::ceil(static_cast(deformable_groups) / static_cast(groups)); + + const size_t group_filters_count = f_shape[filter_out_ch_axis] / groups; + const Shape group_filter_shape = shape_reduce(f_shape); + const size_t group_filter_size = shape_size(group_filter_shape); + + const size_t out_ch_size = shape_size(shape_reduce(shape_reduce(out_shape))); + + for (size_t batch_idx = 0; batch_idx < batches_count; ++batch_idx) + { + const T* group_filters = filters; + const T* group_offsets = offsets; + for (size_t group_idx = 0; group_idx < groups_count; ++group_idx) + { + for (size_t f_idx = 0; f_idx < group_filters_count; ++f_idx) + { + convolve_2D_channels(params, + deformable_groups_per_group, + in, + group_in_shape, + group_offsets, + group_offset_shape, + group_filters, + group_filter_shape, + out); + group_filters += group_filter_size; + out += out_ch_size; + } + in += group_in_size; + if (deformable_groups > 1) + { + group_offsets += (deformable_groups_per_group * group_offset_size); + } + } + offsets += group_offset_batch_size; + } + } + } // namespace reference + } // namespace runtime +} // namespace ngraph diff --git a/ngraph/core/src/op/deformable_convolution.cpp b/ngraph/core/src/op/deformable_convolution.cpp index bdfd057ce8f..eb5071af7de 100644 --- a/ngraph/core/src/op/deformable_convolution.cpp +++ b/ngraph/core/src/op/deformable_convolution.cpp @@ -171,13 +171,18 @@ void op::v1::DeformableConvolution::validate_and_infer_types() return; } } - + // adjust filter shape to reuse regular infer_convolution_forward() + const auto new_filters_pshape = [&](int groups) { + auto new_shape(filters_shape); + new_shape[1] *= groups; + return new_shape; + }(m_group); result_shape = infer_convolution_forward(this, data_batch_shape, Strides(m_strides.size(), 1), // dummy data dilations m_pads_begin, m_pads_end, - filters_shape, + new_filters_pshape, m_strides, m_dilations); diff --git a/ngraph/test/CMakeLists.txt b/ngraph/test/CMakeLists.txt index 53076ef28c1..b158eb7c77b 100644 --- a/ngraph/test/CMakeLists.txt +++ b/ngraph/test/CMakeLists.txt @@ -325,6 +325,7 @@ set(MULTI_TEST_SRC backend/detection_output.in.cpp backend/dft.in.cpp backend/divide.in.cpp + backend/deformable_convolution.in.cpp backend/dyn_reshape.in.cpp backend/strided_slice.in.cpp backend/dynamic.in.cpp diff --git a/ngraph/test/backend/deformable_convolution.in.cpp b/ngraph/test/backend/deformable_convolution.in.cpp new file mode 100644 index 00000000000..a26c704e40c --- /dev/null +++ b/ngraph/test/backend/deformable_convolution.in.cpp @@ -0,0 +1,2622 @@ +// Copyright (C) 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}); + +static void DeformableConvolutionTest(const std::vector& inputs, + const Shape inputs_shape, + const std::vector& offsets, + const Shape offsets_shape, + const std::vector& filter, + const Shape filter_shape, + const std::vector& outputs, + const Shape outputs_shape, + const Strides& strides, + const CoordinateDiff& padding, + const Strides& dilations, + const int64_t group = 1, + const int64_t deformable_group = 1, + const size_t tolerance_bits = 2) +{ + const CoordinateDiff pads_begin{padding}; + const CoordinateDiff pads_end{padding}; + const op::PadType auto_pad{op::PadType::EXPLICIT}; + auto inputs_param = make_shared(element::f32, inputs_shape); + auto offsets_param = make_shared(element::f32, offsets_shape); + auto filter_param = make_shared(element::f32, filter_shape); + auto conv = make_shared(inputs_param, + offsets_param, + filter_param, + strides, + pads_begin, + pads_end, + dilations, + auto_pad, + group, + deformable_group); + auto f = + make_shared(conv, ParameterVector{inputs_param, offsets_param, filter_param}); + auto test_case = test::TestCase(f); + test_case.add_input(inputs); + test_case.add_input(offsets); + test_case.add_input(filter); + test_case.add_expected_output(outputs_shape, outputs); + test_case.run(tolerance_bits); +} +// clang-format off + +// regular convolution attributes (zeroed offsets) +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_default) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{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}; + + const Shape filter_shape{1, 1, 2, 2}; + const std::vector filter{1.0f, 2.0f, + -1.0f, -2.0f}; + + const Shape offsets_shape{1, 8, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 3, 3}; + const std::vector outputs{-12.0f, -12.0f, -12.0f, + -12.0f, -12.0f, -12.0f, + -12.0f, -12.0f, -12.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_padding) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{1, 1}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 3, 3}; + const std::vector inputs{1.0f, 3.0f, 5.0f, + 7.0f, 5.0f, 3.0f, + 1.0f, 3.0f, 5.0f}; + + const Shape filter_shape{1, 1, 2, 2}; + const std::vector filter{1.0f, 2.0f, + 0.0f, 1.0f}; + + const Shape offsets_shape{1, 8, 4, 4}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 4, 4}; + const std::vector outputs{1.0f, 3.0f, 5.0f, 0.0f, + 9.0f, 12.0f, 16.0f, 5.0f, + 15.0f, 20.0f, 16.0f, 3.0f, + 2.0f, 7.0f, 13.0f, 5.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_stride) +{ + const Strides strides{2, 2}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 5, 5}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, + 7.0f, 5.0f, 3.0f, 1.0f, 0.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 1.0f, + 3.0f, 2.0f, 1.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 2, 2}; + const std::vector outputs{57.0f, 94.0f, + 66.0f, 102.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_dilation) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{2, 2}; + + const Shape inputs_shape{1, 1, 7, 7}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f, 13.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 0.0f, + 3.0f, 1.0f, 2.0f}; + + const Shape offsets_shape{1, 18, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 3, 3}; + const std::vector outputs{78.0f, 106.0f, 134.0f, + 44.0f, 16.0f, -12.0f, + 80.0f, 84.0f, 88.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_padding_strides_dilation) +{ + const Strides strides{2, 2}; + const CoordinateDiff padding{2, 2}; + const Strides dilations{2, 2}; + + const Shape inputs_shape{1, 1, 7, 7}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f, 13.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 0.0f, + 3.0f, 1.0f, 2.0f}; + + const Shape offsets_shape{1, 18, 4, 4}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 4, 4}; + const std::vector outputs{15.0f, 38.0f, 70.0f, 66.0f, + 33.0f, 78.0f, 134.0f, 103.0f, + 40.0f, 80.0f, 88.0f, 58.0f, + 30.0f, 56.0f, 72.0f, 34.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_input_channels) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 2, 4, 4}; + const std::vector inputs{ + // channel 1 + 1.0f, 3.0f, 5.0f, 7.0f, + 7.0f, 5.0f, 3.0f, 1.0f, + 2.0f, 4.0f, 6.0f, 8.0f, + 8.0f, 6.0f, 4.0f, 2.0f, + // channel 2 + -1.0f, 3.0f, -5.0f, 7.0f, + 7.0f, -5.0f, 3.0f, -1.0f, + -2.0f, 4.0f, -6.0f, 8.0f, + 8.0f, -6.0f, 4.0f, -2.0f}; + + const Shape filter_shape{1, 2, 3, 3}; + const std::vector filter{ + // channel 1 + 5.0f, 3.0f, 5.0f, + 1.0f, 3.0f, 1.0f, + 4.0f, 2.0f, 4.0f, + // channel 2 + -5.0f, 3.0f, 5.0f, + 1.0f, -3.0f, 1.0f, + 4.0f, 2.0f, -4.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 2, 2}; + const std::vector outputs{142.0f, 102.0f, + 94.0f, 160.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_output_channels) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{ + 1.0f, 3.0f, 5.0f, 7.0f, + 7.0f, 5.0f, 3.0f, 1.0f, + 2.0f, 4.0f, 6.0f, 8.0f, + 8.0f, 6.0f, 4.0f, 2.0f}; + + const Shape filter_shape{2, 1, 3, 3}; + const std::vector filter{ + // channel 1 + 5.0f, 3.0f, 5.0f, + 1.0f, 3.0f, 1.0f, + 4.0f, 2.0f, 4.0f, + // channel 2 + -5.0f, 3.0f, 5.0f, + 1.0f, -3.0f, 1.0f, + 4.0f, 2.0f, -4.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{ + // channel 1 + 104.0f, 140.0f, + 145.0f, 109.0f, + // channel 2 + 16.0f, 28.0f, + 19.0f, 7.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_batch) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{2, 1, 4, 4}; + const std::vector inputs{ + // batch 1 + 1.0f, 3.0f, 2.0f, 1.0f, + 1.0f, 3.0f, 3.0f, 1.0f, + 2.0f, 1.0f, 1.0f, 3.0f, + 3.0f, 2.0f, 3.0f, 3.0f, + // batch 2 + -1.0f, 3.0f, 2.0f, -1.0f, + 1.0f, 3.0f, -3.0f, 1.0f, + -2.0f, -1.0f, 1.0f, 3.0f, + 3.0f, 2.0f, 3.0f, -3.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{-5.0f, 3.0f, 5.0f, + 1.0f, -3.0f, 1.0f, + 4.0f, 2.0f, -4.0f}; + + const Shape offsets_shape{2, 18, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{2, 1, 2, 2}; + const std::vector outputs{ + // batch 1 + 15.0f, -15.0f, + 23.0f, 2.0f, + // batch 2 + -1.0f, -15.0f, + -5.0f, 6.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +// group & deformable_group attributes (zeroed offsets) +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_groups_basic) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 2; + + const Shape inputs_shape{1, 4, 3, 3}; + const std::vector inputs{ // channel 1 + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, + // channel 2 + 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, + // channel 3 + 19.0f, 20.0f, 21.0f, + 22.0f, 23.0f, 24.0f, + 25.0f, 26.0f, 27.0f, + // channel 4 + 28.0f, 29.0f, 30.0f, + 31.0f, 32.0f, 33.0f, + 34.0f, 35.0f, 36.0f}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{ // filter 1 channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // filter 1 channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // filter 2 channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // filter 2 channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 8, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{ // channel 1 + 356.0f, 392.0f, + 464.0f, 500.0f, + // channel 2 + -1004.0f, -1040.0f, + -1112.0f, -1148.0f}; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, dilations, group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_groups_complex) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 4; + + const Shape inputs_shape{1, 8, 3, 3}; + const std::vector inputs{ // channel 1 + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, + // channel 2 + 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, + // channel 3 + 19.0f, 20.0f, 21.0f, + 22.0f, 23.0f, 24.0f, + 25.0f, 26.0f, 27.0f, + // channel 4 + 28.0f, 29.0f, 30.0f, + 31.0f, 32.0f, 33.0f, + 34.0f, 35.0f, 36.0f, + // channel 5 + 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, + 43.0f, 44.0f, 45.0f, + // channel 6 + 46.0f, 47.0f, 48.0f, + 49.0f, 50.0f, 51.0f, + 52.0f, 53.0f, 54.0f, + // channel 7 + 55.0f, 56.0f, 57.0f, + 58.0f, 59.0f, 60.0f, + 61.0f, 62.0f, 63.0f, + // channel 8 + 64.0f, 65.0f, 66.0f, + 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f,}; + + const Shape filter_shape{4, 2, 2, 2}; + const std::vector filter{ // filter 1 channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // filter 1 channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // filter 2 channel 1 + 9.0f, 10.0f, + 11.0f, 12.0f, + // filter 2 channel 2 + 13.0f, 14.0f, + 15.0f, 16.0f, + // filter 3 channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // filter 3 channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // filter 4 channel 1 + -9.0f, -10.0f, + -11.0f, -12.0f, + // filter 4 channel 2 + -13.0f, -14.0f, + -15.0f, -16.0f}; + + const Shape offsets_shape{1, 8, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 4, 2, 2}; + const std::vector outputs{ // channel 1 + 356.0f, 392.0f, + 464.0f, 500.0f, + // channel 2 + 2636.0f, 2736.0f, + 2936.0f, 3036.0f, + // channel 3 + -1652.0f, -1688.0f, + -1760.0f, -1796.0f, + // channel 4 + -6236.0f, -6336.0f, + -6536.0f, -6636.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, dilations, group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_deforgroup) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 2, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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}; + + const Shape filter_shape{1, 2, 2, 2}; + const std::vector filter{// channel 1 + 1.0f, 2.0f, + -1.0f, -2.0f, + // channel 2 + 3.0f, 4.0f, + -3.0f, -4.0f}; + + const Shape offsets_shape{1, 8, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 1, 3, 3}; + const std::vector outputs{-40.0f, -40.0f, -40.0f, + -40.0f, -40.0f, -40.0f, + -40.0f, -40.0f, -40.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_zeroed_offsets_groups_and_deforgroups) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 2; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 4, 3, 3}; + const std::vector inputs{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}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{1.0f, 2.0f, + 3.0f, 4.0f, + 5.0f, 6.0f, + 7.0f, 8.0f, + -1.0f, -2.0f, + -3.0f, -4.0f, + -5.0f, -6.0f, + -7.0f, -8.0f, + }; + + const Shape offsets_shape{1, 16, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 0); + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{356.0f, 392.0f, + 464.0f, 500.0f, + -1004.0f, -1040.0f, + -1112.0f, -1148.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, + dilations, group, deformable_group); +} + +// deformable convolution atrributes (integral offsets) +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_default) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{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}; + + const Shape filter_shape{1, 1, 2, 2}; + const std::vector filter{1.0f, 2.0f, + -1.0f, -2.0f}; + + const Shape offsets_shape{1, 8, 3, 3}; + const std::vector offsets{// window 1 (Y=0, X=0) -> Y coordinate + 1.0f, 1.0f, 1.0f, // out1 .. out 3 + 1.0f, 1.0f, 1.0f, // out4 .. out 6 + 1.0f, 1.0f, 1.0f, // out7 .. out 9 + // window 1 (Y=0, X=0) -> X coordinate + 1.0f, 1.0f, 1.0f, // out1 .. out 3 + 1.0f, 1.0f, 1.0f, // out4 .. out 6 + 1.0f, 1.0f, 1.0f, // out7 .. out 9 + // window 2 + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + // window 2 + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + // window 3 + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + // window 3 + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + // window 4 + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + // window 4 + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + }; + + const Shape outputs_shape{1, 1, 3, 3}; + const std::vector outputs{-12.0f, -12.0f, -4.0f, + -12.0f, -12.0f, -4.0f, + 44.0f, 47.0f, 16.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_padding) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{1, 1}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{1.0f, 3.0f, 7.0f, 7.0f, + 7.0f, 6.0f, 3.0f, 1.0f, + 4.0f, 4.0f, 2.0f, 8.0f, + 1.0f, 1.0f, 1.0f, 2.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 0.0f, 1.0f, 0.0f, + 3.0f, 2.0f, 1.0f}; + + const Shape offsets_shape{1, 18, 4, 4}; + const std::vector offsets{1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f}; + + const Shape outputs_shape{1, 1, 4, 4}; + const std::vector outputs{56.0f, 39.0f, 44.0f, 18.0f, + 38.0f, 56.0f, 65.0f, 0.0f, + 19.0f, 38.0f, 20.0f, 20.0f, + 6.0f, 19.0f, 33.0f, 0.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_stride) +{ + const Strides strides{2, 2}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 5, 5}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, + 7.0f, 5.0f, 3.0f, 1.0f, 0.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 1.0f, + 3.0f, 2.0f, 1.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets{0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f, + 0.0f, 2.0f, + 1.0f, 0.0f}; + + const Shape outputs_shape{1, 1, 2, 2}; + const std::vector outputs{57.0f, 40.0f, + 38.0f, 102.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_dilation) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{2, 2}; + + const Shape inputs_shape{1, 1, 7, 7}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f, 13.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 0.0f, + 3.0f, 1.0f, 2.0f}; + + const Shape offsets_shape{1, 18, 3, 3}; + const std::vector offsets{1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 2.0f, 0.0f, + 0.0f, 2.0f, 0.0f, + 1.0f, 0.0f, 1.0f}; + + const Shape outputs_shape{1, 1, 3, 3}; + const std::vector outputs{16.0f, -2.0f, 134.0f, + 44.0f, -4.0f, -12.0f, + 10.0f, 84.0f, -4.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_padding_stride_dilation) +{ + const Strides strides{2, 2}; + const CoordinateDiff padding{2, 2}; + const Strides dilations{2, 2}; + + const Shape inputs_shape{1, 1, 7, 7}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f, 13.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 0.0f, + 3.0f, 1.0f, 2.0f}; + + const Shape offsets_shape{1, 18, 4, 4}; + const std::vector offsets{1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 2.0f}; + + const Shape outputs_shape{1, 1, 4, 4}; + const std::vector outputs{15.0f, 38.0f, 2.0f, 66.0f, + 26.0f, 78.0f, 134.0f, 16.0f, + 23.0f, 80.0f, -4.0f, 58.0f, + 13.0f, 56.0f, 72.0f, -4.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_input_channels) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 2, 4, 4}; + const std::vector inputs{ + // channel 1 + 1.0f, 3.0f, 5.0f, 7.0f, + 7.0f, 5.0f, 3.0f, 1.0f, + 2.0f, 4.0f, 6.0f, 8.0f, + 8.0f, 6.0f, 4.0f, 2.0f, + // channel 2 + -1.0f, 3.0f, -5.0f, 7.0f, + 7.0f, -5.0f, 3.0f, -1.0f, + -2.0f, 4.0f, -6.0f, 8.0f, + 8.0f, -6.0f, 4.0f, -2.0f}; + + const Shape filter_shape{1, 2, 3, 3}; + const std::vector filter{ + // channel 1 + 5.0f, 3.0f, 5.0f, + 1.0f, 3.0f, 1.0f, + 4.0f, 2.0f, 4.0f, + // channel 2 + -5.0f, 3.0f, 5.0f, + 1.0f, -3.0f, 1.0f, + 4.0f, 2.0f, -4.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets{1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f, + 1.0f, 1.0f, + 0.0f, 2.0f}; + + const Shape outputs_shape{1, 1, 2, 2}; + const std::vector outputs{160.0f, 32.0f, + 94.0f, 20.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_output_channels) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{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}; + + const Shape filter_shape{2, 1, 2, 2}; + const std::vector filter{ // filter 1 + 1.0f, 2.0f, + -1.0f, -2.0f, + // filter 2 + 3.0f, 4.0f, + -3.0f, -4.0f}; + + const Shape offsets_shape{1, 8, 3, 3}; + const std::vector offsets{//channel 1: Y offsets + 1.0f, 1.0f, 1.0f, // out1 .. out 3 + 1.0f, 1.0f, 1.0f, // out4 .. out 6 + 1.0f, 1.0f, 1.0f, // out7 .. out 9 + //channel 1: X offsets + 1.0f, 1.0f, 1.0f, // out1 .. out 3 + 1.0f, 1.0f, 1.0f, // out4 .. out 6 + 1.0f, 1.0f, 1.0f, // out7 .. out 9 + //channel 2: Y offsets + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + //channel 2: X offsets + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + //channel 3: Y offsets + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + //channel 3: X offsets + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + //channel 4: Y offsets + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + //channel 4: X offsets + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + }; + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{ + // output 1 + -12.0f, -12.0f, -4.0f, + -12.0f, -12.0f, -4.0f, + 44.0f, 47.0f, 16.0f, + // output 2 + -28.0f, -28.0f, -12.0f, + -28.0f, -28.0f, -12.0f, + 102.0f, 109.0f, 48.0f, }; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_batch) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + + const Shape inputs_shape{2, 1, 4, 4}; + const std::vector inputs{//batch 1 + 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, + //batch 2 + 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}; + + const Shape filter_shape{1, 1, 2, 2}; + const std::vector filter{1.0f, 2.0f, + -1.0f, -2.0f}; + + const Shape offsets_shape{2, 8, 3, 3}; + const std::vector offsets{// batch1 + 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, 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, 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, + 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, + // batch2 + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + }; + + const Shape outputs_shape{2, 1, 3, 3}; + const std::vector outputs{// batch 1 + -12.0f, -12.0f, -4.0f, + -12.0f, -12.0f, -4.0f, + 44.0f, 47.0f, 16.0f, + // batch 2 + -12.0f, -12.0f, -12.0f, + -12.0f, -12.0f, -12.0f, + -12.0f, -12.0f, -12.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, dilations); +} +// group & deformable_group attributes (integral offsets) +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_groups_basic) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 2; + + const Shape inputs_shape{1, 4, 3, 3}; + const std::vector inputs{ // channel 1 + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, + // channel 2 + 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, + // channel 3 + 19.0f, 20.0f, 21.0f, + 22.0f, 23.0f, 24.0f, + 25.0f, 26.0f, 27.0f, + // channel 4 + 28.0f, 29.0f, 30.0f, + 31.0f, 32.0f, 33.0f, + 34.0f, 35.0f, 36.0f}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{ // filter 1 channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // filter 1 channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // filter 2 channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // filter 2 channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 8, 2, 2}; + const std::vector offsets { + // window 1 (F_Y=0, F_X=0) -> I_Y coordinate + 1.0f, 0.0f, 2.0f, 1.0f, // out1 .. out 4 + // window 1 (F_Y=0, F_X=0) -> I_X coordinate + 0.0f, 1.0f, 1.0f, 2.0f, // out1 .. out 4 + // window 2 (F_Y=0, F_X=1) -> I_Y coordinate + 1.0f, 1.0f, 1.0f, 1.0f, // out1 .. out 4 + // window 2 (F_Y=0, F_X=1) -> I_X coordinate + 1.0f, 1.0f, 1.0f, 1.0f, // out1 .. out 4 + // window 3 (F_Y=1, F_X=0) -> I_Y coordinate + 2.0f, 2.0f, 2.0f, 2.0f, // out1 .. out 4 + // window 3 (F_Y=1, F_X=0) -> I_X coordinate + 2.0f, 2.0f, 2.0f, 2.0f, // out1 .. out 4 + // window 4 (F_Y=1, F_X=1) -> I_Y coordinate + 2.0f, 2.0f, 2.0f, 2.0f, // out1 .. out 4 + // window 4 (F_Y=1, F_X=1) -> I_X coordinate + 2.0f, 2.0f, 2.0f, 2.0f}; // out1 .. out 4 + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{ // channel 1 + 171.0f, 63.0f, + 126.0f, 0.0f, + // channel 2 + -423.0f, -171.0f, + -270.0f, 0.0f}; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, dilations, group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_groups_complex) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 4; + + const Shape inputs_shape{1, 8, 3, 3}; + const std::vector inputs{ // channel 1 + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, + // channel 2 + 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, + // channel 3 + 19.0f, 20.0f, 21.0f, + 22.0f, 23.0f, 24.0f, + 25.0f, 26.0f, 27.0f, + // channel 4 + 28.0f, 29.0f, 30.0f, + 31.0f, 32.0f, 33.0f, + 34.0f, 35.0f, 36.0f, + // channel 5 + 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, + 43.0f, 44.0f, 45.0f, + // channel 6 + 46.0f, 47.0f, 48.0f, + 49.0f, 50.0f, 51.0f, + 52.0f, 53.0f, 54.0f, + // channel 7 + 55.0f, 56.0f, 57.0f, + 58.0f, 59.0f, 60.0f, + 61.0f, 62.0f, 63.0f, + // channel 8 + 64.0f, 65.0f, 66.0f, + 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f,}; + + const Shape filter_shape{4, 2, 2, 2}; + const std::vector filter{ // filter 1 channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // filter 1 channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // filter 2 channel 1 + 9.0f, 10.0f, + 11.0f, 12.0f, + // filter 2 channel 2 + 13.0f, 14.0f, + 15.0f, 16.0f, + // filter 3 channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // filter 3 channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // filter 4 channel 1 + -9.0f, -10.0f, + -11.0f, -12.0f, + // filter 4 channel 2 + -13.0f, -14.0f, + -15.0f, -16.0f}; + + const Shape offsets_shape{1, 8, 2, 2}; + const std::vector offsets {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, 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}; + + const Shape outputs_shape{1, 4, 2, 2}; + const std::vector outputs{ // channel 1 + 500.0f, 234.0f, + 219.0f, 99.0f, + // channel 2 + 3036.0f, 1482.0f, + 1463.0f, 711.0f, + // channel 3 + -1796.0f, -810.0f, + -723.0f, -315.0f, + // channel 4 + -6636.0f, -3210.0f, + -3119.0f, -1503.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, dilations, group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_deforgroup_basic) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 2, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{// f1: channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f2: channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 16, 3, 3}; + const std::vector offsets{// defgroup 1 + 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, 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, 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, + 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, + // defgroup 2 + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + }; + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{// output 1 + 610.0f, 646.0f, 612.0f, + 754.0f, 790.0f, 732.0f, + 768.0f, 797.0f, 792.0f, + // output 2 + -610.0f, -646.0f, -612.0f, + -754.0f, -790.0f, -732.0f, + -768.0f, -797.0f, -792.0f, + }; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_deforgroup_complex1) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 4; + + const Shape inputs_shape{1, 4, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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, + // channel 3 + 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, + // channel 4 + 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}; + + const Shape filter_shape{2, 4, 2, 2}; + const std::vector filter{// f1: channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f1: channel 3 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 4 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f2: channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // f2: channel 3 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 4 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 32, 3, 3}; + const std::vector offsets{// defgroup 1 + 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, 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, 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, + 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, + // defgroup 2 + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + // defgroup 3 + 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, 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, 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, + 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, + // defgroup 4 + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + }; + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{// output 1 + 1220.0f, 1292.0f, 1224.0f, + 1508.0f, 1580.0f, 1464.0f, + 1536.0f, 1594.0f, 1584.0f, + // output 2 + -1220.0f, -1292.0f, -1224.0f, + -1508.0f, -1580.0f, -1464.0f, + -1536.0f, -1594.0f, -1584.0f, + }; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_deforgroup_complex2) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 4, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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, + // channel 3 + 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, + // channel 4 + 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}; + + const Shape filter_shape{2, 4, 2, 2}; + const std::vector filter{// f1: channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f1: channel 3 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 4 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f2: channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // f2: channel 3 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 4 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 16, 3, 3}; + const std::vector offsets{// defgroup 1 + 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, 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, 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, + 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, + // defgroup 2 + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + }; + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{// output 1 + 1300.0f, 1372.0f, 992.0f, + 1588.0f, 1660.0f, 1200.0f, + 1228.0f, 1278.0f, 1096.0f, + // output 2 + -1300.0f, -1372.0f, -992.0f, + -1588.0f, -1660.0f, -1200.0f, + -1228.0f, -1278.0f, -1096.0f, + }; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_integral_offsets_groups_and_deforgroups) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 2; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 4, 3, 3}; + const std::vector inputs{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}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{1.0f, 2.0f, + 3.0f, 4.0f, + 5.0f, 6.0f, + 7.0f, 8.0f, + -1.0f, -2.0f, + -3.0f, -4.0f, + -5.0f, -6.0f, + -7.0f, -8.0f, + }; + + const Shape offsets_shape{1, 16, 2, 2}; + const std::vector offsets{// defgroup 1 + 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, 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, + // defgroup 2 + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + }; + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{500.0f, 234.0f, + 219.0f, 99.0f, + -1004.0f, -1040.0f, + -1112.0f, -1148.0f}; + + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, + dilations, group, deformable_group); +} + +// deformable convolution atrributes (real offsets) +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_default) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{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}; + + const Shape filter_shape{1, 1, 2, 2}; + const std::vector filter{1.0f, 2.0f, + -1.0f, -2.0f}; + + const Shape offsets_shape{1, 8, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 1, 3, 3}; + const std::vector outputs{-11.999998f, -11.999999f, -4.000000f, + -10.799999f, -10.800001f, -3.600004f, + 44.300000f, 47.100000f, 16.000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_padding) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{1, 1}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{1.0f, 3.0f, 7.0f, 7.0f, + 7.0f, 6.0f, 3.0f, 1.0f, + 4.0f, 4.0f, 2.0f, 8.0f, + 1.0f, 1.0f, 1.0f, 2.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 0.0f, 1.0f, 0.0f, + 3.0f, 2.0f, 1.0f}; + + const Shape offsets_shape{1, 18, 4, 4}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 1, 4, 4}; + const std::vector outputs{54.870006f, 61.630001f, 43.230003f, 28.600002f, + 35.590000f, 25.819999f, 20.880001f, 7.700000f, + 19.089998f, 31.719999f, 19.250000f, 7.399999f, + 6.299999f, 9.199999f, 5.099999f, 2.000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_stride) +{ + const Strides strides{2, 2}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 1, 5, 5}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, + 7.0f, 5.0f, 3.0f, 1.0f, 0.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 1.0f, + 3.0f, 2.0f, 1.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 1, 2, 2}; + const std::vector outputs{61.229999f, 29.509998f, + 39.640003f, 22.640003f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_padding_stride_dilation) +{ + const Strides strides{2, 2}; + const CoordinateDiff padding{2, 2}; + const Strides dilations{2, 2}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 1, 7, 7}; + const std::vector inputs{1.0f, 3.0f, 5.0f, 7.0f, 9.0f, 11.0f, 13.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f, + 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f, 14.0f, + 7.0f, 5.0f, 3.0f, 1.0f, -1.0f, -3.0f, -5.0f, + 8.0f, 6.0f, 4.0f, 2.0f, 0.0f, -2.0f, -4.0f}; + + const Shape filter_shape{1, 1, 3, 3}; + const std::vector filter{1.0f, 2.0f, 3.0f, + 1.0f, 1.0f, 0.0f, + 3.0f, 1.0f, 2.0f}; + + const Shape offsets_shape{1, 18, 4, 4}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 1, 4, 4}; + const std::vector outputs{15.260000f, 24.119997f, 6.439994f, -3.940005f, + 26.440002f, 20.319999f, -0.500001f, -11.720002f, + 23.500003f, 14.040000f, -1.279998f, -3.860000f, + 12.500000f, -2.599999f, -5.299999f, -3.099999f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_input_channels) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 2, 4, 4}; + const std::vector inputs{ + // channel 1 + 1.0f, 3.0f, 5.0f, 7.0f, + 7.0f, 5.0f, 3.0f, 1.0f, + 2.0f, 4.0f, 6.0f, 8.0f, + 8.0f, 6.0f, 4.0f, 2.0f, + // channel 2 + -1.0f, 3.0f, -5.0f, 7.0f, + 7.0f, -5.0f, 3.0f, -1.0f, + -2.0f, 4.0f, -6.0f, 8.0f, + 8.0f, -6.0f, 4.0f, -2.0f}; + + const Shape filter_shape{1, 2, 3, 3}; + const std::vector filter{ + // channel 1 + 5.0f, 3.0f, 5.0f, + 1.0f, 3.0f, 1.0f, + 4.0f, 2.0f, 4.0f, + // channel 2 + -5.0f, 3.0f, 5.0f, + 1.0f, -3.0f, 1.0f, + 4.0f, 2.0f, -4.0f}; + + const Shape offsets_shape{1, 18, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 1, 2, 2}; + const std::vector outputs{148.000000f, 43.259998f, + 91.279998f, 111.199996f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_output_channels) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 1, 4, 4}; + const std::vector inputs{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}; + + const Shape filter_shape{2, 1, 2, 2}; + const std::vector filter{ // filter 1 + 1.0f, 2.0f, + -1.0f, -2.0f, + // filter 2 + 3.0f, 4.0f, + -3.0f, -4.0f}; + + const Shape offsets_shape{1, 8, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{ + // output 1 + -12.000000f, -12.000000f, -4.000000f, + -10.799999f, -10.799995f, -3.600000f, + 44.299999f, 47.099998f, 16.000000f, + // output 2 + -28.000000f, -28.000000f, -12.000000f, + -25.200000f, -25.199993f, -10.800003f, + 102.699996f, 109.300003f, 48.000000f, }; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_batch) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 1; + + const Shape inputs_shape{2, 1, 4, 4}; + const std::vector inputs{//batch 1 + 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, + //batch 2 + 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}; + + const Shape filter_shape{1, 1, 2, 2}; + const std::vector filter{1.0f, 2.0f, + -1.0f, -2.0f}; + + const Shape offsets_shape{2, 8, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{2, 1, 3, 3}; + const std::vector outputs{// batch 1 + -12.000000f, -12.000000f, -4.000000f, + -10.799999f, -10.799995f, -3.600000f, + 44.299999f, 47.099998f, 16.000000f, + // batch 2 + -12.000000f, -12.000000f, -4.000000f, + -10.799999f, -10.799995f, -3.600000f, + 92.300003f, 95.099998f, 32.000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +// group & deformable_group attributes (real offsets) +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_groups_basic) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 2; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 4, 3, 3}; + const std::vector inputs{ // channel 1 + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, + // channel 2 + 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, + // channel 3 + 19.0f, 20.0f, 21.0f, + 22.0f, 23.0f, 24.0f, + 25.0f, 26.0f, 27.0f, + // channel 4 + 28.0f, 29.0f, 30.0f, + 31.0f, 32.0f, 33.0f, + 34.0f, 35.0f, 36.0f}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{ // filter 1 channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // filter 1 channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // filter 2 channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // filter 2 channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 8, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{ // channel 1 + 505.800020f, 235.800000f, + 219.600000f, 99.000000f, + // channel 2 + -1153.800000f, -523.800000f, + -471.600000f, -207.0000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_groups_complex) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 4; + const int64_t deformable_group = 1; + + const Shape inputs_shape{1, 8, 3, 3}; + const std::vector inputs{ // channel 1 + 1.0f, 2.0f, 3.0f, + 4.0f, 5.0f, 6.0f, + 7.0f, 8.0f, 9.0f, + // channel 2 + 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, + 16.0f, 17.0f, 18.0f, + // channel 3 + 19.0f, 20.0f, 21.0f, + 22.0f, 23.0f, 24.0f, + 25.0f, 26.0f, 27.0f, + // channel 4 + 28.0f, 29.0f, 30.0f, + 31.0f, 32.0f, 33.0f, + 34.0f, 35.0f, 36.0f, + // channel 5 + 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, + 43.0f, 44.0f, 45.0f, + // channel 6 + 46.0f, 47.0f, 48.0f, + 49.0f, 50.0f, 51.0f, + 52.0f, 53.0f, 54.0f, + // channel 7 + 55.0f, 56.0f, 57.0f, + 58.0f, 59.0f, 60.0f, + 61.0f, 62.0f, 63.0f, + // channel 8 + 64.0f, 65.0f, 66.0f, + 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f,}; + + const Shape filter_shape{4, 2, 2, 2}; + const std::vector filter{ // filter 1 channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // filter 1 channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // filter 2 channel 1 + 9.0f, 10.0f, + 11.0f, 12.0f, + // filter 2 channel 2 + 13.0f, 14.0f, + 15.0f, 16.0f, + // filter 3 channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // filter 3 channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // filter 4 channel 1 + -9.0f, -10.0f, + -11.0f, -12.0f, + // filter 4 channel 2 + -13.0f, -14.0f, + -15.0f, -16.0f}; + + const Shape offsets_shape{1, 8, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 4, 2, 2}; + const std::vector outputs{ // channel 1 + 505.800020f, 235.800000f, + 219.600000f, 99.000000f, + // channel 2 + 3054.600000f, 1488.600000f, + 1465.200100f, 711.000000f, + // channel 3 + -1801.799900f, -811.80000f, + -723.600000f, -315.000000f, + // channel 4 + -6654.600000f, -3216.600000f, + -3121.200000f, -1503.000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_deforgroup_basic) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 2, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{// f1: channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f2: channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 16, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{// output 1 + 758.000000f, 792.000000f, 366.399993f, + 893.200012f, 927.200012f, 426.399993f, + 381.399993f, 394.600006f, 176.000000f, + // output 2 + -758.000000f, -792.000000f, -366.399993f, + -893.200012f, -927.200012f, -426.399993f, + -381.399993f, -394.600006f, -176.000000f, + }; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_deforgroup_complex1) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 4; + + const Shape inputs_shape{1, 4, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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, + // channel 3 + 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, + // channel 4 + 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}; + + const Shape filter_shape{2, 4, 2, 2}; + const std::vector filter{// f1: channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f1: channel 3 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 4 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f2: channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // f2: channel 3 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 4 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 32, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{// output 1 + 1516.000000f, 1583.999877f, 732.799987f, + 1786.400146f, 1854.400024f, 852.799987f, + 762.799987f, 789.200012f, 352.000000f, + // output 2 + -1516.000000f, -1583.999877f, -732.799987f, + -1786.400146f, -1854.400024f, -852.799987f, + -762.799987f, -789.200012f, -352.000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_deforgroup_complex2) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 1; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 4, 4, 4}; + const std::vector inputs{// channel 1 + 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, + // channel 2 + 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, + // channel 3 + 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, + // channel 4 + 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}; + + const Shape filter_shape{2, 4, 2, 2}; + const std::vector filter{// f1: channel 1 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 2 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f1: channel 3 + 1.0f, 2.0f, + 3.0f, 4.0f, + // f1: channel 4 + 5.0f, 6.0f, + 7.0f, 8.0f, + // f2: channel 1 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 2 + -5.0f, -6.0f, + -7.0f, -8.0f, + // f2: channel 3 + -1.0f, -2.0f, + -3.0f, -4.0f, + // f2: channel 4 + -5.0f, -6.0f, + -7.0f, -8.0f}; + + const Shape offsets_shape{1, 16, 3, 3}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 2, 3, 3}; + const std::vector outputs{// output 1 + 1516.000000f, 1583.999877f, 732.799987f, + 1786.400146f, 1854.400024f, 852.799987f, + 762.799987f, 789.200012f, 352.000000f, + // output 2 + -1516.000000f, -1583.999877f, -732.799987f, + -1786.400146f, -1854.400024f, -852.799987f, + -762.799987f, -789.200012f, -352.000000f, + }; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape,strides, padding, + dilations, group, deformable_group, tolerance_bits); +} + +NGRAPH_TEST(${BACKEND_NAME}, deformable_convolution_2D_real_offsets_groups_and_deforgroups) +{ + const Strides strides{1, 1}; + const CoordinateDiff padding{0, 0}; + const Strides dilations{1, 1}; + const int64_t group = 2; + const int64_t deformable_group = 2; + + const Shape inputs_shape{1, 4, 3, 3}; + const std::vector inputs{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}; + + const Shape filter_shape{2, 2, 2, 2}; + const std::vector filter{1.0f, 2.0f, + 3.0f, 4.0f, + 5.0f, 6.0f, + 7.0f, 8.0f, + -1.0f, -2.0f, + -3.0f, -4.0f, + -5.0f, -6.0f, + -7.0f, -8.0f, + }; + + const Shape offsets_shape{1, 16, 2, 2}; + const std::vector offsets(ngraph::shape_size(offsets_shape), 1.1f); + + const Shape outputs_shape{1, 2, 2, 2}; + const std::vector outputs{505.800020f, 235.800000f, + 219.600000f, 99.000000f, + -1153.800000f, -523.800000f, + -471.600000f, -207.000000f}; + + const size_t tolerance_bits = 6; + DeformableConvolutionTest(inputs, inputs_shape, offsets, offsets_shape, filter, + filter_shape, outputs, outputs_shape, strides, padding, + dilations, group, deformable_group, tolerance_bits); +} diff --git a/ngraph/test/runtime/ie/unit_test.manifest b/ngraph/test/runtime/ie/unit_test.manifest index 5bc3e7769f5..ea2955000d6 100644 --- a/ngraph/test/runtime/ie/unit_test.manifest +++ b/ngraph/test/runtime/ie/unit_test.manifest @@ -1669,3 +1669,14 @@ onnx_upsample6_dynamic # random values returned from the plugin: ticket 51762 onnx_model_deformable_conv_2d + +# DeformableConvolution groups attribute: ticket 53312 +IE_CPU.deformable_convolution_2D_zeroed_offsets_groups_basic +IE_CPU.deformable_convolution_2D_zeroed_offsets_groups_complex +IE_CPU.deformable_convolution_2D_zeroed_offsets_groups_and_deforgroups +IE_CPU.deformable_convolution_2D_integral_offsets_groups_basic +IE_CPU.deformable_convolution_2D_integral_offsets_groups_complex +IE_CPU.deformable_convolution_2D_integral_offsets_groups_and_deforgroups +IE_CPU.deformable_convolution_2D_real_offsets_groups_basic +IE_CPU.deformable_convolution_2D_real_offsets_groups_complex +IE_CPU.deformable_convolution_2D_real_offsets_groups_and_deforgroups diff --git a/ngraph/test/runtime/interpreter/evaluates_map.cpp b/ngraph/test/runtime/interpreter/evaluates_map.cpp index 321c7bb7e0e..8e711c29dcb 100644 --- a/ngraph/test/runtime/interpreter/evaluates_map.cpp +++ b/ngraph/test/runtime/interpreter/evaluates_map.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -331,6 +332,37 @@ namespace return true; } + template + bool evaluate(const shared_ptr& op, + const HostTensorVector& outputs, + const HostTensorVector& inputs) + { + const auto in_data_ptr = inputs[0]->get_data_ptr(); + const auto offset_data_ptr = inputs[1]->get_data_ptr(); + const auto filter_data_ptr = inputs[2]->get_data_ptr(); + auto out_data_ptr = outputs[0]->get_data_ptr(); + const auto& out_shape = outputs[0]->get_shape(); + const auto& in_shape = inputs[0]->get_shape(); + const auto& offset_shape = inputs[1]->get_shape(); + const auto& filter_shape = inputs[2]->get_shape(); + runtime::reference::deformable_convolution::value_type>( + in_data_ptr, + offset_data_ptr, + filter_data_ptr, + out_data_ptr, + in_shape, + offset_shape, + filter_shape, + out_shape, + op->get_strides(), + op->get_dilations(), + op->get_pads_begin(), + op->get_pads_end(), + op->get_group(), + op->get_deformable_group()); + return true; + } + namespace cum_sum_v0 { template diff --git a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp index 2eb25b7b0ec..abf494d55d3 100644 --- a/ngraph/test/runtime/interpreter/opset_int_tbl.hpp +++ b/ngraph/test/runtime/interpreter/opset_int_tbl.hpp @@ -43,6 +43,7 @@ NGRAPH_OP(Convolution, ngraph::op::v1) NGRAPH_OP(ConvolutionBackpropData, ngraph::op::v1) NGRAPH_OP(GroupConvolution, ngraph::op::v1) NGRAPH_OP(GroupConvolutionBackpropData, ngraph::op::v1) +NGRAPH_OP(DeformableConvolution, ngraph::op::v1) NGRAPH_OP(LessEqual, op::v1) NGRAPH_OP(LogicalAnd, op::v1) NGRAPH_OP(LogicalOr, op::v1) diff --git a/ngraph/test/type_prop/convolution.cpp b/ngraph/test/type_prop/convolution.cpp index afd26ff71e7..1e72cf391b5 100644 --- a/ngraph/test/type_prop/convolution.cpp +++ b/ngraph/test/type_prop/convolution.cpp @@ -2702,83 +2702,3 @@ TEST(type_prop, conv_bprop_v1_partial_auto_padding_lower) ASSERT_EQ(conv->get_pads_begin(), (CoordinateDiff{0, 0})); ASSERT_EQ(conv->get_pads_end(), (CoordinateDiff{0, 0})); } - -TEST(type_prop, deformable_conv_incorrect_group) -{ - const PartialShape data_batch_shape{1, 3, 96, 96}; - const PartialShape deformable_values_shape{1, 50, 5, 5}; - const PartialShape filters_shape{4, 3, 5, 5}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, deformable_values_shape); - auto param2 = make_shared(element::f32, filters_shape); - - try - { - make_shared(param0, - param1, - param2, - Strides{}, - CoordinateDiff{}, - CoordinateDiff{}, - Strides{}, - op::PadType::EXPLICIT, - 2); - - FAIL() << "DeformableConvolution created with incorrect 'group' value"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), "input data shape must be evenly divisible"); - } - - try - { - make_shared(param0, - param1, - param2, - Strides{}, - CoordinateDiff{}, - CoordinateDiff{}, - Strides{}, - op::PadType::EXPLICIT, - 3); - - FAIL() << "DeformableConvolution created with incorrect 'group' value"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), "weights shape must be evenly divisible"); - } -} - -TEST(type_prop, deformable_conv_incorrect_deformable_group) -{ - const PartialShape data_batch_shape{1, 3, 96, 96}; - const PartialShape deformable_values_shape{1, 50, 5, 5}; - const PartialShape filters_shape{3, 3, 5, 5}; - - auto param0 = make_shared(element::f32, data_batch_shape); - auto param1 = make_shared(element::f32, deformable_values_shape); - auto param2 = make_shared(element::f32, filters_shape); - - try - { - make_shared(param0, - param1, - param2, - Strides{}, - CoordinateDiff{}, - CoordinateDiff{}, - Strides{}, - op::PadType::EXPLICIT, - 1, - 7); - - FAIL() << "DeformableConvolution created with incorrect 'deformable group' value"; - } - catch (const NodeValidationFailure& error) - { - EXPECT_HAS_SUBSTRING(error.what(), "deformable values input must be evenly divisible"); - } -} diff --git a/ngraph/test/type_prop/deformable_convolution.cpp b/ngraph/test/type_prop/deformable_convolution.cpp index 3b1935967cb..ee5d94ceec7 100644 --- a/ngraph/test/type_prop/deformable_convolution.cpp +++ b/ngraph/test/type_prop/deformable_convolution.cpp @@ -11,9 +11,9 @@ using namespace ngraph; TEST(type_prop, deformable_conv_v1_partial_auto_padding_same) { - const PartialShape data_batch_shape{1, 4, 5, 5}; + const PartialShape data_batch_shape{1, 8, 5, 5}; const PartialShape deformable_shape{1, 4, 3, 3}; - const PartialShape filters_shape{4, 4, 3, 3}; + const PartialShape filters_shape{4, 2, 3, 3}; Strides strides{1, 1}; CoordinateDiff pads_begin{0, 0}; CoordinateDiff pads_end{0, 0}; @@ -112,9 +112,9 @@ TEST(type_prop, deformable_conv_v1_partial_auto_padding_same_nc_dims_dynamic_sam TEST(type_prop, deformable_conv_v1_partial_auto_padding_same_spatial_dims_dynamic) { - const PartialShape data_batch_shape{1, 4, Dimension::dynamic(), 5}; + const PartialShape data_batch_shape{1, 8, Dimension::dynamic(), 5}; const PartialShape deformable_shape{1, 4, 3, 3}; - const PartialShape filters_shape{4, 4, 3, 3}; + const PartialShape filters_shape{4, 2, 3, 3}; Strides strides{1, 1}; CoordinateDiff pads_begin{0, 0}; CoordinateDiff pads_end{0, 0}; @@ -143,3 +143,83 @@ TEST(type_prop, deformable_conv_v1_partial_auto_padding_same_spatial_dims_dynami ASSERT_EQ(deformable_conv->get_pads_begin(), (CoordinateDiff{0, 1})); ASSERT_EQ(deformable_conv->get_pads_end(), (CoordinateDiff{0, 1})); } + +TEST(type_prop, deformable_conv_incorrect_group) +{ + const PartialShape data_batch_shape{1, 3, 96, 96}; + const PartialShape deformable_values_shape{1, 50, 5, 5}; + const PartialShape filters_shape{4, 3, 5, 5}; + + auto param0 = make_shared(element::f32, data_batch_shape); + auto param1 = make_shared(element::f32, deformable_values_shape); + auto param2 = make_shared(element::f32, filters_shape); + + try + { + make_shared(param0, + param1, + param2, + Strides{}, + CoordinateDiff{}, + CoordinateDiff{}, + Strides{}, + op::PadType::EXPLICIT, + 2); + + FAIL() << "DeformableConvolution created with incorrect 'group' value"; + } + catch (const NodeValidationFailure& error) + { + EXPECT_HAS_SUBSTRING(error.what(), "input data shape must be evenly divisible"); + } + + try + { + make_shared(param0, + param1, + param2, + Strides{}, + CoordinateDiff{}, + CoordinateDiff{}, + Strides{}, + op::PadType::EXPLICIT, + 3); + + FAIL() << "DeformableConvolution created with incorrect 'group' value"; + } + catch (const NodeValidationFailure& error) + { + EXPECT_HAS_SUBSTRING(error.what(), "weights shape must be evenly divisible"); + } +} + +TEST(type_prop, deformable_conv_incorrect_deformable_group) +{ + const PartialShape data_batch_shape{1, 3, 96, 96}; + const PartialShape deformable_values_shape{1, 50, 5, 5}; + const PartialShape filters_shape{3, 3, 5, 5}; + + auto param0 = make_shared(element::f32, data_batch_shape); + auto param1 = make_shared(element::f32, deformable_values_shape); + auto param2 = make_shared(element::f32, filters_shape); + + try + { + make_shared(param0, + param1, + param2, + Strides{}, + CoordinateDiff{}, + CoordinateDiff{}, + Strides{}, + op::PadType::EXPLICIT, + 1, + 7); + + FAIL() << "DeformableConvolution created with incorrect 'deformable group' value"; + } + catch (const NodeValidationFailure& error) + { + EXPECT_HAS_SUBSTRING(error.what(), "deformable values input must be evenly divisible"); + } +}