[CPU] DS support for Deformable Convolution (#8986)

This commit is contained in:
Yury Gaydaychuk 2022-01-12 14:08:24 +03:00 committed by GitHub
parent 613facafde
commit b06c0b5c32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 640 additions and 356 deletions

View File

@ -578,10 +578,6 @@ private:
bool MKLDNNDeformableConvolutionNode::isSupportedOperation(const std::shared_ptr<const ngraph::Node>& 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<ngraph::op::util::DeformableConvolutionBase>(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<ngraph::op::v8::DeformableConvolution>(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<DnnlBlockedMemoryDesc>(getInputShapeAtPort(0),
config.inConfs[DATA_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(DATA_ID),
memory::data_type::f32, dataFormat);
config.inConfs[1].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(1),
config.inConfs[OFF_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(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<DnnlBlockedMemoryDesc>(getInputShapeAtPort(2),
memory::data_type::f32, weiFormat);
} else {
config.inConfs[2].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(2),
memory::data_type::f32, weiFormat);
}
config.inConfs[WEI_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(WEI_ID),
memory::data_type::f32, weiFormat);
if (inputsNumber > 3) {
config.inConfs[3].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(3),
config.inConfs[MOD_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(MOD_ID),
memory::data_type::f32, memory::format_tag::nchw);
}
config.outConfs[0].desc = std::make_shared<DnnlBlockedMemoryDesc>(getOutputShapeAtPort(0),
config.outConfs[0].desc = std::make_shared<DnnlBlockedMemoryDesc>(getOutputShapeAtPort(DATA_ID),
memory::data_type::f32, dataFormat);
supportedPrimitiveDescriptors.push_back({config, impl_type});
} else {
// reference implementation
config.inConfs[0].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(0), memory::data_type::f32,
config.inConfs[DATA_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(DATA_ID), memory::data_type::f32,
memory::format_tag::nchw);
config.inConfs[1].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(1), memory::data_type::f32,
config.inConfs[OFF_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(OFF_ID), memory::data_type::f32,
memory::format_tag::nchw);
config.inConfs[2].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(2), memory::data_type::f32,
config.inConfs[WEI_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(WEI_ID), memory::data_type::f32,
memory::format_tag::oihw);
if (inputsNumber > 3) {
config.inConfs[3].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(3), memory::data_type::f32,
config.inConfs[MOD_ID].desc = std::make_shared<DnnlBlockedMemoryDesc>(getInputShapeAtPort(MOD_ID), memory::data_type::f32,
memory::format_tag::nchw);
}
config.outConfs[0].desc = std::make_shared<DnnlBlockedMemoryDesc>(getOutputShapeAtPort(0), memory::data_type::f32,
config.outConfs[0].desc = std::make_shared<DnnlBlockedMemoryDesc>(getOutputShapeAtPort(DATA_ID), memory::data_type::f32,
memory::format_tag::nchw);
supportedPrimitiveDescriptors.push_back({config, impl_type});
}
}
void MKLDNNDeformableConvolutionNode::prepareSamplingWeights(
const std::vector<size_t>& src_strides, const float* offsets, const std::vector<size_t>& off_strides,
const float* modulation, const std::vector<size_t>& 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<int>(map_w) > -1 &&
static_cast<int>(map_w) < IW &&
static_cast<int>(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<std::shared_ptr<BlockedMemoryDesc>> &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<size_t>(srcDesc->getStrides().size());
offStrides = descVector[OFF_ID]->getStrides();
weiStrides = descVector[WEI_ID]->getStrides();
dstStrides = std::vector<size_t>(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<std::shared_ptr<BlockedMemoryDesc>> &descVector) :
DefConvExecutor(defConvAttr, descVector) {
if (mayiuse(cpu::x64::avx512_common)) {
def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32<cpu::x64::avx512_common>(jcp));
} else if (mayiuse(cpu::x64::avx2)) {
def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32<cpu::x64::avx2>(jcp));
} else if (mayiuse(cpu::x64::sse41)) {
def_conv_kernel.reset(new jit_uni_def_conv_kernel_f32<cpu::x64::sse41>(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<size_t>& src_strides,
const std::vector<size_t>& wei_strides, const std::vector<size_t>& 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<size_t>& src_strides,
const std::vector<size_t>& 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<std::shared_ptr<BlockedMemoryDesc>> descVector {
getParentEdgeAt(DATA_ID)->getMemory().GetDescWithType<BlockedMemoryDesc>(),
getParentEdgeAt(OFF_ID)->getMemory().GetDescWithType<BlockedMemoryDesc>(),
getParentEdgeAt(WEI_ID)->getMemory().GetDescWithType<BlockedMemoryDesc>()
};
if (withModulation) {
descVector.push_back(getParentEdgeAt(MOD_ID)->getMemory().GetDescWithType<BlockedMemoryDesc>());
}
descVector.push_back(getChildEdgesAtPort(0)[0]->getMemory().GetDescWithType<BlockedMemoryDesc>());
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<DefConvRefExecutor>(defConvAttr, descVector);
} else {
execPtr = std::make_shared<DefConvJitExecutor>(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<float> 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<BlockedMemoryDesc>();
std::vector<size_t> 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<BlockedMemoryDesc>();
std::vector<size_t> 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<BlockedMemoryDesc>()->getStrides();
auto wei_strides = getParentEdgeAt(2)->getMemory().GetDescWithType<BlockedMemoryDesc>()->getStrides();
InferenceEngine::SizeVector modulation_strides;
if (inputsNumber > 3) {
modulation_strides = getParentEdgeAt(3)->getMemory().GetDescWithType<BlockedMemoryDesc>()->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<ngraph::op::util::DeformableConvolutionBase>(opToShapeInfer);
defConvAttr.padL = defConvNodeBase->get_pads_begin();
}
}

View File

@ -73,7 +73,6 @@ public:
static bool isSupportedOperation(const std::shared_ptr<const ngraph::Node>& 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<ptrdiff_t> stride = {};
std::vector<ptrdiff_t> dilation = {};
std::vector<ptrdiff_t> 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<ptrdiff_t> stride = {};
std::vector<ptrdiff_t> dilation = {};
std::vector<ptrdiff_t> padL;
} defConvAttr;
std::vector<int> sampledCoordsVector;
std::vector<float> interpWeightsVector;
std::shared_ptr<jit_uni_def_conv_kernel> def_conv_kernel = nullptr;
void prepareParams() override;
void updatePadding();
void prepareSamplingWeights(const std::vector<size_t>& src_strides, const float* offsets, const std::vector<size_t>& off_strides,
const float* modulation = nullptr, const std::vector<size_t>& 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<std::shared_ptr<BlockedMemoryDesc>> &descVector);
void executeReference(const float* src, const float* weights, float* dst, const std::vector<size_t>& src_strides,
const std::vector<size_t>& wei_strides, const std::vector<size_t>& dst_strides);
void executeOptimized(const float* src, const float* weights, float* dst,
const std::vector<size_t>& src_strides, const std::vector<size_t>& 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<std::shared_ptr<BlockedMemoryDesc>> &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<jit_uni_def_conv_kernel> def_conv_kernel = nullptr;
public:
DefConvJitExecutor(const DefConvAttr &defConvAttr,
const std::vector<std::shared_ptr<BlockedMemoryDesc>> &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<DefConvExecutor> execPtr = nullptr;
bool autoPadding = false;
};
} // namespace MKLDNNPlugin

View File

@ -147,6 +147,9 @@ std::vector<std::string> 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

View File

@ -3,12 +3,14 @@
//
#include "test_utils/cpu_test_utils.hpp"
#include "ngraph_functions/builders.hpp"
#include "ngraph_functions/utils/ngraph_helpers.hpp"
#include <functional_test_utils/ov_tensor_utils.hpp>
#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<size_t>, // input spatial shape
std::vector<size_t>, // offsets spatial shape
std::vector<size_t>, // kernel spatial shape
ngraph::op::PadType, // pad. type
std::vector<ptrdiff_t>, // pad. begin
std::vector<ptrdiff_t>, // pad. end
std::vector<size_t>, // strides
std::vector<size_t> // 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<InputShape>,
DefConvSpecificParams,
InferenceEngine::Precision, // Net precision
LayerTestsUtils::TargetDevice // Device name
@ -51,48 +42,51 @@ typedef std::tuple<
CPUSpecificParams> DefConvLayerCPUTestParamsSet;
class DefConvLayerCPUTest : public testing::WithParamInterface<DefConvLayerCPUTestParamsSet>,
virtual public LayerTestsUtils::LayerTestsCommon, public CPUTestsBase {
virtual public SubgraphBaseTest, public CPUTestsBase {
public:
OffsetType offsetType;
static std::string getTestCaseName(testing::TestParamInfo<DefConvLayerCPUTestParamsSet> obj) {
CPULayerTestsDefinitions::DefConvLayerTestParams basicParamsSet;
std::string td;
Precision netPr;
InferenceEngine::Precision inPrc, outPrc;
ChannelParams chParams;
SpatialParams spParams;
CPULayerTestsDefinitions::DefConvSpecificParams dcSpecificParams;
std::vector<InputShape> 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<ptrdiff_t> 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<ngraph::Shape>& 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<size_t> inShape;
std::vector<InputShape> 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<ptrdiff_t> 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<size_t>({batch, groups * inGrCh, inSpatShape[0], inSpatShape[1]});
offsets = std::vector<size_t> {batch, deformableGroups * kerSpatShape[0] * kerSpatShape[1] * 2,
offSpatShape[0], offSpatShape[1]};
filter = std::vector<size_t> {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<ngraph::op::Parameter>(params));
auto data = std::make_shared<ngraph::op::Parameter>(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<ngraph::op::Parameter>(ngPrc, ngraph::Shape(offsets));
auto offset_vals = inputParams[1];
offset_vals->set_friendly_name("b_offset_vals");
auto filter_vals = std::make_shared<ngraph::op::Parameter>(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<ngraph::Node> deformable_conv;
if (withModulation) {
auto modulation_shape = ngraph::Shape(offsets);
modulation_shape[1] = offsets[1] / 2;
auto modulation_scalars = std::make_shared<ngraph::op::Parameter>(ngPrc, modulation_shape);
auto modulation_scalars = inputParams[3];
modulation_scalars->set_friendly_name("c_modulation_scalars");
deformable_conv = std::make_shared<ngraph::op::v8::DeformableConvolution>(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<ngraph::op::PadType> padTypes = {
ngraph::op::PadType::EXPLICIT,
ngraph::op::PadType::VALID
};
std::vector<std::vector<size_t>> getCartProduct(const std::vector<std::vector<size_t>> &v) {
int outSize = 1;
int n = v.size();
for (int i = 0; i < n; i++) {
outSize *= v[i].size();
}
std::vector<std::vector<size_t>> res(outSize);
for (int i = 0; i < outSize; i++) {
std::vector<size_t> 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<std::vector<ov::Shape>> buildStaticParams(
const std::vector<std::vector<size_t>> spatParams,
const std::vector<std::vector<size_t>> chParamsUncombined) {
std::vector<std::vector<size_t>> chParams = getCartProduct(chParamsUncombined);
std::vector<std::vector<ov::Shape>> shapes;
for (std::vector<size_t> &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<size_t>({34, 34})), // in. spat. shape
::testing::Values(std::vector<size_t>({32, 32})), // off. spat. shape
::testing::Values(std::vector<size_t>({3, 3})), // ker. spat. shape
::testing::ValuesIn(padTypes), // pad. type
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. begin
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. end
::testing::Values(std::vector<size_t> {1, 1}), // strides
::testing::Values(std::vector<size_t> {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<size_t>({3, 3})), // in. spat. shape
::testing::Values(std::vector<size_t>({2, 2})), // off. spat. shape
::testing::Values(std::vector<size_t>({2, 2})), // ker. spat. shape
std::vector<ov::Shape> 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<ptrdiff_t>({0, 0})), // pad. begin
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. end
@ -287,132 +306,282 @@ const auto spParams2 = ::testing::Combine(
::testing::Values(std::vector<size_t> {1, 1}) // dilations
);
const auto spParams3 = ::testing::Combine(
::testing::Values(1), // batch
::testing::Values(std::vector<size_t>({5, 5})), // in. spat. shape
::testing::Values(std::vector<size_t>({4, 4})), // off. spat. shape
::testing::Values(std::vector<size_t>({2, 2})), // ker. spat. shape
::testing::ValuesIn(padTypes), // pad. type
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. begin
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. end
const std::vector<std::vector<size_t>> spatParams1 = {
{1}, // batch
{34, 34}, // in. spat. shape
{32, 32}, // off. spat. shape
{3, 3} // ker. spat. shape
};
const std::vector<std::vector<size_t>> spatParams2 = {
{1}, // batch
{3, 3}, // in. spat. shape
{2, 2}, // off. spat. shape
{2, 2} // ker. spat. shape
};
const std::vector<std::vector<size_t>> spatParams3 = {
{1}, // batch
{5, 5}, // in. spat. shape
{4, 4}, // off. spat. shape
{2, 2} // ker. spat. shape
};
const std::vector<std::vector<size_t>> spatParams4 = {
{1}, // batch
{3, 2}, // in. spat. shape
{2, 1}, // off. spat. shape
{2, 2} // ker. spat. shape
};
const std::vector<std::vector<size_t>> 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<std::vector<size_t>> 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<std::vector<InputShape>> 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<std::vector<InputShape>> 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<std::vector<InputShape>> 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<std::vector<size_t>> autoPadSpatParams = {
{1}, // batch
{3, 2}, // in. spat. shape
{3, 2}, // off. spat. shape
{2, 2} // ker. spat. shape
};
std::vector<ngraph::op::PadType> 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<ptrdiff_t>({0, 0})), // pad. begin - ignored
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. end - ignored
::testing::Values(std::vector<size_t> {1, 1}), // strides
::testing::Values(std::vector<size_t> {1, 1}) // dilations
);
const auto spParams4 = ::testing::Combine(
::testing::Values(1), // batch
::testing::Values(std::vector<size_t>({3, 2})), // in. spat. shape
::testing::Values(std::vector<size_t>({2, 1})), // off. spat. shape
::testing::Values(std::vector<size_t>({2, 2})), // ker. spat. shape
::testing::ValuesIn(padTypes), // pad. type
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. begin
::testing::Values(std::vector<ptrdiff_t>({0, 0})), // pad. end
::testing::Values(std::vector<size_t> {1, 1}), // strides
::testing::Values(std::vector<size_t> {1, 1}) // dilations
);
const auto chParamsSingleGr = ::testing::Combine(
::testing::ValuesIn(std::vector<size_t> {1}), // gr. 1
::testing::ValuesIn(std::vector<size_t> {1, 2}), // def. gr. 1,2
::testing::ValuesIn(std::vector<size_t> {16, 32}), // in. ch. per gr.
::testing::ValuesIn(std::vector<size_t> {16, 32})); // out. ch. per gr.
const auto chParamsMulGr = ::testing::Combine(
::testing::ValuesIn(std::vector<size_t> {2, 4}), // gr. 2,4
::testing::ValuesIn(std::vector<size_t> {1, 2}), // def. gr. 1,2
::testing::ValuesIn(std::vector<size_t> {3, 7}), // in. ch. per gr.
::testing::ValuesIn(std::vector<size_t> {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