From b06c0b5c3296d9277b1672f3293adb98e8762469 Mon Sep 17 00:00:00 2001 From: Yury Gaydaychuk Date: Wed, 12 Jan 2022 14:08:24 +0300 Subject: [PATCH] [CPU] DS support for Deformable Convolution (#8986) --- .../src/nodes/mkldnn_def_conv_node.cpp | 369 +++++++----- .../src/nodes/mkldnn_def_conv_node.h | 79 ++- .../skip_tests_config.cpp | 3 + .../deformable_convolution.cpp | 545 ++++++++++++------ 4 files changed, 640 insertions(+), 356 deletions(-) diff --git a/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.cpp b/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.cpp index fc0722d6ff6..3515fbeac16 100644 --- a/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.cpp +++ b/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.cpp @@ -578,10 +578,6 @@ private: bool MKLDNNDeformableConvolutionNode::isSupportedOperation(const std::shared_ptr& op, std::string& errorMessage) noexcept { try { - if (isDynamicNgraphNode(op)) { - errorMessage = "Doesn't support op with dynamic shapes"; - return false; - } if (!one_of(op->get_type_info(), ngraph::op::v1::DeformableConvolution::get_type_info_static(), ngraph::op::v8::DeformableConvolution::get_type_info_static())) { @@ -600,53 +596,53 @@ MKLDNNDeformableConvolutionNode::MKLDNNDeformableConvolutionNode(const std::shar if (!isSupportedOperation(op, errorMessage)) { IE_THROW(NotImplemented) << errorMessage; } + errorPrefix = "Deformable convolution with name '" + op->get_friendly_name() + "'"; auto defConvNodeBase = std::dynamic_pointer_cast(op); if (defConvNodeBase == nullptr) - IE_THROW() << "Operation with name '" << op->get_friendly_name() << - "' is not an instance of DeformableConvolutionBase."; + IE_THROW() << errorPrefix << " is not an instance of DeformableConvolutionBase."; - group = defConvNodeBase->get_group(); - deformable_group = defConvNodeBase->get_deformable_group(); + defConvAttr.group = defConvNodeBase->get_group(); + defConvAttr.deformable_group = defConvNodeBase->get_deformable_group(); auto& strides = defConvNodeBase->get_strides(); for (int i = 0; i < strides.size(); i++) { - stride.push_back(strides[i]); + defConvAttr.stride.push_back(strides[i]); } auto& dilations = defConvNodeBase->get_dilations(); for (int i = 1; i <= dilations.size(); i++) { - dilation.push_back(dilations[dilations.size() - i] - 1); + defConvAttr.dilation.push_back(dilations[dilations.size() - i] - 1); } - paddingL = defConvNodeBase->get_pads_begin(); + defConvAttr.padL = defConvNodeBase->get_pads_begin(); + + autoPadding = one_of(defConvNodeBase->get_auto_pad(), ov::op::PadType::SAME_UPPER, ov::op::PadType::SAME_LOWER); if (op->get_type_info() == ngraph::op::v8::DeformableConvolution::get_type_info_static()) { auto defConvNode = std::dynamic_pointer_cast(op); if (defConvNode == nullptr) - IE_THROW() << "Operation with name '" << op->get_friendly_name() << - "' is not an instance of DeformableConvolution from opset8."; - with_bilinear_pad = defConvNode->get_bilinear_interpolation_pad(); + IE_THROW() << errorPrefix << " is not an instance of DeformableConvolution from opset8."; + defConvAttr.with_bilinear_pad = defConvNode->get_bilinear_interpolation_pad(); } else { - with_bilinear_pad = false; + defConvAttr.with_bilinear_pad = false; } } void MKLDNNDeformableConvolutionNode::getSupportedDescriptors() { - std::string errorPrefix = "DeformableConvolution layer with name '" + getName() + "' "; if (getParentEdges().size() != 3 && getParentEdges().size() != 4) - IE_THROW() << errorPrefix << "has incorrect number of input edges"; + IE_THROW() << errorPrefix << " has incorrect number of input edges"; if (getChildEdges().empty()) - IE_THROW() << errorPrefix << "has incorrect number of output edges"; - if (getInputShapeAtPort(0).getRank() != 4) { - IE_THROW() << "Deformable convolution layer. Unsupported mode. Only 4D blobs are supported as input."; + IE_THROW() << errorPrefix << " has incorrect number of output edges"; + if (getInputShapeAtPort(DATA_ID).getRank() != 4) { + IE_THROW() << errorPrefix << " has unsupported mode. Only 4D blobs are supported as input."; } - if (getInputShapeAtPort(1).getRank() != 4) { - IE_THROW() << errorPrefix << "doesn't support 1st input with rank: " << getInputShapeAtPort(1).getRank(); + if (getInputShapeAtPort(OFF_ID).getRank() != 4) { + IE_THROW() << errorPrefix << " doesn't support 1st input with rank: " << getInputShapeAtPort(OFF_ID).getRank(); } - if (getInputShapeAtPort(2).getRank() != 4) { - IE_THROW() << errorPrefix << "doesn't support 2nd input with rank: " << getInputShapeAtPort(2).getRank(); + if (getInputShapeAtPort(WEI_ID).getRank() != 4) { + IE_THROW() << errorPrefix << " doesn't support 2nd input with rank: " << getInputShapeAtPort(WEI_ID).getRank(); } - if (getOutputShapeAtPort(0).getRank() != 4) { - IE_THROW() << errorPrefix << "doesn't support output with rank: " << getOutputShapeAtPort(0).getRank(); + if (getOutputShapeAtPort(DATA_ID).getRank() != 4) { + IE_THROW() << errorPrefix << " doesn't support output with rank: " << getOutputShapeAtPort(DATA_ID).getRank(); } } @@ -675,9 +671,15 @@ void MKLDNNDeformableConvolutionNode::initSupportedPrimitiveDescriptors() { impl_desc_type impl_type; const int simd_w = mayiuse(cpu::x64::avx512_common) ? 16 : 8; - if (group != 1 || (((getInputShapeAtPort(0).getStaticDims()[1] / group) % simd_w != 0) - || ((getOutputShapeAtPort(0).getStaticDims()[1] / group) % simd_w != 0))) { + + auto &weiDims = getInputShapeAtPort(WEI_ID).getDims(); + if (weiDims[1] == Shape::UNDEFINED_DIM || weiDims[0] == Shape::UNDEFINED_DIM || + defConvAttr.group != 1 || // temporary workaround until jit impl. will correctly handle multigroup cases + (weiDims[1] % simd_w != 0) // in_channels_per_gr !% simd_w + || ((weiDims[0] / defConvAttr.group) % simd_w != 0)) { // out_channels_per_gr !% simd_w enforceRef = true; + } else { + enforceRef = false; } if (enforceRef) { @@ -697,51 +699,41 @@ void MKLDNNDeformableConvolutionNode::initSupportedPrimitiveDescriptors() { auto dataFormat = memory::format_tag::nhwc; auto offFormat = memory::format_tag::nchw; auto weiFormat = mayiuse(avx512_common) ? memory::format_tag::OIhw16i16o : memory::format_tag::OIhw8i8o; - config.inConfs[0].desc = std::make_shared(getInputShapeAtPort(0), + config.inConfs[DATA_ID].desc = std::make_shared(getInputShapeAtPort(DATA_ID), memory::data_type::f32, dataFormat); - config.inConfs[1].desc = std::make_shared(getInputShapeAtPort(1), + config.inConfs[OFF_ID].desc = std::make_shared(getInputShapeAtPort(OFF_ID), memory::data_type::f32, offFormat); - auto& wDims = getInputShapeAtPort(2).getStaticDims(); - if (group > 1 && wDims.size() != 5) { - auto new_dims = InferenceEngine::SizeVector({group, div_up(wDims[0], group)}); - for (int i = 1; i < wDims.size(); i++) { - new_dims.push_back(wDims[i]); - } - config.inConfs[2].desc = std::make_shared(getInputShapeAtPort(2), - memory::data_type::f32, weiFormat); - } else { - config.inConfs[2].desc = std::make_shared(getInputShapeAtPort(2), - memory::data_type::f32, weiFormat); - } + + config.inConfs[WEI_ID].desc = std::make_shared(getInputShapeAtPort(WEI_ID), + memory::data_type::f32, weiFormat); if (inputsNumber > 3) { - config.inConfs[3].desc = std::make_shared(getInputShapeAtPort(3), + config.inConfs[MOD_ID].desc = std::make_shared(getInputShapeAtPort(MOD_ID), memory::data_type::f32, memory::format_tag::nchw); } - config.outConfs[0].desc = std::make_shared(getOutputShapeAtPort(0), + config.outConfs[0].desc = std::make_shared(getOutputShapeAtPort(DATA_ID), memory::data_type::f32, dataFormat); supportedPrimitiveDescriptors.push_back({config, impl_type}); } else { // reference implementation - config.inConfs[0].desc = std::make_shared(getInputShapeAtPort(0), memory::data_type::f32, + config.inConfs[DATA_ID].desc = std::make_shared(getInputShapeAtPort(DATA_ID), memory::data_type::f32, memory::format_tag::nchw); - config.inConfs[1].desc = std::make_shared(getInputShapeAtPort(1), memory::data_type::f32, + config.inConfs[OFF_ID].desc = std::make_shared(getInputShapeAtPort(OFF_ID), memory::data_type::f32, memory::format_tag::nchw); - config.inConfs[2].desc = std::make_shared(getInputShapeAtPort(2), memory::data_type::f32, + config.inConfs[WEI_ID].desc = std::make_shared(getInputShapeAtPort(WEI_ID), memory::data_type::f32, memory::format_tag::oihw); if (inputsNumber > 3) { - config.inConfs[3].desc = std::make_shared(getInputShapeAtPort(3), memory::data_type::f32, + config.inConfs[MOD_ID].desc = std::make_shared(getInputShapeAtPort(MOD_ID), memory::data_type::f32, memory::format_tag::nchw); } - config.outConfs[0].desc = std::make_shared(getOutputShapeAtPort(0), memory::data_type::f32, + config.outConfs[0].desc = std::make_shared(getOutputShapeAtPort(DATA_ID), memory::data_type::f32, memory::format_tag::nchw); supportedPrimitiveDescriptors.push_back({config, impl_type}); } } -void MKLDNNDeformableConvolutionNode::prepareSamplingWeights( - const std::vector& src_strides, const float* offsets, const std::vector& off_strides, - const float* modulation, const std::vector& modulation_strides) { +void MKLDNNDeformableConvolutionNode::DefConvExecutor::prepareSamplingWeights( + const float* offsets, const float* modulation, bool enforceRef) { const int MB = jcp.mb; const int OH = jcp.oh; const int OW = jcp.ow; @@ -766,9 +758,6 @@ void MKLDNNDeformableConvolutionNode::prepareSamplingWeights( const bool with_bi_pad = jcp.with_bi_pad; - // prepare weights and indices - sampledCoordsVector.resize(MB * DG * KH * KW * OH * OW * sampledPointsPerPixel); - interpWeightsVector.resize(MB * DG * KH * KW * OH * OW * sampledPointsPerPixel); auto precompKer = [&](int mb, int dg, int oh, int ow) { int sampledCoordIndex = (mb * DG * OH * OW + dg * OH * OW + oh * OW + ow) * KH * KW * sampledPointsPerPixel; const int h_in = oh * KSH - padT; @@ -777,22 +766,22 @@ void MKLDNNDeformableConvolutionNode::prepareSamplingWeights( const int waOffsetH = (enforceRef ? 0 : h_in); const int waOffsetW = (enforceRef ? 0 : w_in); - const float *data_offset_ptr = offsets + mb * off_strides[0] + (dg * 2 * KH * KW) * off_strides[1]; + const float *data_offset_ptr = offsets + mb * offStrides[0] + (dg * 2 * KH * KW) * offStrides[1]; const float *modulation_offset_ptr = nullptr; if (modulation != nullptr) { - modulation_offset_ptr = modulation + mb * modulation_strides[0] + (dg * ker_size) * modulation_strides[1]; + modulation_offset_ptr = modulation + mb * modStrides[0] + (dg * ker_size) * modStrides[1]; } for (int kh = 0; kh < KH; kh++) { for (int kw = 0; kw < KW; kw++) { - const size_t data_offset_h_index = 2 * ((size_t) kh * KW + kw) * off_strides[1] + oh * off_strides[2] + ow * off_strides[3]; - const size_t data_offset_w_index = (2 * ((size_t) kh * KW + kw) + 1) * off_strides[1] + oh * off_strides[2] + ow * off_strides[3]; + const size_t data_offset_h_index = 2 * ((size_t) kh * KW + kw) * offStrides[1] + oh * offStrides[2] + ow * offStrides[3]; + const size_t data_offset_w_index = (2 * ((size_t) kh * KW + kw) + 1) * offStrides[1] + oh * offStrides[2] + ow * offStrides[3]; const float offset_h = data_offset_ptr[data_offset_h_index]; const float offset_w = data_offset_ptr[data_offset_w_index]; float map_h = h_in + kh * (KDH + 1) + offset_h; float map_w = w_in + kw * (KDW + 1) + offset_w; bool skip_compute; - if (with_bilinear_pad) { + if (with_bi_pad) { skip_compute = !(static_cast(map_w) > -1 && static_cast(map_w) < IW && static_cast(map_h) > -1 && @@ -806,7 +795,7 @@ void MKLDNNDeformableConvolutionNode::prepareSamplingWeights( float modulation_scalar = 1.0f; if (modulation_offset_ptr != nullptr) { - size_t modulation_index = (kh * KW + kw) * modulation_strides[1] + oh * modulation_strides[2] + ow * modulation_strides[3]; + size_t modulation_index = (kh * KW + kw) * modStrides[1] + oh * modStrides[2] + ow * modStrides[3]; modulation_scalar = modulation_offset_ptr[modulation_index]; } // interpolation precomp. @@ -833,28 +822,28 @@ void MKLDNNDeformableConvolutionNode::prepareSamplingWeights( lh = (h_high < cur_h_end ? lh : 0); lw = (w_high < cur_w_end ? lw : 0); - const int h_off_low = h_ind_low * src_strides[2] / src_strides[3]; - const int h_off_high = h_ind_high * src_strides[2] / src_strides[3]; + const int h_off_low = h_ind_low * srcStrides[2] / srcStrides[3]; + const int h_off_high = h_ind_high * srcStrides[2] / srcStrides[3]; const int w_off_low = w_ind_low; const int w_off_high = w_ind_high; - sampledCoordsVector[sampledCoordIndex] = h_off_high + w_off_high; - sampledCoordsVector[sampledCoordIndex + 1] = h_off_high + w_off_low; - sampledCoordsVector[sampledCoordIndex + 2] = h_off_low + w_off_high; - sampledCoordsVector[sampledCoordIndex + 3] = h_off_low + w_off_low; + pSampledCoordsVector[sampledCoordIndex] = h_off_high + w_off_high; + pSampledCoordsVector[sampledCoordIndex + 1] = h_off_high + w_off_low; + pSampledCoordsVector[sampledCoordIndex + 2] = h_off_low + w_off_high; + pSampledCoordsVector[sampledCoordIndex + 3] = h_off_low + w_off_low; float w22 = hh * hw * modulation_scalar, w21 = hh * lw * modulation_scalar, w12 = lh * hw * modulation_scalar, w11 = lh * lw * modulation_scalar; - interpWeightsVector[sampledCoordIndex] = w11; - interpWeightsVector[sampledCoordIndex + 1] = w12; - interpWeightsVector[sampledCoordIndex + 2] = w21; - interpWeightsVector[sampledCoordIndex + 3] = w22; + pInterpWeightsVector[sampledCoordIndex] = w11; + pInterpWeightsVector[sampledCoordIndex + 1] = w12; + pInterpWeightsVector[sampledCoordIndex + 2] = w21; + pInterpWeightsVector[sampledCoordIndex + 3] = w22; } else { - sampledCoordsVector[sampledCoordIndex] = 0; - interpWeightsVector[sampledCoordIndex] = 0; - interpWeightsVector[sampledCoordIndex + 1] = 0; - interpWeightsVector[sampledCoordIndex + 2] = 0; - interpWeightsVector[sampledCoordIndex + 3] = 0; + pSampledCoordsVector[sampledCoordIndex] = 0; + pInterpWeightsVector[sampledCoordIndex] = 0; + pInterpWeightsVector[sampledCoordIndex + 1] = 0; + pInterpWeightsVector[sampledCoordIndex + 2] = 0; + pInterpWeightsVector[sampledCoordIndex + 3] = 0; } sampledCoordIndex += sampledPointsPerPixel; } @@ -866,19 +855,36 @@ void MKLDNNDeformableConvolutionNode::prepareSamplingWeights( }); } -void MKLDNNDeformableConvolutionNode::createPrimitive() { - auto selectedPrimitiveDescriptor = getSelectedPrimitiveDescriptor(); - if (!selectedPrimitiveDescriptor) - IE_THROW() << "CPU deformable convolution with name '" << getName() << "' doesn't have primitive descriptors."; - auto config = selectedPrimitiveDescriptor->getConfig(); +MKLDNNDeformableConvolutionNode::DefConvExecutor::DefConvExecutor(const DefConvAttr &defConvAttr, + const std::vector> &descVector) { + if (descVector.size() != 4 && descVector.size() != 5) { + IE_THROW() << "Deformable Convolution executor got incorrect desc's count (" << descVector.size() << ")"; + } + bool withModulation = descVector.size() == 5; - auto srcDims = getParentEdgeAt(0)->getMemory().getStaticDims(); - auto weiDims = getParentEdgeAt(2)->getMemory().getStaticDims(); - auto dstDims = getChildEdgesAtPort(0)[0]->getMemory().getStaticDims(); + auto &srcDesc = descVector[DATA_ID]; + auto &dstDesc = descVector[descVector.size() - 1]; + srcStrides = std::vector(srcDesc->getStrides().size()); + offStrides = descVector[OFF_ID]->getStrides(); + weiStrides = descVector[WEI_ID]->getStrides(); + dstStrides = std::vector(dstDesc->getStrides().size()); + for (int i = 0; i < srcDesc->getStrides().size(); i++) { + srcStrides[srcDesc->getOrder()[i]] = srcDesc->getStrides()[i]; + } + for (int i = 0; i < dstDesc->getStrides().size(); i++) { + dstStrides[dstDesc->getOrder()[i]] = dstDesc->getStrides()[i]; + } - jcp.dg = deformable_group; + if (withModulation) { + modStrides = descVector[MOD_ID]->getStrides(); + } - jcp.ngroups = group; + const VectorDims srcDims = descVector[DATA_ID]->getShape().getStaticDims(); + const VectorDims weiDims = descVector[WEI_ID]->getShape().getStaticDims(); + const VectorDims dstDims = descVector[descVector.size() - 1]->getShape().getStaticDims(); + + jcp.dg = defConvAttr.deformable_group; + jcp.ngroups = defConvAttr.group; jcp.mb = srcDims[0]; @@ -893,19 +899,18 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { jcp.kh = weiDims[2]; jcp.kw = weiDims[3]; - jcp.t_pad = paddingL[0]; - jcp.l_pad = paddingL[1]; + jcp.t_pad = defConvAttr.padL[0]; + jcp.l_pad = defConvAttr.padL[1]; - jcp.stride_h = stride[0]; - jcp.stride_w = stride[1]; + jcp.stride_h = defConvAttr.stride[0]; + jcp.stride_w = defConvAttr.stride[1]; - jcp.dilate_h = dilation[0]; - jcp.dilate_w = dilation[1]; + jcp.dilate_h = defConvAttr.dilation[0]; + jcp.dilate_w = defConvAttr.dilation[1]; jcp.with_bias = false; - jcp.with_bi_pad = with_bilinear_pad; - jcp.with_modulation = getParentEdges().size() > 3; - + jcp.with_bi_pad = defConvAttr.with_bilinear_pad; + jcp.with_modulation = withModulation; const int simd_w = mayiuse(cpu::x64::avx512_common) ? 16 : 8; jcp.ic_block = simd_w; jcp.nb_ic = div_up(jcp.ic, jcp.ic_block); @@ -924,23 +929,33 @@ void MKLDNNDeformableConvolutionNode::createPrimitive() { jcp.nb_oc_blocking = !mayiuse(cpu::x64::avx2) ? 2 : 4; jcp.nthr = dnnl_get_max_threads(); +} - if (enforceRef) { - return; - } else if (mayiuse(cpu::x64::avx512_common)) { +MKLDNNDeformableConvolutionNode::DefConvJitExecutor::DefConvJitExecutor(const DefConvAttr &defConvAttr, + const std::vector> &descVector) : + DefConvExecutor(defConvAttr, descVector) { + if (mayiuse(cpu::x64::avx512_common)) { def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32(jcp)); } else if (mayiuse(cpu::x64::avx2)) { def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32(jcp)); } else if (mayiuse(cpu::x64::sse41)) { def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32(jcp)); + } else { + IE_THROW() << "Can't create DefConvJitExecutor"; } - - if (def_conv_kernel) + if (def_conv_kernel) { def_conv_kernel->create_ker(); + } else { + IE_THROW() << "Can't compile DefConvJitExecutor"; + } } -void MKLDNNDeformableConvolutionNode::executeReference(const float* src, const float* weights, float* dst, const std::vector& src_strides, - const std::vector& wei_strides, const std::vector& dst_strides) { +void MKLDNNDeformableConvolutionNode::DefConvRefExecutor::exec(const float* src, const float* offsets, + const float* weights, const float* modulation, float* dst, + int *pSampledCoordsVector, float *pInterpWeightsVector) { + this->pSampledCoordsVector = pSampledCoordsVector; + this->pInterpWeightsVector = pInterpWeightsVector; + prepareSamplingWeights(offsets, modulation, true); const int G = jcp.ngroups; const int MB = jcp.mb; const int OH = jcp.oh; @@ -958,26 +973,26 @@ void MKLDNNDeformableConvolutionNode::executeReference(const float* src, const f const int HW = OH * OW; const int channel_per_deformable_group = (IC * G) / DG; - const size_t group_wei_stride = wei_strides[0] * OC; + const size_t group_wei_stride = weiStrides[0] * OC; auto compKer = [=](int g, int mb, int oc, int oh, int ow) { float d = 0; for (int ic = 0; ic < IC; ic++) { - const float *data_im_ptr = src + mb * src_strides[0] + (g * IC + ic) * src_strides[1]; + const float *data_im_ptr = src + mb * srcStrides[0] + (g * IC + ic) * srcStrides[1]; const int deformable_group_index = (IC * g + ic) / channel_per_deformable_group; int sampledCoordIndex = (mb * DGHW + deformable_group_index * HW + oh * OW + ow) * ker_size * sampledPointsPerPixel; - size_t weiIndex = (size_t) g * group_wei_stride + oc * wei_strides[0] + ic * wei_strides[1]; - for (int kh_off = 0; kh_off < KH * wei_strides[2]; kh_off += wei_strides[2]) { - for (int kw_off = 0; kw_off < KW * wei_strides[3]; kw_off += wei_strides[3]) { + size_t weiIndex = (size_t) g * group_wei_stride + oc * weiStrides[0] + ic * weiStrides[1]; + for (int kh_off = 0; kh_off < KH * weiStrides[2]; kh_off += weiStrides[2]) { + for (int kw_off = 0; kw_off < KW * weiStrides[3]; kw_off += weiStrides[3]) { // check if current addendum marked as equal zero - if (sampledCoordsVector[sampledCoordIndex] != -1) { - const int v11 = sampledCoordsVector[sampledCoordIndex]; - const int v12 = sampledCoordsVector[sampledCoordIndex + 1]; - const int v21 = sampledCoordsVector[sampledCoordIndex + 2]; - const int v22 = sampledCoordsVector[sampledCoordIndex + 3]; - float val = interpWeightsVector[sampledCoordIndex++] * data_im_ptr[v11]; // v11 - val += interpWeightsVector[sampledCoordIndex++] * data_im_ptr[v12]; // v12 - val += interpWeightsVector[sampledCoordIndex++] * data_im_ptr[v21]; // v21 - val += interpWeightsVector[sampledCoordIndex++] * data_im_ptr[v22]; // v22 + if (pSampledCoordsVector[sampledCoordIndex] != -1) { + const int v11 = pSampledCoordsVector[sampledCoordIndex]; + const int v12 = pSampledCoordsVector[sampledCoordIndex + 1]; + const int v21 = pSampledCoordsVector[sampledCoordIndex + 2]; + const int v22 = pSampledCoordsVector[sampledCoordIndex + 3]; + float val = pInterpWeightsVector[sampledCoordIndex++] * data_im_ptr[v11]; // v11 + val += pInterpWeightsVector[sampledCoordIndex++] * data_im_ptr[v12]; // v12 + val += pInterpWeightsVector[sampledCoordIndex++] * data_im_ptr[v21]; // v21 + val += pInterpWeightsVector[sampledCoordIndex++] * data_im_ptr[v22]; // v22 d += val * weights[weiIndex + kh_off + kw_off]; } else { sampledCoordIndex += sampledPointsPerPixel; @@ -990,14 +1005,81 @@ void MKLDNNDeformableConvolutionNode::executeReference(const float* src, const f parallel_nd(G, MB, OC, OH, OW, [&](int g, int mb, int oc, int oh, int ow) { - dst[mb * dst_strides[0] + (g * OC + oc) * dst_strides[1] + oh * dst_strides[2] + ow * dst_strides[3]] = compKer(g, mb, oc, oh, ow); + dst[mb * dstStrides[0] + (g * OC + oc) * dstStrides[1] + oh * dstStrides[2] + ow * dstStrides[3]] = compKer(g, mb, oc, oh, ow); }); } +void MKLDNNDeformableConvolutionNode::prepareParams() { + auto& dstMemPtr = getChildEdgeAt(0)->getMemoryPtr(); + auto& srcMemPtr = getParentEdgeAt(DATA_ID)->getMemoryPtr(); + auto& offMemPtr = getParentEdgeAt(OFF_ID)->getMemoryPtr(); + auto& weiMemPtr = getParentEdgeAt(WEI_ID)->getMemoryPtr(); -void MKLDNNDeformableConvolutionNode::executeOptimized(const float* src, const float* weights, float* dst, - const std::vector& src_strides, - const std::vector& dst_strides) { + if (!dstMemPtr || !dstMemPtr->GetPrimitivePtr()) + IE_THROW() << errorPrefix << " did not allocate destination memory"; + if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr()) + IE_THROW() << errorPrefix << " did not allocate input memory"; + if (!offMemPtr || !offMemPtr->GetPrimitivePtr()) + IE_THROW() << errorPrefix << " did not allocate offsets shape memory"; + if (!weiMemPtr || !weiMemPtr->GetPrimitivePtr()) + IE_THROW() << errorPrefix << " did not allocate weights memory"; + + if (getOriginalInputsNumber() > 3) { + auto& modMemPtr = getParentEdgeAt(MOD_ID)->getMemoryPtr(); + if (!modMemPtr || !modMemPtr->GetPrimitivePtr()) + IE_THROW() << errorPrefix << " did not allocate modulations memory"; + } + + auto selectedPrimitiveDescriptor = getSelectedPrimitiveDescriptor(); + if (!selectedPrimitiveDescriptor) + IE_THROW() << errorPrefix << "' doesn't have primitive descriptors."; + auto config = selectedPrimitiveDescriptor->getConfig(); + + bool withModulation = getParentEdges().size() > 3; + + updatePadding(); + + std::vector> descVector { + getParentEdgeAt(DATA_ID)->getMemory().GetDescWithType(), + getParentEdgeAt(OFF_ID)->getMemory().GetDescWithType(), + getParentEdgeAt(WEI_ID)->getMemory().GetDescWithType() + }; + + if (withModulation) { + descVector.push_back(getParentEdgeAt(MOD_ID)->getMemory().GetDescWithType()); + } + descVector.push_back(getChildEdgesAtPort(0)[0]->getMemory().GetDescWithType()); + + const int MB = getParentEdgeAt(DATA_ID)->getMemory().getStaticDims()[0]; + const int OH = getChildEdgesAtPort(0)[0]->getMemory().getStaticDims()[2]; + const int OW = getChildEdgesAtPort(0)[0]->getMemory().getStaticDims()[3]; + + const int KH = getParentEdgeAt(WEI_ID)->getMemory().getStaticDims()[2]; + const int KW = getParentEdgeAt(WEI_ID)->getMemory().getStaticDims()[3]; + + const int DG = defConvAttr.deformable_group; + + // allocate sampling weights and indices + sampledCoordsVector.resize(MB * DG * KH * KW * OH * OW * sampledPointsPerPixel); + interpWeightsVector.resize(MB * DG * KH * KW * OH * OW * sampledPointsPerPixel); + + if (enforceRef) { + execPtr = std::make_shared(defConvAttr, descVector); + } else { + execPtr = std::make_shared(defConvAttr, descVector); + } +} + +void MKLDNNDeformableConvolutionNode::executeDynamicImpl(dnnl::stream strm) { + execute(strm); +} + +void MKLDNNDeformableConvolutionNode::DefConvJitExecutor::exec(const float* src, const float* offsets, + const float* weights, const float* modulation, float* dst, + int *pSampledCoordsVector, float *pInterpWeightsVector) { + this->pSampledCoordsVector = pSampledCoordsVector; + this->pInterpWeightsVector = pInterpWeightsVector; + prepareSamplingWeights(offsets, modulation, false); size_t buffer_size = (size_t)jcp.nthr * jcp.ur_w * jcp.kh * jcp.kw * jcp.ic * jcp.typesize_in; std::vector input_buffer(buffer_size, 0); float* input_buffer_ptr = input_buffer.data(); @@ -1010,12 +1092,12 @@ void MKLDNNDeformableConvolutionNode::executeOptimized(const float* src, const f const size_t _oc = g * jcp.nb_oc; const size_t _ic = g * jcp.nb_ic; - par_conv.src = &src[n * src_strides[0] + _ic*jcp.ic_block * src_strides[1] + - (oh * jcp.stride_h - jcp.t_pad) * src_strides[2] - jcp.l_pad * src_strides[3]]; - par_conv.sampledWei = &interpWeightsVector[(n * jcp.dg * jcp.oh + oh) * jcp.kh * jcp.kw * jcp.ow * sampledPointsPerPixel]; - par_conv.sampledCoords = &sampledCoordsVector[(n * jcp.dg * jcp.oh + oh) * jcp.kh * jcp.kw * jcp.ow * sampledPointsPerPixel]; + par_conv.src = &src[n * srcStrides[0] + _ic*jcp.ic_block * srcStrides[1] + + (oh * jcp.stride_h - jcp.t_pad) * srcStrides[2] - jcp.l_pad * srcStrides[3]]; + par_conv.sampledWei = &(pInterpWeightsVector[(n * jcp.dg * jcp.oh + oh) * jcp.kh * jcp.kw * jcp.ow * sampledPointsPerPixel]); + par_conv.sampledCoords = &(pSampledCoordsVector[(n * jcp.dg * jcp.oh + oh) * jcp.kh * jcp.kw * jcp.ow * sampledPointsPerPixel]); par_conv.filt = &weights[g * jcp.nb_oc * jcp.nb_ic * jcp.kh * jcp.kw * jcp.ic_block * jcp.oc_block]; - par_conv.dst = &dst[n * dst_strides[0] + _oc * jcp.oc_block * dst_strides[1] + oh * dst_strides[2]]; + par_conv.dst = &dst[n * dstStrides[0] + _oc * jcp.oc_block * dstStrides[1] + oh * dstStrides[2]]; par_conv.buf = input_buffer_ptr + ithr * jcp.ur_w * jcp.kh * jcp.kw * jcp.ic; par_conv.oh_pos = oh; @@ -1044,34 +1126,21 @@ void MKLDNNDeformableConvolutionNode::execute(mkldnn::stream strm) { auto selectedPrimitiveDescriptor = getSelectedPrimitiveDescriptor(); if (!selectedPrimitiveDescriptor) - IE_THROW() << "CPU deformable convolution with name '" << getName() << "' doesn't have primitive descriptors."; + IE_THROW() << "Deformable convolution with name '" << getName() << "' doesn't have primitive descriptors."; auto config = selectedPrimitiveDescriptor->getConfig(); - auto src_block_desc = getParentEdgeAt(0)->getMemory().GetDescWithType(); - std::vector src_strides(src_block_desc->getStrides().size()); - for (int i = 0; i < src_strides.size(); i++) { - src_strides[src_block_desc->getOrder()[i]] = src_block_desc->getStrides()[i]; - } - - auto dst_block_desc = getChildEdgeAt(0)->getMemory().GetDescWithType(); - std::vector dst_strides(dst_block_desc->getStrides().size()); - for (int i = 0; i < dst_strides.size(); i++) { - dst_strides[dst_block_desc->getOrder()[i]] = dst_block_desc->getStrides()[i]; - } - - auto off_strides = getParentEdgeAt(1)->getMemory().GetDescWithType()->getStrides(); - auto wei_strides = getParentEdgeAt(2)->getMemory().GetDescWithType()->getStrides(); - InferenceEngine::SizeVector modulation_strides; - if (inputsNumber > 3) { - modulation_strides = getParentEdgeAt(3)->getMemory().GetDescWithType()->getStrides(); - } - - prepareSamplingWeights(src_strides, offsets, off_strides, modulation, modulation_strides); - - if (def_conv_kernel) { - executeOptimized(src, weights, dst, src_strides, dst_strides); + if (execPtr) { + execPtr->exec(src, offsets, weights, modulation, dst, sampledCoordsVector.data(), interpWeightsVector.data()); } else { - executeReference(src, weights, dst, src_strides, wei_strides, dst_strides); + IE_THROW() << "Deformable Convolution executor doesn't exist"; + } +} + +void MKLDNNDeformableConvolutionNode::updatePadding() { + //update padding. TODO [DS] : rewrite when the final shape inference interface is available + if (isDynamicNode() && autoPadding) { + auto defConvNodeBase = std::dynamic_pointer_cast(opToShapeInfer); + defConvAttr.padL = defConvNodeBase->get_pads_begin(); } } diff --git a/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.h b/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.h index e0d159dbd0c..3e8970d3763 100644 --- a/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.h +++ b/src/plugins/intel_cpu/src/nodes/mkldnn_def_conv_node.h @@ -73,7 +73,6 @@ public: static bool isSupportedOperation(const std::shared_ptr& op, std::string& errorMessage) noexcept; void getSupportedDescriptors() override; - void createPrimitive() override; void initSupportedPrimitiveDescriptors() override; void execute(mkldnn::stream strm) override; bool created() const override; @@ -86,29 +85,73 @@ public: InferenceEngine::Precision getRuntimePrecision() const override; private: - size_t group = 1; - bool with_bilinear_pad = false; - std::vector stride = {}; - std::vector dilation = {}; - std::vector paddingL = {}; - - int deformable_group = 1; - - jit_def_conv_params jcp = {}; + struct DefConvAttr { + size_t group = 1; + int deformable_group = 1; + bool with_bilinear_pad = false; + std::vector stride = {}; + std::vector dilation = {}; + std::vector padL; + } defConvAttr; std::vector sampledCoordsVector; std::vector interpWeightsVector; - std::shared_ptr def_conv_kernel = nullptr; + void prepareParams() override; + void updatePadding(); - void prepareSamplingWeights(const std::vector& src_strides, const float* offsets, const std::vector& off_strides, - const float* modulation = nullptr, const std::vector& modulation_strides = {}); + void executeDynamicImpl(mkldnn::stream strm) override; + static constexpr size_t DATA_ID = 0; + static constexpr size_t OFF_ID = 1; + static constexpr size_t WEI_ID = 2; + static constexpr size_t MOD_ID = 3; + std::string errorPrefix; + class DefConvExecutor { + public: + DefConvExecutor(const DefConvAttr &defConvAttr, + const std::vector> &descVector); - void executeReference(const float* src, const float* weights, float* dst, const std::vector& src_strides, - const std::vector& wei_strides, const std::vector& dst_strides); - void executeOptimized(const float* src, const float* weights, float* dst, - const std::vector& src_strides, const std::vector& dst_strides); + virtual void exec(const float* src, const float* offsets, + const float* weights, const float* modulation, float* dst, + int *pSampledCoordsVector, float *pInterpWeightsVector) = 0; + virtual ~DefConvExecutor() = default; + + protected: + void prepareSamplingWeights(const float* offsets, const float* modulation = nullptr, bool enforceRef = false); + jit_def_conv_params jcp = {}; + VectorDims srcStrides; + VectorDims offStrides; + VectorDims weiStrides; + VectorDims modStrides; + VectorDims dstStrides; + int *pSampledCoordsVector; + float *pInterpWeightsVector; + }; + + class DefConvRefExecutor : public DefConvExecutor { + public: + DefConvRefExecutor(const DefConvAttr &defConvAttr, + const std::vector> &descVector) : + DefConvExecutor(defConvAttr, descVector) {} + + void exec(const float* src, const float* offsets, + const float* weights, const float* modulation, float* dst, + int *pSampledCoordsVector, float *pInterpWeightsVector) override; + }; + + class DefConvJitExecutor : public DefConvExecutor { + std::shared_ptr def_conv_kernel = nullptr; + public: + DefConvJitExecutor(const DefConvAttr &defConvAttr, + const std::vector> &descVector); + + void exec(const float* src, const float* offsets, + const float* weights, const float* modulation, float* dst, + int *pSampledCoordsVector, float *pInterpWeightsVector) override; + }; + + std::shared_ptr execPtr = nullptr; + bool autoPadding = false; }; - } // namespace MKLDNNPlugin diff --git a/src/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp b/src/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp index 6cd2c5a1529..456269992a5 100644 --- a/src/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp +++ b/src/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp @@ -147,6 +147,9 @@ std::vector disabledTestPatterns() { // TODO : CVS-69533 R"(.*ConvolutionLayerCPUTest.*IS=\{.+\}.*_Fused=.*Add\(Parameters\).*)", R"(.*GroupConvolutionLayerCPUTest.*IS=\{.+\}.*_Fused=.*Add\(Parameters\).*)", + // Issue: 74817 + // Sporadic failings with NAN on Dynamic shape cases with jit implementation + R"(.*DefConvLayoutTest7.*)", // Issue: 71968 R"(.*LSTMSequenceCommonZeroClip.*PURE.*CONST.*hidden_size=10.*sigmoid.sigmoid.sigmoid.*reverse.*FP32_targetDevice=CPU.*)", // Issue: 72005 diff --git a/src/tests/functional/plugin/cpu/single_layer_tests/deformable_convolution.cpp b/src/tests/functional/plugin/cpu/single_layer_tests/deformable_convolution.cpp index 3371cfc3878..2ab81ba4d87 100644 --- a/src/tests/functional/plugin/cpu/single_layer_tests/deformable_convolution.cpp +++ b/src/tests/functional/plugin/cpu/single_layer_tests/deformable_convolution.cpp @@ -3,12 +3,14 @@ // #include "test_utils/cpu_test_utils.hpp" - #include "ngraph_functions/builders.hpp" #include "ngraph_functions/utils/ngraph_helpers.hpp" +#include +#include "shared_test_classes/base/ov_subgraph.hpp" using namespace InferenceEngine; using namespace CPUTestUtils; +using namespace ov::test; namespace CPULayerTestsDefinitions { enum OffsetType {ZERO, NATURAL, REAL_POSITIVE, REAL_NEGATIVE, REAL_MISC}; @@ -20,27 +22,16 @@ typedef std::tuple< > DefConvSpecificParams; typedef std::tuple< - size_t, // batches - std::vector, // input spatial shape - std::vector, // offsets spatial shape - std::vector, // kernel spatial shape ngraph::op::PadType, // pad. type std::vector, // pad. begin std::vector, // pad. end std::vector, // strides std::vector // dilations - > SpatialParams; + > AddSpatialParamsDyn; typedef std::tuple< - size_t, // groups - size_t, // deformable groups - size_t, // input channels per group - size_t // output channels per group - > ChannelParams; - -typedef std::tuple< - SpatialParams, - ChannelParams, + AddSpatialParamsDyn, + std::vector, DefConvSpecificParams, InferenceEngine::Precision, // Net precision LayerTestsUtils::TargetDevice // Device name @@ -51,48 +42,51 @@ typedef std::tuple< CPUSpecificParams> DefConvLayerCPUTestParamsSet; class DefConvLayerCPUTest : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon, public CPUTestsBase { + virtual public SubgraphBaseTest, public CPUTestsBase { public: OffsetType offsetType; static std::string getTestCaseName(testing::TestParamInfo obj) { - CPULayerTestsDefinitions::DefConvLayerTestParams basicParamsSet; - std::string td; - Precision netPr; - InferenceEngine::Precision inPrc, outPrc; - ChannelParams chParams; - SpatialParams spParams; CPULayerTestsDefinitions::DefConvSpecificParams dcSpecificParams; + std::vector inputShape; + InferenceEngine::Precision netPrecision; + CPULayerTestsDefinitions::DefConvLayerTestParams basicParamsSet; CPUSpecificParams cpuParams; std::tie(basicParamsSet, cpuParams) = obj.param; - std::tie(spParams, chParams, dcSpecificParams, netPr, td) = basicParamsSet; - inPrc = outPrc = netPr; + AddSpatialParamsDyn addSpParams; + std::string td; + std::tie(addSpParams, inputShape, dcSpecificParams, netPrecision, td) = basicParamsSet; + ngraph::op::PadType padType; - size_t batch; - InferenceEngine::SizeVector offsets, filter, stride, dilation; + InferenceEngine::SizeVector stride, dilation; std::vector padBegin, padEnd; - InferenceEngine::SizeVector inSpatShape, offSpatShape, kerSpatShape; - std::tie(batch, inSpatShape, offSpatShape, kerSpatShape, - padType, padBegin, padEnd, stride, dilation) = spParams; - size_t groups, deformableGroups, inGrCh, outGrCh; - std::tie(groups, deformableGroups, inGrCh, outGrCh) = chParams; + std::tie(padType, padBegin, padEnd, stride, dilation) = addSpParams; + + // gr * in_ch_per_gr / in_ch_per_gr + size_t groups = inputShape[0].second[0][1] / inputShape[2].second[0][1]; + // dg * ker_spat_shape[0] * ker_spat_shape[1] * 2 / (ker_spat_shape[0] * ker_spat_shape[1] * 2) + size_t deformableGroups = inputShape[1].second[0][1] / (inputShape[2].second[0][2] * inputShape[2].second[0][3] *2); + bool withBilinearInterpolationPad, withModulation; OffsetType offType; std::tie(withBilinearInterpolationPad, withModulation, offType) = dcSpecificParams; + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); std::ostringstream result; result << "DefConvTest("; result << std::to_string(obj.index) << ")_"; - result << "IS=(" << batch << "_" << groups * inGrCh << "_" << inSpatShape[0] << "_" << inSpatShape[1] << ")_"; - result << "OS=(" << batch << "_" << groups * outGrCh << "_" << offSpatShape[0] << "_" << offSpatShape[1] << ")_"; - result << "K" << CommonTestUtils::vec2str(kerSpatShape) << "_"; - result << "S" << CommonTestUtils::vec2str(stride) << "_"; - result << "PB" << CommonTestUtils::vec2str(padBegin) << "_"; - result << "PE" << CommonTestUtils::vec2str(padEnd) << "_"; + result << "IS=" << CommonTestUtils::vec2str(inputShape[0].second) << "_"; + result << "OS=" << CommonTestUtils::vec2str(inputShape[1].second) << "_"; + result << "FS=" << CommonTestUtils::vec2str(inputShape[2].second) << "_"; + if (withModulation) { + result << "MS=" << CommonTestUtils::vec2str(inputShape[3].second) << "_"; + } + result << "G=" << groups << "_"; + result << "DG=" << deformableGroups << "_"; + result << "S=" << CommonTestUtils::vec2str(stride) << "_"; + result << "PB=" << CommonTestUtils::vec2str(padBegin) << "_"; + result << "PE=" << CommonTestUtils::vec2str(padEnd) << "_"; result << "D=" << CommonTestUtils::vec2str(dilation) << "_"; - result << "O=" << groups * outGrCh << "_"; result << "AP=" << padType << "_"; - result << "netPRC=" << netPr.name() << "_"; - result << "inPRC=" << inPrc.name() << "_"; - result << "outPRC=" << outPrc.name() << "_"; + result << "netPRC=" << netPrecision.name() << "_"; result << "withBilPad=" << withBilinearInterpolationPad << "_"; result << "withMod=" << withModulation << "_"; result << "offsetType=" << offType << "_"; @@ -101,87 +95,80 @@ public: return result.str(); } protected: - void GenerateInputs() override { - for (const auto &input : cnnNetwork.getInputsInfo()) { - const auto info = input.second.get(); - const auto &name = info->name(); - InferenceEngine::Blob::Ptr blob; - if (name == "a_data") { - blob = GenerateInput(*info); - } else if (name == "b_offset_vals") { + void generate_inputs(const std::vector& targetInputStaticShapes) override { + inputs.clear(); + const auto& funcInputs = function->inputs(); + auto inShape = targetInputStaticShapes[0]; + auto offShape = targetInputStaticShapes[1]; + auto filtShape = targetInputStaticShapes[2]; + + for (size_t i = 0; i < funcInputs.size(); ++i) { + const auto& funcInput = funcInputs[i]; + ov::runtime::Tensor tensor; + if (i == 0) { // "a_data" + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), inShape, 2, -1, 100); + } else if (i == 1) { // "b_offset_vals" if (offsetType == OffsetType::NATURAL) { - blob = FuncTestUtils::createAndFillBlobFloat(info->getTensorDesc(), 10, 0, 1); + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), offShape, 10, 0, 1); } else if (offsetType == OffsetType::ZERO) { - blob = FuncTestUtils::createAndFillBlobFloat(info->getTensorDesc(), 0, 1, 1); + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), offShape, 1, 0, 1); } else if (offsetType == OffsetType::REAL_POSITIVE) { - blob = FuncTestUtils::createAndFillBlobFloat(info->getTensorDesc(), 2, 0, 100); + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), offShape, 2, 0, 100); } else if (offsetType == OffsetType::REAL_NEGATIVE) { - blob = FuncTestUtils::createAndFillBlobFloat(info->getTensorDesc(), 2, -2, 100); + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), offShape, 2, -2, 100); } else if (offsetType == OffsetType::REAL_MISC) { - blob = FuncTestUtils::createAndFillBlobFloat(info->getTensorDesc(), 4, -2, 100); + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), offShape, 4, -2, 100); } else { IE_THROW() << "Unexpected offset type"; } - } else if (name == "c_filter_vals") { - blob = GenerateInput(*info); - } else if (name == "c_modulation_scalars") { - blob = FuncTestUtils::createAndFillBlobFloat(info->getTensorDesc(), 1, 0, 100); + } else if (i == 2) { // "c_filter_vals" + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), filtShape, 2, -1, 100); + } else if (i == 3) { // "c_modulation_scalars" + auto modShape = targetInputStaticShapes[3]; + tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), modShape, 1, 0, 100); } else { IE_THROW() << "Unknown input of DeformableConvolution"; } - inputs.push_back(blob); + inputs.insert({funcInput.get_node_shared_ptr(), tensor}); } } void SetUp() override { - ChannelParams chParams; - SpatialParams spParams; CPULayerTestsDefinitions::DefConvSpecificParams dcSpecificParams; - - std::vector inShape; + std::vector inputShape; InferenceEngine::Precision netPrecision; CPULayerTestsDefinitions::DefConvLayerTestParams basicParamsSet; CPUSpecificParams cpuParams; std::tie(basicParamsSet, cpuParams) = this->GetParam(); std::tie(inFmts, outFmts, priority, selectedType) = cpuParams; + AddSpatialParamsDyn addSpParams; + std::tie(addSpParams, inputShape, dcSpecificParams, netPrecision, targetDevice) = basicParamsSet; + init_input_shapes(inputShape); - std::tie(spParams, chParams, dcSpecificParams, netPrecision, targetDevice) = basicParamsSet; - - inPrc = outPrc = netPrecision; - inLayout = outLayout = InferenceEngine::Layout::ANY; ngraph::op::PadType padType; - size_t batch; - InferenceEngine::SizeVector offsets, filter, stride, dilation; + InferenceEngine::SizeVector stride, dilation; std::vector padBegin, padEnd; - InferenceEngine::SizeVector inSpatShape, offSpatShape, kerSpatShape; - std::tie(batch, inSpatShape, offSpatShape, kerSpatShape, - padType, padBegin, padEnd, stride, dilation) = spParams; + std::tie(padType, padBegin, padEnd, stride, dilation) = addSpParams; - size_t groups, deformableGroups, inGrCh, outGrCh; - std::tie(groups, deformableGroups, inGrCh, outGrCh) = chParams; + // gr * in_ch_per_gr / in_ch_per_gr + size_t groups = inputShape[0].second[0].at(1) / inputShape[2].second[0].at(1); + // dg * ker_spat_shape[0] * ker_spat_shape[1] * 2 / (ker_spat_shape[0] * ker_spat_shape[1] * 2) + size_t deformableGroups = inputShape[1].second[0].at(1) / + (inputShape[2].second[0].at(2) * inputShape[2].second[0].at(3) * 2); bool withBilinearInterpolationPad, withModulation; std::tie(withBilinearInterpolationPad, withModulation, offsetType) = dcSpecificParams; - - inShape = std::vector({batch, groups * inGrCh, inSpatShape[0], inSpatShape[1]}); - offsets = std::vector {batch, deformableGroups * kerSpatShape[0] * kerSpatShape[1] * 2, - offSpatShape[0], offSpatShape[1]}; - filter = std::vector {groups * outGrCh, inGrCh, kerSpatShape[0], kerSpatShape[1]}; - auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); - auto params = ngraph::builder::makeParams(ngPrc, {inShape, offsets, filter}); - auto paramOuts = ngraph::helpers::convert2OutputVector( - ngraph::helpers::castOps2Nodes(params)); - auto data = std::make_shared(ngPrc, ngraph::Shape(inShape)); + auto inputParams = ngraph::builder::makeDynamicParams(ngPrc, inputDynamicShapes); + + auto data = inputParams[0]; data->set_friendly_name("a_data"); - auto offset_vals = std::make_shared(ngPrc, ngraph::Shape(offsets)); + auto offset_vals = inputParams[1]; offset_vals->set_friendly_name("b_offset_vals"); - auto filter_vals = std::make_shared(ngPrc, ngraph::Shape(filter)); + auto filter_vals = inputParams[2]; filter_vals->set_friendly_name("c_filter_vals"); ngraph::ParameterVector parameters{data, offset_vals, filter_vals}; std::shared_ptr deformable_conv; if (withModulation) { - auto modulation_shape = ngraph::Shape(offsets); - modulation_shape[1] = offsets[1] / 2; - auto modulation_scalars = std::make_shared(ngPrc, modulation_shape); + auto modulation_scalars = inputParams[3]; modulation_scalars->set_friendly_name("c_modulation_scalars"); deformable_conv = std::make_shared(data, offset_vals, filter_vals, modulation_scalars, stride, padBegin, @@ -199,7 +186,7 @@ protected: TEST_P(DefConvLayerCPUTest, CompareWithRefs) { SKIP_IF_CURRENT_TEST_IS_DISABLED() - Run(); + run(); CheckPluginRelatedResults(executableNetwork, "DeformableConvolution"); } @@ -262,24 +249,56 @@ std::vector padTypes = { ngraph::op::PadType::EXPLICIT, ngraph::op::PadType::VALID }; +std::vector> getCartProduct(const std::vector> &v) { + int outSize = 1; + int n = v.size(); + for (int i = 0; i < n; i++) { + outSize *= v[i].size(); + } + std::vector> res(outSize); + for (int i = 0; i < outSize; i++) { + std::vector cortege(n); + int curResid = i, curInd = 0; + for (int j = v.size() - 1; j >= 0 ; j--) { + curInd = curResid % v[j].size(); + curResid = curResid / v[j].size(); + cortege[j] = v[j][curInd]; + } + res[i] = cortege; + } + return res; +} +std::vector> buildStaticParams( + const std::vector> spatParams, + const std::vector> chParamsUncombined) { + std::vector> chParams = getCartProduct(chParamsUncombined); + std::vector> shapes; + for (std::vector &chPar : chParams) { + const size_t batch = spatParams[0][0]; + const size_t inSpH = spatParams[1][0]; + const size_t inSpW = spatParams[1][1]; + const size_t offSpH = spatParams[2][0]; + const size_t offSpW = spatParams[2][1]; + const size_t kerSpH = spatParams[3][0]; + const size_t kerSpW = spatParams[3][1]; -const auto spParams1 = ::testing::Combine( - ::testing::Values(1), // batch - ::testing::Values(std::vector({34, 34})), // in. spat. shape - ::testing::Values(std::vector({32, 32})), // off. spat. shape - ::testing::Values(std::vector({3, 3})), // ker. spat. shape - ::testing::ValuesIn(padTypes), // pad. type - ::testing::Values(std::vector({0, 0})), // pad. begin - ::testing::Values(std::vector({0, 0})), // pad. end - ::testing::Values(std::vector {1, 1}), // strides - ::testing::Values(std::vector {1, 1}) // dilations -); + const size_t gr = chPar[0]; + const size_t defGr = chPar[1]; + const size_t inChPerGr = chPar[2]; + const size_t outChPerGr = chPar[3]; -const auto spParams2 = ::testing::Combine( - ::testing::Values(1), // batch - ::testing::Values(std::vector({3, 3})), // in. spat. shape - ::testing::Values(std::vector({2, 2})), // off. spat. shape - ::testing::Values(std::vector({2, 2})), // ker. spat. shape + std::vector inputShape = { + {batch, gr * inChPerGr, inSpH, inSpW}, + {batch, defGr * kerSpH * kerSpW * 2, offSpH, offSpW}, + {gr * outChPerGr, inChPerGr, kerSpH, kerSpW}, + {batch, defGr * kerSpH * kerSpW, offSpH, offSpW} + }; + shapes.push_back(inputShape); + } + return shapes; +} + +const auto addSpParams = ::testing::Combine( ::testing::ValuesIn(padTypes), // pad. type ::testing::Values(std::vector({0, 0})), // pad. begin ::testing::Values(std::vector({0, 0})), // pad. end @@ -287,132 +306,282 @@ const auto spParams2 = ::testing::Combine( ::testing::Values(std::vector {1, 1}) // dilations ); -const auto spParams3 = ::testing::Combine( - ::testing::Values(1), // batch - ::testing::Values(std::vector({5, 5})), // in. spat. shape - ::testing::Values(std::vector({4, 4})), // off. spat. shape - ::testing::Values(std::vector({2, 2})), // ker. spat. shape - ::testing::ValuesIn(padTypes), // pad. type - ::testing::Values(std::vector({0, 0})), // pad. begin - ::testing::Values(std::vector({0, 0})), // pad. end +const std::vector> spatParams1 = { + {1}, // batch + {34, 34}, // in. spat. shape + {32, 32}, // off. spat. shape + {3, 3} // ker. spat. shape +}; +const std::vector> spatParams2 = { + {1}, // batch + {3, 3}, // in. spat. shape + {2, 2}, // off. spat. shape + {2, 2} // ker. spat. shape +}; +const std::vector> spatParams3 = { + {1}, // batch + {5, 5}, // in. spat. shape + {4, 4}, // off. spat. shape + {2, 2} // ker. spat. shape +}; +const std::vector> spatParams4 = { + {1}, // batch + {3, 2}, // in. spat. shape + {2, 1}, // off. spat. shape + {2, 2} // ker. spat. shape +}; +const std::vector> channelParamsSingleGr = { + {1}, // gr. 2,4 + {1, 2}, // def. gr. 1,2 + {16, 32}, // in. ch. per gr. + {16, 32} // out. ch. per gr. +}; +const std::vector> channelParamsMulGr = { + {2, 4}, // gr. 2,4 + {1, 2}, // def. gr. 1,2 + {3, 7}, // in. ch. per gr. + {3, 7} // out. ch. per gr. +}; + +const std::vector> dynShapeChainRef = { + { + // gr == 2, dg == 1, in_ch_per_gr == 3, out_ch_per_gr == 3 + // {{dynamic shape}, {{static shape case1}, {static shape case2}, ...} + {{-1, -1, -1, -1}, {{1, 6, 3, 2}, {1, 6, 4, 3}, {1, 6, 5, 4}}}, // input 0 + {{-1, -1, -1, -1}, {{1, 8, 2, 1}, {1, 8, 3, 2}, {1, 8, 4, 3}}}, // input 1 + {{6, 3, 2, 2}, {{6, 3, 2, 2}, {6, 3, 2, 2}, {6, 3, 2, 2}}}, // input 2 + {{-1, -1, -1, -1}, {{1, 4, 2, 1}, {1, 4, 3, 2}, {1, 4, 4, 3}}} // input 3 + }, + { + {{{1, 5}, 6, {1, 10}, {1, 8}}, {{2, 6, 3, 2}, {1, 6, 4, 3}, {3, 6, 5, 4}}}, + {{{1, 3}, 8, {1, 10}, {1, 8}}, {{2, 8, 2, 1}, {1, 8, 3, 2}, {3, 8, 4, 3}}}, + {{6, 3, 2, 2}, {{6, 3, 2, 2}, {6, 3, 2, 2}, {6, 3, 2, 2}}}, + {{{1, 3}, 4, {1, 10}, {1, 8}}, {{2, 4, 2, 1}, {1, 4, 3, 2}, {3, 4, 4, 3}}} + }, + { + {{{1, 5}, {1, 6}, {1, 10}, {1, 8}}, {{2, 6, 3, 2}, {1, 6, 4, 3}, {3, 6, 5, 4}}}, + {{{1, 3}, {1, 8}, {1, 10}, {1, 8}}, {{2, 8, 2, 1}, {1, 8, 3, 2}, {3, 8, 4, 3}}}, + {{6, 3, 2, 2}, {{6, 3, 2, 2}, {6, 3, 2, 2}, {6, 3, 2, 2}}}, + {{{1, 3}, {1, 5}, {1, 10}, {1, 8}}, {{2, 4, 2, 1}, {1, 4, 3, 2}, {3, 4, 4, 3}}} + }, +}; +const std::vector> dynShapeChainJIT = { + { + // gr == 1, dg == 1, in_ch_per_gr == 16, out_ch_per_gr == 16 + // {{dynamic shape}, {{static shape case1}, {static shape case2}, ...} + {{-1, -1, -1, -1}, {{1, 16, 3, 2}, {1, 16, 4, 3}, {1, 16, 5, 4}}}, // input 0 + {{-1, 8, -1, -1}, {{1, 8, 2, 1}, {1, 8, 3, 2}, {1, 8, 4, 3}}}, // input 1 + {{16, 16, 2, 2}, {{16, 16, 2, 2}, {16, 16, 2, 2}, {16, 16, 2, 2}}}, // input 2 + {{-1, 4, -1, -1}, {{1, 4, 2, 1}, {1, 4, 3, 2}, {1, 4, 4, 3}}} // input 3 + }, + { + {{{1, 5}, 16, {1, 10}, {1, 8}}, {{1, 16, 3, 2}, {1, 16, 4, 3}, {1, 16, 5, 4}}}, // input 0 + {{{1, 5}, 8, {1, 10}, {1, 8}}, {{1, 8, 2, 1}, {1, 8, 3, 2}, {1, 8, 4, 3}}}, // input 1 + {{16, 16, 2, 2}, {{16, 16, 2, 2}, {16, 16, 2, 2}, {16, 16, 2, 2}}}, // input 2 + {{{1, 5}, 4, {1, 10}, {1, 8}}, {{1, 4, 2, 1}, {1, 4, 3, 2}, {1, 4, 4, 3}}} // input 3 + }, + { + {{{1, 5}, {1, 16}, {1, 10}, {1, 8}}, {{1, 16, 3, 2}, {1, 16, 4, 3}, {1, 16, 5, 4}}}, // input 0 + {{{1, 5}, {1, 8}, {1, 10}, {1, 8}}, {{1, 8, 2, 1}, {1, 8, 3, 2}, {1, 8, 4, 3}}}, // input 1 + {{16, 16, 2, 2}, {{16, 16, 2, 2}, {16, 16, 2, 2}, {16, 16, 2, 2}}}, // input 2 + {{{1, 5}, {1, 5}, {1, 10}, {1, 8}}, {{1, 4, 2, 1}, {1, 4, 3, 2}, {1, 4, 4, 3}}} // input 3 + }, +}; + +// autopad params +const std::vector> dynShapeChainJITAutoPad = { + { + {{{1, 5}, {1, 16}, {1, 10}, {1, 10}}, {{1, 16, 3, 2}, {1, 16, 10, 10}, {1, 16, 3, 2}}}, // input 0 + {{{1, 5}, 8, {1, 10}, {1, 10}}, {{1, 8, 3, 2}, {1, 8, 10, 10}, {1, 8, 3, 2}}}, // input 1 + {{16, 16, 2, 2}, {{16, 16, 2, 2}, {16, 16, 2, 2}, {16, 16, 2, 2}}}, // input 2 + {{{1, 5}, 4, {1, 10}, {1, 10}}, {{1, 4, 3, 2}, {1, 4, 10, 10}, {1, 4, 3, 2}}} // input 3 + } +}; +const std::vector> autoPadSpatParams = { + {1}, // batch + {3, 2}, // in. spat. shape + {3, 2}, // off. spat. shape + {2, 2} // ker. spat. shape +}; + +std::vector padTypesAutoPad = { + ngraph::op::PadType::SAME_LOWER, + ngraph::op::PadType::SAME_UPPER +}; + +const auto autoPadAddSpParams = ::testing::Combine( + ::testing::ValuesIn(padTypesAutoPad), // pad. type + ::testing::Values(std::vector({0, 0})), // pad. begin - ignored + ::testing::Values(std::vector({0, 0})), // pad. end - ignored ::testing::Values(std::vector {1, 1}), // strides ::testing::Values(std::vector {1, 1}) // dilations ); -const auto spParams4 = ::testing::Combine( - ::testing::Values(1), // batch - ::testing::Values(std::vector({3, 2})), // in. spat. shape - ::testing::Values(std::vector({2, 1})), // off. spat. shape - ::testing::Values(std::vector({2, 2})), // ker. spat. shape - ::testing::ValuesIn(padTypes), // pad. type - ::testing::Values(std::vector({0, 0})), // pad. begin - ::testing::Values(std::vector({0, 0})), // pad. end - ::testing::Values(std::vector {1, 1}), // strides - ::testing::Values(std::vector {1, 1}) // dilations -); - -const auto chParamsSingleGr = ::testing::Combine( - ::testing::ValuesIn(std::vector {1}), // gr. 1 - ::testing::ValuesIn(std::vector {1, 2}), // def. gr. 1,2 - ::testing::ValuesIn(std::vector {16, 32}), // in. ch. per gr. - ::testing::ValuesIn(std::vector {16, 32})); // out. ch. per gr. - -const auto chParamsMulGr = ::testing::Combine( - ::testing::ValuesIn(std::vector {2, 4}), // gr. 2,4 - ::testing::ValuesIn(std::vector {1, 2}), // def. gr. 1,2 - ::testing::ValuesIn(std::vector {3, 7}), // in. ch. per gr. - ::testing::ValuesIn(std::vector {3, 7})); // out. ch. per gr. const auto params1_Smoke = ::testing::Combine( - ::testing::Combine( - spParams1, - chParamsSingleGr, - defConvSpecificParams_Smoke, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU)), - ::testing::ValuesIn(filterCPUInfoForDevice())); + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams1, channelParamsSingleGr))), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params2_Smoke = ::testing::Combine( - ::testing::Combine( - spParams2, - chParamsSingleGr, - defConvSpecificParams_Smoke, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU)), - ::testing::ValuesIn(filterCPUInfoForDevice())); + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams2, channelParamsSingleGr))), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params3_Smoke = ::testing::Combine( - ::testing::Combine( - spParams3, - chParamsSingleGr, - defConvSpecificParams_Smoke, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU)), - ::testing::ValuesIn(filterCPUInfoForDevice())); + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams3, channelParamsSingleGr))), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params4_Smoke = ::testing::Combine( - ::testing::Combine( - spParams4, - chParamsSingleGr, - defConvSpecificParams_Smoke, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU)), - ::testing::ValuesIn(filterCPUInfoForDevice())); + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams4, channelParamsSingleGr))), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params5_Smoke = ::testing::Combine( - ::testing::Combine( - spParams4, - chParamsMulGr, - defConvSpecificParams_Smoke, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(CommonTestUtils::DEVICE_CPU)), - ::testing::ValuesIn(filterCPUInfoForDevice(true))); + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams4, channelParamsMulGr))), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(true))); +const auto params6_Smoke = ::testing::Combine( + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(dynShapeChainRef), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(true))); +const auto params7_Smoke = ::testing::Combine( + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(dynShapeChainJIT), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(false))); +const auto params8_Smoke = ::testing::Combine( + ::testing::Combine( + autoPadAddSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(autoPadSpatParams, channelParamsSingleGr))), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice())); +const auto params9_Smoke = ::testing::Combine( + ::testing::Combine( + autoPadAddSpParams, + ::testing::ValuesIn(dynShapeChainJITAutoPad), + defConvSpecificParams_Smoke, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(false))); + INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest1, DefConvLayerCPUTest, params1_Smoke, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest2, DefConvLayerCPUTest, params2_Smoke, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest3, DefConvLayerCPUTest, params3_Smoke, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest4, DefConvLayerCPUTest, params4_Smoke, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest5, DefConvLayerCPUTest, params5_Smoke, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest6, DefConvLayerCPUTest, params6_Smoke, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest7, DefConvLayerCPUTest, params7_Smoke, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest8, DefConvLayerCPUTest, params8_Smoke, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_DefConvLayoutTest9, DefConvLayerCPUTest, params9_Smoke, DefConvLayerCPUTest::getTestCaseName); const auto params1 = ::testing::Combine( ::testing::Combine( - spParams1, - chParamsSingleGr, - defConvSpecificParams, + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams1, channelParamsSingleGr))), + defConvSpecificParams, ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params2 = ::testing::Combine( ::testing::Combine( - spParams2, - chParamsSingleGr, - defConvSpecificParams, + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams2, channelParamsSingleGr))), + defConvSpecificParams, ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params3 = ::testing::Combine( ::testing::Combine( - spParams3, - chParamsSingleGr, - defConvSpecificParams, + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams3, channelParamsSingleGr))), + defConvSpecificParams, ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params4 = ::testing::Combine( ::testing::Combine( - spParams4, - chParamsSingleGr, - defConvSpecificParams, + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams4, channelParamsSingleGr))), + defConvSpecificParams, ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice())); const auto params5 = ::testing::Combine( ::testing::Combine( - spParams4, - chParamsMulGr, - defConvSpecificParams, + addSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(spatParams4, channelParamsMulGr))), + defConvSpecificParams, ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice(true))); +const auto params6 = ::testing::Combine( + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(dynShapeChainRef), + defConvSpecificParams, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(true))); +const auto params7 = ::testing::Combine( + ::testing::Combine( + addSpParams, + ::testing::ValuesIn(dynShapeChainJIT), + defConvSpecificParams, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(false))); +// autopad cases +const auto params8 = ::testing::Combine( + ::testing::Combine( + autoPadAddSpParams, + ::testing::ValuesIn(static_shapes_to_test_representation(buildStaticParams(autoPadSpatParams, channelParamsSingleGr))), + defConvSpecificParams, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice())); +const auto params9 = ::testing::Combine( + ::testing::Combine( + autoPadAddSpParams, + ::testing::ValuesIn(dynShapeChainJITAutoPad), + defConvSpecificParams, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice(false))); + INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest1, DefConvLayerCPUTest, params1, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest2, DefConvLayerCPUTest, params2, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest3, DefConvLayerCPUTest, params3, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest4, DefConvLayerCPUTest, params4, DefConvLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest5, DefConvLayerCPUTest, params5, DefConvLayerCPUTest::getTestCaseName); - +INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest6, DefConvLayerCPUTest, params6, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest7, DefConvLayerCPUTest, params7, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest8, DefConvLayerCPUTest, params8, DefConvLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(DefConvLayoutTest9, DefConvLayerCPUTest, params9, DefConvLayerCPUTest::getTestCaseName); } // namespace } // namespace CPULayerTestsDefinitions