[CPU] Native dynamic shapes support in the Convolution node (#8047)

* Dynamic conv first commit

* Fixes after rebase

* Refactoring:

1. Conv node code refactor
2. DW conv fusing is disabled for dynamic case
3. Weights static shape constraint was added

* Minor fix for 1st rank bias

* WA fix

* MKLDNN dynamic conv fixes

* Temporal WA on format serialization

* Convolution SL prepared for dynamism

* Fix for bias fusing

* Update for nspc heuristics

* Convolution SL tests are updated with dynamic shapes

* GroupConv SL tests are updated with dynamic shapes

* Wip

* Dynamic shapes post ops support

* Dynamic shapes convolution full SL tests support

* Convolution builder changed to support pShape

* Convolution CPU SL test moved to the new Test Infra

* Skip tests conf update

* Auto padding support in dynamic mode with test

* Convolution dyn tests for bf16

* Group Conv test commented

* Submodule up

* First review fixes

* Group convolution dynamic shapes SL test

* Serialize format method has been fixed

* Floating point numbers resolution changed to even number

* AutoPad flag was added

* Skip test config updated with changed signature

* An attempt to reduce SL test time

* Dilated convolution tests extracted from the precommit
This commit is contained in:
Maksim Kutakov 2021-11-18 18:53:16 +03:00 committed by GitHub
parent 3efd842dd9
commit a3fae37fe1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1220 additions and 674 deletions

View File

@ -29,3 +29,29 @@ bool BlockedMemoryDesc::isCompatible(const BlockedMemoryDesc &rhs) const {
return dimsEqualWeak(this->getOffsetPadding(), rhs.getOffsetPadding());
}
std::string BlockedMemoryDesc::serializeFormat() const {
std::stringstream result;
char startLetter = 'a';
std::unordered_set<size_t> blockedAxis;
const auto& order = getOrder();
const auto& shape = getShape();
for (size_t i = shape.getRank(); i < order.size(); ++i) {
blockedAxis.insert(order[i]);
}
for (size_t i = 0; i < shape.getRank(); ++i) {
char nextLetter = startLetter + order[i];
if (blockedAxis.count(i)) {
nextLetter = toupper(nextLetter);
}
result << nextLetter;
}
const auto& blkDims = getBlockDims();
for (size_t i = shape.getRank(); i < order.size(); ++i) {
result << blkDims[i] << char(startLetter + order[i]);
}
return result.str();
}

View File

@ -75,6 +75,8 @@ public:
*/
virtual MemoryDescPtr cloneWithDefaultStridesAndOffset() const = 0;
std::string serializeFormat() const override;
protected:
/**
* @brief Check descs on compatibility

View File

@ -214,29 +214,6 @@ bool CpuBlockedMemoryDesc::isTailCFormat() const {
return true;
}
std::string CpuBlockedMemoryDesc::serializeFormat() const {
std::stringstream result;
char startLetter = 'a';
std::unordered_map<size_t, size_t> mapAxisBlockSize;
for (size_t i = shape.getRank(); i < order.size(); ++i) {
mapAxisBlockSize.insert({order[i], blockedDims[i]});
}
for (size_t i = 0; i < shape.getRank(); ++i) {
char nextLetter = startLetter + order[i];
if (mapAxisBlockSize.count(i)) {
nextLetter = toupper(nextLetter);
}
result << nextLetter;
}
for (auto& item : mapAxisBlockSize) {
result << item.second << char(startLetter + item.first);
}
return result.str();
}
MemoryDescPtr CpuBlockedMemoryDesc::cloneWithNewDimsImp(const VectorDims &dims) const {
if (std::any_of(dims.begin(), dims.end(), [](size_t x){ return Shape::UNDEFINED_DIM == x; })) {
IE_THROW() << "Can't clone desc if new dims are undefined";

View File

@ -72,8 +72,6 @@ public:
bool hasLayoutType(LayoutType layoutType) const override;
std::string serializeFormat() const override;
size_t getMaxMemSize() const override;
size_t getPaddedElementsCount() const override;

View File

@ -401,207 +401,6 @@ MemoryDescPtr DnnlBlockedMemoryDesc::cloneWithNewDimsImp(const VectorDims &dims)
return DnnlBlockedMemoryDescPtr(new DnnlBlockedMemoryDesc(cloneDescWithNewDims(desc, dims, order)));
}
static const std::map<int, std::vector<mkldnn::memory::format_tag>> form_tags_by_ndims {
{0, {
mkldnn::memory::format_tag::a // TODO :: really 1d layout for scalar??
}}, {1, {
mkldnn::memory::format_tag::a
}}, {2, {
mkldnn::memory::format_tag::ab,
mkldnn::memory::format_tag::ba
}}, {3, {
mkldnn::memory::format_tag::abc,
mkldnn::memory::format_tag::acb,
mkldnn::memory::format_tag::bac,
mkldnn::memory::format_tag::bca,
mkldnn::memory::format_tag::cba,
mkldnn::memory::format_tag::Abc16a,
mkldnn::memory::format_tag::ABc16a16b,
mkldnn::memory::format_tag::ABc4a4b,
mkldnn::memory::format_tag::aBc16b,
mkldnn::memory::format_tag::aBc32b,
mkldnn::memory::format_tag::ABc16b16a,
mkldnn::memory::format_tag::Abc4a,
mkldnn::memory::format_tag::aBc4b,
mkldnn::memory::format_tag::ABc4b16a4b,
mkldnn::memory::format_tag::ABc2b8a4b,
mkldnn::memory::format_tag::ABc16b16a4b,
mkldnn::memory::format_tag::ABc16b16a2b,
mkldnn::memory::format_tag::ABc4b4a,
mkldnn::memory::format_tag::ABc8a16b2a,
mkldnn::memory::format_tag::ABc8a8b,
mkldnn::memory::format_tag::ABc8a4b,
mkldnn::memory::format_tag::aBc8b,
mkldnn::memory::format_tag::ABc8b16a2b,
mkldnn::memory::format_tag::ABc8b8a,
mkldnn::memory::format_tag::Acb16a,
mkldnn::memory::format_tag::Acb4a,
mkldnn::memory::format_tag::Acb8a,
mkldnn::memory::format_tag::BAc16a16b,
mkldnn::memory::format_tag::BAc16b16a,
}}, {4, { // Popular
mkldnn::memory::format_tag::abcd, // plain
mkldnn::memory::format_tag::acdb, // tail_c
mkldnn::memory::format_tag::aBcd8b, // blocked 8c
mkldnn::memory::format_tag::aBcd16b, // blocked 16c
mkldnn::memory::format_tag::abdc,
mkldnn::memory::format_tag::bacd,
mkldnn::memory::format_tag::bcda,
mkldnn::memory::format_tag::cdba,
mkldnn::memory::format_tag::dcab,
mkldnn::memory::format_tag::Abcd8a,
mkldnn::memory::format_tag::Abcd16a,
mkldnn::memory::format_tag::Abcd32a,
mkldnn::memory::format_tag::ABcd16a16b,
mkldnn::memory::format_tag::aBcd32b,
mkldnn::memory::format_tag::ABcd16b16a,
mkldnn::memory::format_tag::aBCd16b16c,
mkldnn::memory::format_tag::aBCd16c16b,
mkldnn::memory::format_tag::Abcd4a,
mkldnn::memory::format_tag::aBcd4b,
mkldnn::memory::format_tag::ABcd4b16a4b,
mkldnn::memory::format_tag::ABcd2b8a4b,
mkldnn::memory::format_tag::ABcd4b4a,
mkldnn::memory::format_tag::ABcd4a4b,
mkldnn::memory::format_tag::aBCd4c16b4c,
mkldnn::memory::format_tag::aBCd2c8b4c,
mkldnn::memory::format_tag::ABcd16b16a4b,
mkldnn::memory::format_tag::ABcd16b16a2b,
mkldnn::memory::format_tag::aBCd16c16b4c,
mkldnn::memory::format_tag::aBCd16c16b2c,
mkldnn::memory::format_tag::aBCd4c4b,
mkldnn::memory::format_tag::aBCd4b4c,
mkldnn::memory::format_tag::ABcd8a16b2a,
mkldnn::memory::format_tag::ABcd8a8b,
mkldnn::memory::format_tag::ABcd8a32b,
mkldnn::memory::format_tag::ABcd32a32b,
mkldnn::memory::format_tag::ABcd8a4b,
mkldnn::memory::format_tag::ABcd8b16a2b,
mkldnn::memory::format_tag::aBCd8b16c2b,
mkldnn::memory::format_tag::ABcd8b8a,
mkldnn::memory::format_tag::aBCd8b8c,
mkldnn::memory::format_tag::aBCd8b4c,
mkldnn::memory::format_tag::aBCd8c16b2c,
mkldnn::memory::format_tag::aBCd8c8b,
mkldnn::memory::format_tag::ABcd4a8b8a4b,
mkldnn::memory::format_tag::ABcd2a8b8a2b,
mkldnn::memory::format_tag::aBdc16b,
mkldnn::memory::format_tag::aBdc4b,
mkldnn::memory::format_tag::aBdc8b,
mkldnn::memory::format_tag::aCBd16b16c,
mkldnn::memory::format_tag::aCBd16c16b,
mkldnn::memory::format_tag::Acdb16a,
mkldnn::memory::format_tag::Acdb4a,
mkldnn::memory::format_tag::Acdb8a,
mkldnn::memory::format_tag::BAcd16a16b,
mkldnn::memory::format_tag::BAcd16b16a,
mkldnn::memory::format_tag::ABcd32a32b,
mkldnn::memory::format_tag::Acdb32a,
mkldnn::memory::format_tag::aBCd2b4c2b,
mkldnn::memory::format_tag::aBCd2c4b2c,
mkldnn::memory::format_tag::aBCd4b8c2b,
mkldnn::memory::format_tag::aBCd4c8b2c,
}}, {5, { // Popular
mkldnn::memory::format_tag::abcde, // plain
mkldnn::memory::format_tag::acdeb, // tail_c
mkldnn::memory::format_tag::aBcde8b, // blocked 8c
mkldnn::memory::format_tag::aBcde16b, // blocked 16c
mkldnn::memory::format_tag::abdec,
mkldnn::memory::format_tag::acbde,
mkldnn::memory::format_tag::bacde,
mkldnn::memory::format_tag::bcdea,
mkldnn::memory::format_tag::cdeba,
mkldnn::memory::format_tag::decab,
mkldnn::memory::format_tag::Abcde16a,
mkldnn::memory::format_tag::Abcde32a,
mkldnn::memory::format_tag::ABcde16a16b,
mkldnn::memory::format_tag::aBcde32b,
mkldnn::memory::format_tag::ABcde16b16a,
mkldnn::memory::format_tag::aBCde16b16c,
mkldnn::memory::format_tag::aBCde16c16b,
mkldnn::memory::format_tag::aBCde2c8b4c,
mkldnn::memory::format_tag::Abcde4a,
mkldnn::memory::format_tag::aBcde4b,
mkldnn::memory::format_tag::ABcde4b4a,
mkldnn::memory::format_tag::ABcde4a4b,
mkldnn::memory::format_tag::aBCde4b4c,
mkldnn::memory::format_tag::aBCde4c16b4c,
mkldnn::memory::format_tag::aBCde16c16b4c,
mkldnn::memory::format_tag::aBCde16c16b2c,
mkldnn::memory::format_tag::aBCde4c4b,
mkldnn::memory::format_tag::Abcde8a,
mkldnn::memory::format_tag::ABcde8a8b,
mkldnn::memory::format_tag::ABcde8a4b,
mkldnn::memory::format_tag::ABcde8b16a2b,
mkldnn::memory::format_tag::ABcde4b16a4b,
mkldnn::memory::format_tag::ABcde2b8a4b,
mkldnn::memory::format_tag::aBCde8b16c2b,
mkldnn::memory::format_tag::ABcde8b8a,
mkldnn::memory::format_tag::aBCde8b8c,
mkldnn::memory::format_tag::aBCde8b4c,
mkldnn::memory::format_tag::aBCde4b8c8b4c,
mkldnn::memory::format_tag::aBCde2b8c8b2c,
mkldnn::memory::format_tag::aBCde8c16b2c,
mkldnn::memory::format_tag::aBCde8c8b,
mkldnn::memory::format_tag::aBdec16b,
mkldnn::memory::format_tag::aBdec4b,
mkldnn::memory::format_tag::aBdec8b,
mkldnn::memory::format_tag::aCBde16b16c,
mkldnn::memory::format_tag::aCBde16c16b,
mkldnn::memory::format_tag::Acdeb16a,
mkldnn::memory::format_tag::Acdeb4a,
mkldnn::memory::format_tag::Acdeb8a,
mkldnn::memory::format_tag::BAcde16b16a,
mkldnn::memory::format_tag::BAcde16a16b,
mkldnn::memory::format_tag::aBdec32b,
mkldnn::memory::format_tag::aBCde2b4c2b,
mkldnn::memory::format_tag::aBCde2c4b2c,
mkldnn::memory::format_tag::aBCde4b8c2b,
mkldnn::memory::format_tag::aBCde4c8b2c,
}}, {6, { // Popular
mkldnn::memory::format_tag::abcdef, // plain
mkldnn::memory::format_tag::acbdef, // permute
mkldnn::memory::format_tag::defcab, // permute
mkldnn::memory::format_tag::aBcdef16b, // blocked 16c
mkldnn::memory::format_tag::aBCdef16b16c,
mkldnn::memory::format_tag::aBCdef16c16b,
mkldnn::memory::format_tag::aBcdef4b,
mkldnn::memory::format_tag::aBCdef2c8b4c,
mkldnn::memory::format_tag::aBCdef4c4b,
mkldnn::memory::format_tag::aBCdef4b4c,
mkldnn::memory::format_tag::aBCdef8b8c,
mkldnn::memory::format_tag::aBCdef8b4c,
mkldnn::memory::format_tag::aBCdef8c16b2c,
mkldnn::memory::format_tag::aBCdef4c16b4c,
mkldnn::memory::format_tag::aBCdef8c8b,
mkldnn::memory::format_tag::aBdefc16b,
mkldnn::memory::format_tag::aCBdef16c16b,
mkldnn::memory::format_tag::aCBdef16b16c,
mkldnn::memory::format_tag::aBdefc4b,
mkldnn::memory::format_tag::aBdefc8b,
mkldnn::memory::format_tag::Abcdef4a,
mkldnn::memory::format_tag::Abcdef8a,
mkldnn::memory::format_tag::Abcdef16a,
mkldnn::memory::format_tag::Abcdef32a,
mkldnn::memory::format_tag::aBCdef2b4c2b,
mkldnn::memory::format_tag::aBCdef2c4b2c,
mkldnn::memory::format_tag::aBCdef4b8c2b,
mkldnn::memory::format_tag::aBCdef4c8b2c,
}}
};
bool DnnlBlockedMemoryDesc::isSame(mkldnn::memory::format_tag fmt) const {
mkldnn::memory::desc refDesc(desc.dims(), desc.data_type(), fmt);
@ -676,28 +475,6 @@ bool DnnlBlockedMemoryDesc::isSame(mkldnn::memory::format_tag fmt) const {
return true;
}
mkldnn::memory::format_tag DnnlBlockedMemoryDesc::getFormat() const {
// TODO [OneDNN]: Previously it was a field of tdesc, but now the brute
// force search here. Please avoid of using this method.
const auto ndims = desc.dims().size();
// There are no suitable format_tag for this
if (ndims == 0 || ndims > 6)
return mkldnn::memory::format_tag::undef;
for (const auto fmt : form_tags_by_ndims.at(ndims)) {
if (this->isSame(fmt))
return fmt;
}
return mkldnn::memory::format_tag::undef;
}
std::string DnnlBlockedMemoryDesc::serializeFormat() const {
auto fmt = getFormat();
return mkldnn::utils::fmt2str(fmt);
}
size_t DnnlBlockedMemoryDesc::getMaxMemSize() const {
if (shape.isStatic()) {
return getCurrentMemSize();
@ -858,3 +635,7 @@ DnnlBlockedMemoryDesc::DnnlBlockedMemoryDesc(const mkldnn::memory::desc& mdesc,
initBlockedParams();
}
std::string DnnlBlockedMemoryDesc::serializeFormat() const {
return BlockedMemoryDesc::serializeFormat();
}

View File

@ -95,13 +95,6 @@ private:
void recomputeDefaultStrides();
/**
* Try to define original format tag use on creation
*
* @return format tag if was able to define it
*/
mkldnn::memory::format_tag getFormat() const;
friend DnnlMemoryDescPtr MKLDNNExtensionUtils::makeDescriptor(const mkldnn::memory::desc &desc);
friend std::shared_ptr<DnnlBlockedMemoryDesc> MKLDNNExtensionUtils::makeUndefinedDesc(const mkldnn::memory::desc &desc, const Shape& shape);
friend class MemoryDescUtils;

View File

@ -263,7 +263,8 @@ void MKLDNNGraphOptimizer::FuseConvolutionAndBias(MKLDNNGraph &graph) {
graphEdges.push_back(newEdge);
parent->addEdge(newEdge);
parent->outputShapes[inNum] = Shape(VectorDims{parentEltwise->outputShapes[0].getStaticDims()[1]});
auto partialShape = { parentEltwise->outputShapes[0].toPartialShape()[1] };
parent->outputShapes[inNum] = Shape(partialShape);
parentEltwise->inputShapes.push_back(parent->outputShapes[0]);
}
}
@ -726,6 +727,9 @@ void MKLDNNGraphOptimizer::FuseConvolutionAndDWConvolution(MKLDNNGraph &graph) {
if (node->isDropped())
return false;
if (node->isDynamicNode())
return false;
const auto conv = std::dynamic_pointer_cast<MKLDNNConvolutionNode>(node);
if (conv == nullptr)
IE_THROW() << "Cannot cast to convolution node " << node->getName();
@ -754,6 +758,9 @@ void MKLDNNGraphOptimizer::FuseConvolutionAndDWConvolution(MKLDNNGraph &graph) {
if (parentNode->isDropped() || childNode->isDropped())
return false;
if (childNode->isDynamicNode())
return false;
const auto convChild = std::dynamic_pointer_cast<MKLDNNConvolutionNode>(childNode);
if (convChild == nullptr)
IE_THROW() << "Cannot cast to convolution node " << childNode->getName();

View File

@ -957,14 +957,14 @@ bool MKLDNNNode::isConfigDefined(const NodeConfig &config) const {
}
MemoryDescPtr MKLDNNNode::getSrcMemDesc(mkldnn::primitive_desc_iterator &primitive_desc_it, size_t idx) {
if (isDynamicNode()) {
if (getInputShapeAtPort(idx).isDynamic()) {
return MKLDNNExtensionUtils::makeUndefinedDesc(primitive_desc_it.src_desc(idx), getInputShapeAtPort(idx));
}
return MKLDNNExtensionUtils::makeDescriptor(primitive_desc_it.src_desc(idx));
}
MemoryDescPtr MKLDNNNode::getDstMemDesc(mkldnn::primitive_desc_iterator &primitive_desc_it, size_t idx) {
if (isDynamicNode()) {
if (getOutputShapeAtPort(idx).isDynamic()) {
return MKLDNNExtensionUtils::makeUndefinedDesc(primitive_desc_it.dst_desc(idx), getOutputShapeAtPort(idx));
}
return MKLDNNExtensionUtils::makeDescriptor(primitive_desc_it.dst_desc(idx));

View File

@ -28,20 +28,19 @@ using namespace InferenceEngine;
bool MKLDNNConvolutionNode::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 (!ngraph::is_type<ngraph::op::v1::Convolution>(op) && !ngraph::is_type<ngraph::op::v1::GroupConvolution>(op)) {
errorMessage = "Only opset1 Convolution and GroupConvolution operations are supported";
return false;
}
size_t ndims = op->get_input_shape(0).size();
size_t ndims = op->get_input_partial_shape(0).rank().get_length();
if ((ndims < 4) || (ndims > 5)) {
errorMessage = "Doesn't support 'data' input with rank: " + std::to_string(ndims);
return false;
}
if (op->get_input_partial_shape(1).is_dynamic()) {
errorMessage = "Doesn't support dynamic weights shape";
return false;
}
} catch (...) {
return false;
}
@ -83,6 +82,7 @@ MKLDNNConvolutionNode::MKLDNNConvolutionNode(const std::shared_ptr<ngraph::Node>
}
paddingL = convolutionOp->get_pads_begin();
paddingR = convolutionOp->get_pads_end();
autoPadding = one_of(convolutionOp->get_auto_pad(), ov::op::PadType::SAME_UPPER, ov::op::PadType::SAME_LOWER);
} else if (groupConvolutionOp) {
algorithm = ConvolutionGrouped;
@ -105,6 +105,7 @@ MKLDNNConvolutionNode::MKLDNNConvolutionNode(const std::shared_ptr<ngraph::Node>
}
paddingL = groupConvolutionOp->get_pads_begin();
paddingR = groupConvolutionOp->get_pads_end();
autoPadding = one_of(groupConvolutionOp->get_auto_pad(), ov::op::PadType::SAME_UPPER, ov::op::PadType::SAME_LOWER);
}
}
@ -204,6 +205,9 @@ void MKLDNNConvolutionNode::getSupportedDescriptors() {
int ndims = getInputShapeAtPort(0).getRank();
withDWConv = isFusedWith(Convolution);
if (withDWConv && isDynamicNode()) {
IE_THROW() << "DW convolution is fused into convolution node " << getName() << " with dynamic shape.";
}
for (int i = 0; i < fusedWith.size(); i++) {
auto *convolutionNode = dynamic_cast<MKLDNNConvolutionNode *>(fusedWith[i].get());
@ -326,7 +330,7 @@ void MKLDNNConvolutionNode::getSupportedDescriptors() {
}
}
void MKLDNNConvolutionNode::setPostOps(mkldnn::primitive_attr &attr, bool initWeights = false, bool initAsBinary = false) {
void MKLDNNConvolutionNode::setPostOps(mkldnn::primitive_attr &attr, const VectorDims &dims, bool initWeights = false, bool initAsBinary = false) {
bool initBinaryMemory = initWeights;
mkldnn::post_ops ops;
@ -340,7 +344,7 @@ void MKLDNNConvolutionNode::setPostOps(mkldnn::primitive_attr &attr, bool initWe
ops.append_sum(1.0, MKLDNNExtensionUtils::IEPrecisionToDataType(eltwisePrecision));
} else {
constexpr int align = 16;
eltwiseNode->appendPostOps(ops, getOutputShapeAtPort(0).getStaticDims(), align, initAsBinary, initBinaryMemory);
eltwiseNode->appendPostOps(ops, dims, align, initAsBinary, initBinaryMemory);
if (initBinaryMemory) {
if (eltwiseNode->scalesMemory)
binaryPostOpsArgs.push_back(eltwiseNode->scalesMemory->GetPrimitive());
@ -354,8 +358,7 @@ void MKLDNNConvolutionNode::setPostOps(mkldnn::primitive_attr &attr, bool initWe
auto* fakeQuantizeNode = dynamic_cast<MKLDNNFakeQuantizeNode *>(node.get());
if (fakeQuantizeNode) {
constexpr int align = -1;
// no need to fill post ops dims for fq, make sense only for bin fq
fakeQuantizeNode->appendPostOps(ops, VectorDims{}, align, initAsBinary, initBinaryMemory);
fakeQuantizeNode->appendPostOps(ops, dims, align, initAsBinary, initBinaryMemory);
if (initBinaryMemory) {
if (fakeQuantizeNode->cropHighMemory)
binaryPostOpsArgs.push_back(fakeQuantizeNode->cropHighMemory->GetPrimitive());
@ -412,8 +415,8 @@ void MKLDNNConvolutionNode::initSupportedPrimitiveDescriptors() {
// attr[0] - depthwise, quantize
// attr[1] - binary
mkldnn::primitive_attr attrs[1];
setPostOps(attrs[0]);
// setPostOps(attrs[1], false, true);
setPostOps(attrs[0], MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims());
// setPostOps(attrs[1], MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims(), false, true);
bool containJitImpl = false;
@ -493,57 +496,90 @@ void MKLDNNConvolutionNode::initSupportedPrimitiveDescriptors() {
void MKLDNNConvolutionNode::createPrimitive() {
if (prim)
return;
mkldnn::primitive_attr attr;
addZeroPoints(attr);
// todo: [AV] delete "false" to use binary mechanism
if (false && getSelectedPrimitiveDescriptor()->getImplementationType() == jit_gemm) {
setPostOps(attr, true, true);
} else {
setPostOps(attr, true);
if (inputShapesDefined()) {
if (needPrepareParams())
prepareParams();
updateLastInputDims();
}
auto prim_desc = createPrimitiveDescriptor<convolution_forward::primitive_desc,
convolution_forward::desc>(attr);
prim.reset(new convolution_forward(prim_desc));
auto src = getParentEdgesAtPort(0)[0]->getMemoryPtr()->GetPrimitive();
auto dst = getChildEdgesAtPort(0)[0]->getMemoryPtr()->GetPrimitive();
if (withBiases)
primArgs = {{DNNL_ARG_SRC, src}, {DNNL_ARG_WEIGHTS, getWeights()}, {DNNL_ARG_BIAS, getBias()}, {DNNL_ARG_DST, dst}};
else
primArgs = {{DNNL_ARG_SRC, src}, {DNNL_ARG_WEIGHTS, getWeights()}, {DNNL_ARG_DST, dst}};
// todo: [AV] uncomment to use binary mechanism
// auto post_ops = attr.get_post_ops();
// int idx = 0;
// for (int i = 0; i < post_ops.len(); i++) {
// if (post_ops.kind(i) == mkldnn::primitive::kind::binary) {
// primArgs.insert({DNNL_ARG_ATTR_MULTIPLE_POST_OP(i) | DNNL_ARG_SRC_1, binaryPostOpsArgs[idx++]});
// }
// }
}
bool MKLDNNConvolutionNode::created() const {
return getType() == Convolution;
}
std::shared_ptr<mkldnn::convolution_forward::desc>
MKLDNNConvolutionNode::createDescriptorInternal(const mkldnn::memory::desc& inputDesc,
const mkldnn::memory::desc& weightDesc,
const mkldnn::memory::desc& outputDesc,
mkldnn::algorithm alg) {
updatePadding();
std::shared_ptr<mkldnn::convolution_forward::desc> conv_desc;
try {
conv_desc.reset(new convolution_forward::desc(prop_kind::forward_scoring, alg,
inputDesc, weightDesc, outputDesc,
mkldnn::memory::dims(stride.begin(), stride.end()),
mkldnn::memory::dims(dilation.begin(), dilation.end()),
mkldnn::memory::dims(paddingL.begin(), paddingL.end()),
mkldnn::memory::dims(paddingR.begin(), paddingR.end())));
}
catch (...) {
IE_THROW() << "Cannot create convolution forward descriptor for layer: " << getName();
}
return conv_desc;
}
std::shared_ptr<mkldnn::convolution_forward::desc>
MKLDNNConvolutionNode::createDescriptorInternal(const mkldnn::memory::desc& inputDesc,
const mkldnn::memory::desc& weightDesc,
const mkldnn::memory::desc& biasDesc,
const mkldnn::memory::desc& outputDesc,
mkldnn::algorithm alg) {
updatePadding();
std::shared_ptr<mkldnn::convolution_forward::desc> conv_desc;
try {
conv_desc.reset(new convolution_forward::desc(prop_kind::forward_scoring, alg,
inputDesc, weightDesc, biasDesc, outputDesc,
mkldnn::memory::dims(stride.begin(), stride.end()),
mkldnn::memory::dims(dilation.begin(), dilation.end()),
mkldnn::memory::dims(paddingL.begin(), paddingL.end()),
mkldnn::memory::dims(paddingR.begin(), paddingR.end())));
}
catch (...) {
IE_THROW() << "Cannot create convolution forward descriptor for layer: " << getName();
}
return conv_desc;
}
void MKLDNNConvolutionNode::createDescriptor(const std::vector<MemoryDescPtr>& inputDesc,
const std::vector<MemoryDescPtr>& outputDesc) {
const auto inDesc = MemoryDescUtils::convertToDnnlMemoryDesc(inputDesc[0])->getDnnlDesc();
const auto outDesc = MemoryDescUtils::convertToDnnlMemoryDesc(outputDesc[0])->getDnnlDesc();
auto inpDesc = inputDesc[0]->isDefined() ? inputDesc[0] : MemoryDescUtils::makeDummyDesc(*inputDesc[0]);
DnnlMemoryDescPtr definedInpMemDesc = MemoryDescUtils::convertToDnnlMemoryDesc(inpDesc);
DnnlMemoryDescPtr definedOutMemDesc;
memory::data_type wdt = static_cast<memory::data_type>(inDesc.data.data_type);
memory::data_type bdt = memory::data_type::f32;
if (outputDesc[0]->isDefined()) {
definedOutMemDesc = MemoryDescUtils::convertToDnnlMemoryDesc(outputDesc[0]);
} else {
std::vector<Shape> shapes = { definedInpMemDesc->getShape(), Shape(weightDims) };
auto outDims = shapeInferGeneric(shapes);
definedOutMemDesc = MemoryDescUtils::convertToDnnlMemoryDesc(outputDesc[0]->cloneWithNewDims(outDims.front()));
}
if (inDesc.data.data_type == mkldnn_s8 || inDesc.data.data_type == mkldnn_u8) {
const auto& inDnnlDesc = definedInpMemDesc->getDnnlDesc();
const auto& outDnnlDesc = definedOutMemDesc->getDnnlDesc();
memory::data_type wdt = static_cast<memory::data_type>(inDnnlDesc.data.data_type);
if (inDnnlDesc.data.data_type == mkldnn_s8 || inDnnlDesc.data.data_type == mkldnn_u8) {
wdt = memory::data_type::s8;
}
mkldnn::memory::desc wgh_candidate(MKLDNNExtensionUtils::convertToDnnlDims(weightDims), wdt, memory::format_tag::any);
mkldnn::memory::desc weightDnnlDesc(MKLDNNExtensionUtils::convertToDnnlDims(weightDims), wdt, memory::format_tag::any);
mkldnn::memory::desc biasDnnlDesc;
if (withBiases) {
memory::data_type bdt = memory::data_type::f32;
biasDnnlDesc = mkldnn::memory::desc(MKLDNNExtensionUtils::convertToDnnlDims(biasesDims), bdt, memory::format_tag::any);
}
std::vector<mkldnn::algorithm> algorithms;
@ -552,29 +588,10 @@ void MKLDNNConvolutionNode::createDescriptor(const std::vector<MemoryDescPtr>& i
algorithms.push_back(mkldnn::algorithm::convolution_direct);
for (auto alg : algorithms) {
try {
std::shared_ptr<mkldnn::convolution_forward::desc> conv_desc;
if (withBiases) {
mkldnn::memory::desc bias_candidate(MKLDNNExtensionUtils::convertToDnnlDims(biasesDims), bdt, memory::format_tag::any);
conv_desc.reset(new convolution_forward::desc(prop_kind::forward_scoring, alg,
inDesc, wgh_candidate, bias_candidate, outDesc,
mkldnn::memory::dims(stride.begin(), stride.end()),
mkldnn::memory::dims(dilation.begin(), dilation.end()),
mkldnn::memory::dims(paddingL.begin(), paddingL.end()),
mkldnn::memory::dims(paddingR.begin(), paddingR.end())));
} else {
conv_desc.reset(new convolution_forward::desc(prop_kind::forward_scoring, alg,
inDesc, wgh_candidate, outDesc,
mkldnn::memory::dims(stride.begin(), stride.end()),
mkldnn::memory::dims(dilation.begin(), dilation.end()),
mkldnn::memory::dims(paddingL.begin(), paddingL.end()),
mkldnn::memory::dims(paddingR.begin(), paddingR.end())));
}
descs.emplace_back(conv_desc);
} catch (...) {
IE_THROW() << "Cannot create convolution forward descriptor for layer: " << getName();
if (withBiases) {
descs.emplace_back(createDescriptorInternal(inDnnlDesc, weightDnnlDesc, biasDnnlDesc, outDnnlDesc, alg));
} else {
descs.emplace_back(createDescriptorInternal(inDnnlDesc, weightDnnlDesc, outDnnlDesc, alg));
}
}
}
@ -612,7 +629,7 @@ void MKLDNNConvolutionNode::initDescriptor(const NodeConfig& config) {
// attr[0] - depthwise, quantize
// attr[1] - binary
mkldnn::primitive_attr attrs[1];
setPostOps(attrs[0]);
setPostOps(attrs[0], MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims());
// setPostOps(attrs[1], false, true);
auto rightConfig = selectedPD->getConfig();
@ -761,6 +778,9 @@ bool MKLDNNConvolutionNode::isPossibleToSkipInitConfig(MKLDNNDescriptor &desc) c
std::shared_ptr<MemoryDesc> MKLDNNConvolutionNode::getSrcMemDesc(mkldnn::primitive_desc_iterator &primitive_desc_it, size_t idx) {
auto desc = idx > 0 ? primitive_desc_it.weights_desc(idx - 1) : primitive_desc_it.src_desc(idx);
if (getInputShapeAtPort(idx).isDynamic()) {
return MKLDNNExtensionUtils::makeUndefinedDesc(desc, getInputShapeAtPort(idx));
}
return MKLDNNExtensionUtils::makeDescriptor(desc);
}
@ -804,8 +824,8 @@ bool MKLDNNConvolutionNode::isNspcAvailable() const {
}
// A bunch of heuristics are designed to cut off not optimal nspc convolution applications
auto inpDims = getInputShapeAtPort(0).getStaticDims();
auto outDims = getOutputShapeAtPort(0).getStaticDims();
auto inpDims = getInputShapeAtPort(0).getDims();
auto outDims = getOutputShapeAtPort(0).getDims();
auto ndims = inpDims.size();
if (isDepthWise()) {
@ -821,15 +841,14 @@ bool MKLDNNConvolutionNode::isNspcAvailable() const {
if (!isGrouped) {
auto weightDimsReversItr = weightDims.crbegin();
auto inpDimsReversItr = inpDims.crbegin();
auto outDimsReversItr = outDims.crbegin();
auto strideReversItr = stride.crbegin();
auto paddingLreversItr = paddingL.crbegin();
auto paddingRreversItr = paddingR.crbegin();
for (size_t i = 0; i < spatialRank; ++i) {
is1x1 = true
&& *(weightDimsReversItr++) == 1
&& *(inpDimsReversItr++) == *(outDimsReversItr++)
&& *(strideReversItr++) == 1
&& *(paddingLreversItr++) == 0
&& *(paddingRreversItr++) == 0;
}
@ -839,7 +858,7 @@ bool MKLDNNConvolutionNode::isNspcAvailable() const {
if (mayiuse(impl::cpu::x64::avx512_common) && is1x1) {
auto end = inpDims.rbegin();
std::advance(end, spatialRank);
if (std::all_of(inpDims.rbegin(), end, [](size_t x) { return 1 == x; })) {
if (std::all_of(inpDims.rbegin(), end, [](size_t x) { return dimsEqualStrong(1, x); })) {
return false;
}
}
@ -895,4 +914,108 @@ InferenceEngine::Blob::Ptr MKLDNNConvolutionNode::createInternalBlob(InferenceEn
return internalBlob;
}
void MKLDNNConvolutionNode::prepareParams() {
const NodeDesc *selected_pd = getSelectedPrimitiveDescriptor();
if (selected_pd == nullptr)
IE_THROW() << "Preferable primitive descriptor is not set for node " << getName() << ".";
auto inMemoryDesc = getParentEdgesAtPort(0).front()->getMemory().GetDescWithType<DnnlMemoryDesc>();
auto weightMemoryDesc = getParentEdgesAtPort(1).front()->getMemory().GetDescWithType<DnnlMemoryDesc>();
auto outMemoryDesc = getChildEdgesAtPort(0).front()->getMemory().GetDescWithType<DnnlMemoryDesc>();
auto initPrimitiveAttr = [&]() {
mkldnn::primitive_attr attr;
addZeroPoints(attr);
// todo: [AV] delete "false" to use binary mechanism
if (false && getSelectedPrimitiveDescriptor()->getImplementationType() == jit_gemm) {
setPostOps(attr, outMemoryDesc->getShape().getStaticDims(), true, true);
} else {
setPostOps(attr, outMemoryDesc->getShape().getStaticDims(), true);
}
return std::make_shared<mkldnn::primitive_attr>(std::move(attr));
};
AttrPtr pAttrLocal;
if (isDynamicNode()) {
if (!pAttr) {
pAttr = initPrimitiveAttr();
}
pAttrLocal = pAttr;
} else {
pAttrLocal = initPrimitiveAttr();
}
std::shared_ptr<mkldnn::convolution_forward::desc> dnnlConvDesc;
auto alg = isWinograd() ? mkldnn::algorithm::convolution_winograd : mkldnn::algorithm::convolution_direct;
if (withBiases) {
auto biasMemoryDesc = getParentEdgesAtPort(2).front()->getMemory().GetDescWithType<DnnlMemoryDesc>();
// WA to align IR bias representation (3 to 5 rank tensors) to oneDNN representation (1 rank tensor)
mkldnn::memory::desc dnnlBiasDesc = biasMemoryDesc->getDnnlDesc().reshape(MKLDNNExtensionUtils::convertToDnnlDims(biasesDims));
dnnlConvDesc = createDescriptorInternal(inMemoryDesc->getDnnlDesc(),
weightMemoryDesc->getDnnlDesc(),
dnnlBiasDesc,
outMemoryDesc->getDnnlDesc(),
alg);
} else {
dnnlConvDesc = createDescriptorInternal(inMemoryDesc->getDnnlDesc(),
weightMemoryDesc->getDnnlDesc(),
outMemoryDesc->getDnnlDesc(),
alg);
}
MKLDNNDescriptor desc(dnnlConvDesc);
auto itpd = desc.createPrimitiveDescriptorIterator(getEngine(), *pAttrLocal);
convolution_forward::primitive_desc prim_desc;
while (static_cast<bool>(itpd)) {
impl_desc_type impl_type = parse_impl_name(itpd.impl_info_str());
if (impl_type == selected_pd->getImplementationType()) {
prim_desc = convolution_forward::primitive_desc(itpd.get());
break;
}
if (!itpd.next_impl())
IE_THROW() << "Primitive descriptor was not found for node " << getName() << ".";
}
prim.reset(new convolution_forward(prim_desc));
primArgs[DNNL_ARG_SRC] = getParentEdgesAtPort(0)[0]->getMemoryPtr()->GetPrimitive();
primArgs[DNNL_ARG_WEIGHTS] = getWeights();
primArgs[DNNL_ARG_DST] = getChildEdgesAtPort(0)[0]->getMemoryPtr()->GetPrimitive();
if (withBiases) {
primArgs[DNNL_ARG_BIAS] = getBias();
}
// todo: [AV] uncomment to use binary mechanism
// auto post_ops = attr.get_post_ops();
// int idx = 0;
// for (int i = 0; i < post_ops.len(); i++) {
// if (post_ops.kind(i) == mkldnn::primitive::kind::binary) {
// primArgs.insert({DNNL_ARG_ATTR_MULTIPLE_POST_OP(i) | DNNL_ARG_SRC_1, binaryPostOpsArgs[idx++]});
// }
// }
}
void MKLDNNConvolutionNode::executeDynamicImpl(dnnl::stream strm) {
execute(strm);
}
void MKLDNNConvolutionNode::updatePadding() {
//update padding. TODO [DS] : rewrite when the final shape inference interface is available
if (isDynamicNode() && autoPadding) {
if (auto convolutionOp = ov::as_type_ptr<ov::op::v1::Convolution>(opToShapeInfer)) {
paddingL = convolutionOp->get_pads_begin();
paddingR = convolutionOp->get_pads_end();
} else if (auto groupConvolutionOp = ov::as_type_ptr<ov::op::v1::GroupConvolution>(opToShapeInfer)) {
paddingL = groupConvolutionOp->get_pads_begin();
paddingR = groupConvolutionOp->get_pads_end();
}
}
}
REG_MKLDNN_PRIM_FOR(MKLDNNConvolutionNode, Convolution);

View File

@ -65,12 +65,27 @@ protected:
InferenceEngine::Precision fusedEltwisePrecision(const MKLDNNNodePtr& fusingNode) const;
private:
void prepareParams() override;
void executeDynamicImpl(mkldnn::stream strm) override;
void addZeroPoints(mkldnn::primitive_attr& attr) const;
void setPostOps(mkldnn::primitive_attr &attr, bool initWeights, bool initAsBinary);
void setPostOps(mkldnn::primitive_attr &attr, const VectorDims &dims, bool initWeights, bool initAsBinary);
void filterSupportedDescriptors();
bool isPossibleToSkipInitConfig(MKLDNNDescriptor &desc) const;
bool isNspcAvailable() const;
InferenceEngine::Blob::Ptr createInternalBlob(InferenceEngine::SizeVector dims, size_t edgeNum, bool isGrouped = false);
std::shared_ptr<mkldnn::convolution_forward::desc>
createDescriptorInternal(const mkldnn::memory::desc& inputDesc,
const mkldnn::memory::desc& weightDesc,
const mkldnn::memory::desc& outputDesc,
mkldnn::algorithm alg);
std::shared_ptr<mkldnn::convolution_forward::desc>
createDescriptorInternal(const mkldnn::memory::desc& inputDesc,
const mkldnn::memory::desc& weightDesc,
const mkldnn::memory::desc& biasDesc,
const mkldnn::memory::desc& outputDesc,
mkldnn::algorithm alg);
void updatePadding();
bool withBiases;
bool withSum;
@ -102,6 +117,8 @@ private:
const size_t Y_AXIS = 1;
bool isWino = false;
AttrPtr pAttr;
bool autoPadding = false;
};
} // namespace MKLDNNPlugin

View File

@ -45,13 +45,13 @@ std::vector<std::string> disabledTestPatterns() {
R"(.*ClampLayerTest.*netPrc=(I64|I32).*)",
R"(.*ClampLayerTest.*netPrc=U64.*)",
// TODO: 53618. BF16 gemm ncsp convolution crash
R"(.*_GroupConv.*_inPRC=BF16.*_inFmts=nc.*_primitive=jit_gemm.*)",
R"(.*_GroupConv.*_inFmts=nc.*_primitive=jit_gemm.*ENFORCE_BF16=YES.*)",
// TODO: 53578. fork DW bf16 convolution does not support 3d cases yet
R"(.*_DW_GroupConv.*_inPRC=BF16.*_inFmts=(ndhwc|nCdhw16c).*)",
R"(.*_DW_GroupConv.*_inFmts=(ndhwc|nCdhw16c).*ENFORCE_BF16=YES.*)",
// TODO: 56143. Enable nspc convolutions for bf16 precision
R"(.*ConvolutionLayerCPUTest.*BF16.*_inFmts=(ndhwc|nhwc).*)",
R"(.*ConvolutionLayerCPUTest.*_inFmts=(ndhwc|nhwc).*ENFORCE_BF16=YES.*)",
// TODO: 56827. Sporadic test failures
R"(.*smoke_Conv.+_FP32.ConvolutionLayerCPUTest\.CompareWithRefs.IS=\(1\.67.+\).*inFmts=n.+c.*_primitive=jit_avx2.*)",
R"(.*smoke_Conv.+_FP32.ConvolutionLayerCPUTest\.CompareWithRefs.*TS=\(\(.\.67.+\).*inFmts=n.+c.*_primitive=jit_avx2.*)",
// incorrect jit_uni_planar_convolution with dilation = {1, 2, 1} and output channel 1
R"(.*smoke_Convolution3D.*D=\(1.2.1\)_O=1.*)",
@ -151,6 +151,9 @@ std::vector<std::string> disabledTestPatterns() {
*IS=_TS=\(\(4\.5\.6\.7\)\)_RS=\(\(1\.1\.6\.1\)\)_\(\(1\.5\.6\.1\)\)_\(\(1\.1\.1\.1\)\)_\(\(1\.1\.6\.1\)\).*)",
// Issue: 71121
R"(.*smoke_Proposal*.*TS=\(2.*)",
// TODO : CVS-69533
R"(.*ConvolutionLayerCPUTest.*IS=\{.+\}.*_Fused=.*Add\(Parameters\).*)",
R"(.*GroupConvolutionLayerCPUTest.*IS=\{.+\}.*_Fused=.*Add\(Parameters\).*)",
};
#define FIX_62820 0

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "shared_test_classes/base/ov_subgraph.hpp"
#include <shared_test_classes/single_layer/group_convolution.hpp>
#include "test_utils/cpu_test_utils.hpp"
#include "test_utils/convolution_params.hpp"
@ -9,41 +10,88 @@
using namespace InferenceEngine;
using namespace CPUTestUtils;
using namespace ov::test;
namespace CPULayerTestsDefinitions {
using groupConvLayerTestParamsSet = LayerTestsDefinitions::groupConvLayerTestParamsSet;
using groupConvSpecificParams = LayerTestsDefinitions::groupConvSpecificParams;
using Config = std::map<std::string, std::string>;
typedef std::tuple<
groupConvSpecificParams,
ElementType,
ElementType, // Input precision
ElementType, // Output precision
InputShape, // Input shapes
LayerTestsUtils::TargetDevice> groupConvLayerTestParamsSet;
typedef std::tuple<
groupConvLayerTestParamsSet,
CPUSpecificParams,
fusingSpecificParams> groupConvLayerCPUTestParamsSet;
fusingSpecificParams,
Config > groupConvLayerCPUTestParamsSet;
class GroupConvolutionLayerCPUTest : public testing::WithParamInterface<groupConvLayerCPUTestParamsSet>,
virtual public LayerTestsUtils::LayerTestsCommon, public CpuTestWithFusing {
virtual public SubgraphBaseTest, public CpuTestWithFusing {
public:
static std::string getTestCaseName(testing::TestParamInfo<groupConvLayerCPUTestParamsSet> obj) {
groupConvLayerTestParamsSet basicParamsSet;
CPUSpecificParams cpuParams;
fusingSpecificParams fusingParams;
std::tie(basicParamsSet, cpuParams, fusingParams) = obj.param;
Config additionalConfig;
std::tie(basicParamsSet, cpuParams, fusingParams, additionalConfig) = obj.param;
groupConvSpecificParams groupConvParams;
ElementType netType;
ElementType inType, outType;
InputShape inputShape;
std::string targetDevice;
std::tie(groupConvParams, netType, inType, outType, inputShape, targetDevice) = basicParamsSet;
ngraph::op::PadType padType;
InferenceEngine::SizeVector kernel, stride, dilation;
std::vector<ptrdiff_t> padBegin, padEnd;
size_t convOutChannels, numGroups;
std::tie(kernel, stride, padBegin, padEnd, dilation, convOutChannels, numGroups, padType) = groupConvParams;
std::ostringstream result;
result << LayerTestsDefinitions::GroupConvolutionLayerTest::getTestCaseName(testing::TestParamInfo<groupConvLayerTestParamsSet>(
basicParamsSet, 0));
result << "IS=";
result << CommonTestUtils::partialShape2str({inputShape.first}) << "_";
result << "TS=(";
for (const auto& shape : inputShape.second) {
result << CommonTestUtils::vec2str(shape) << "_";
}
result << ")_";
result << "K" << CommonTestUtils::vec2str(kernel) << "_";
result << "S" << CommonTestUtils::vec2str(stride) << "_";
result << "PB" << CommonTestUtils::vec2str(padBegin) << "_";
result << "PE" << CommonTestUtils::vec2str(padEnd) << "_";
result << "D=" << CommonTestUtils::vec2str(dilation) << "_";
result << "O=" << convOutChannels << "_";
result << "G=" << numGroups << "_";
result << "AP=" << padType << "_";
result << "netPRC=" << netType << "_";
result << "inPRC=" << inType << "_";
result << "outPRC=" << outType << "_";
result << "trgDev=" << targetDevice;
result << CPUTestsBase::getTestCaseName(cpuParams);
result << CpuTestWithFusing::getTestCaseName(fusingParams);
if (!additionalConfig.empty()) {
result << "_PluginConf";
for (auto& item : additionalConfig) {
result << "_" << item.first << "=" << item.second;
}
}
return result.str();
}
protected:
bool isBias = false;
void checkBiasFusing(InferenceEngine::ExecutableNetwork &execNet) const {
auto execGraph = execNet.GetExecGraphInfo().getFunction();
void checkBiasFusing(ov::runtime::ExecutableNetwork &execNet) const {
auto execGraph = execNet.get_runtime_function();
ASSERT_NE(nullptr, execGraph);
bool foundConv = false;
@ -67,11 +115,29 @@ protected:
ASSERT_TRUE(foundConv) << "Can't find Convolution node";
}
std::shared_ptr<ngraph::Node> modifyGraph(const ngraph::element::Type &ngPrc,
ngraph::ParameterVector &params,
const std::shared_ptr<ngraph::Node> &lastNode) override {
auto retNode = CpuTestWithFusing::modifyGraph(ngPrc, params, lastNode);
for (size_t i = targetStaticShapes.front().size(); i < params.size(); ++i) {
const auto& shape = params[i]->get_output_partial_shape(0);
if (shape.is_static()) {
targetStaticShapes.front().push_back(shape.get_shape());
}
}
return retNode;
}
void SetUp() override {
rel_threshold = 1e-4f;
groupConvLayerTestParamsSet basicParamsSet;
CPUSpecificParams cpuParams;
fusingSpecificParams fusingParams;
std::tie(basicParamsSet, cpuParams, fusingParams) = this->GetParam();
Config additionalConfig;
std::tie(basicParamsSet, cpuParams, fusingParams, additionalConfig) = this->GetParam();
configuration.insert(additionalConfig.begin(), additionalConfig.end());
std::tie(inFmts, outFmts, priority, selectedType) = cpuParams;
std::tie(postOpMgrPtr, fusedOps) = fusingParams;
@ -80,9 +146,19 @@ protected:
isBias = postOpMgrPtr->getFusedOpsNames() == "Add(PerChannel)";
groupConvSpecificParams groupConvParams;
std::vector<size_t> inputShape;
auto netPrecision = InferenceEngine::Precision::UNSPECIFIED;
std::tie(groupConvParams, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, targetDevice) = basicParamsSet;
InputShape inputShape;
auto netType = ElementType::undefined;
std::tie(groupConvParams, netType, inType, outType, inputShape, targetDevice) = basicParamsSet;
init_input_shapes({inputShape});
if (configuration.count(PluginConfigParams::KEY_ENFORCE_BF16) &&
PluginConfigParams::YES == configuration[PluginConfigParams::KEY_ENFORCE_BF16]) {
selectedType += "_BF16";
rel_threshold = 1e-2f;
} else {
selectedType = makeSelectedTypeStr(selectedType, netType);
}
ngraph::op::PadType padType;
InferenceEngine::SizeVector kernel, stride, dilation;
@ -90,27 +166,20 @@ protected:
size_t convOutChannels, numGroups;
std::tie(kernel, stride, padBegin, padEnd, dilation, convOutChannels, numGroups, padType) = groupConvParams;
if (inPrc == Precision::UNSPECIFIED) {
selectedType += std::string("_") + Precision(Precision::FP32).name();
} else {
selectedType += std::string("_") + inPrc.name();
}
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
auto params = ngraph::builder::makeParams(ngPrc, {inputShape});
auto params = ngraph::builder::makeDynamicParams(netType, inputDynamicShapes);
auto paramOuts = ngraph::helpers::convert2OutputVector(
ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(params));
auto groupConv = std::dynamic_pointer_cast<ngraph::opset1::GroupConvolution>(
ngraph::builder::makeGroupConvolution(paramOuts[0], ngPrc, kernel, stride, padBegin,
ngraph::builder::makeGroupConvolution(paramOuts[0], netType, kernel, stride, padBegin,
padEnd, dilation, padType, convOutChannels, numGroups));
function = makeNgraphFunction(ngPrc, params, groupConv, "groupConvolution");
function = makeNgraphFunction(netType, params, groupConv, "groupConvolution");
}
};
TEST_P(GroupConvolutionLayerCPUTest, CompareWithRefs) {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
Run();
run();
if (isBias) {
checkBiasFusing(executableNetwork);
}
@ -218,34 +287,44 @@ const std::vector<CPUSpecificParams> CPUParams_Gemm_2D = {
conv_gemm_2D_nspc
};
std::vector<InputShape> inShapesGemm2D = {
{{}, {{ 2, 12, 7, 7 }}},
{
//dynamic shape
{{1, 200}, 12, -1, {1, 200}},
{ //target static shapes
{ 2, 12, 7, 7 },
{ 1, 12, 5, 5 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_2D_Gemm_FP32, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_Gemm_2D,
::testing::Values(Precision::FP32),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 12, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inShapesGemm2D),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_Gemm_2D)),
::testing::ValuesIn(fusingParamsSet)),
::testing::ValuesIn(fusingParamsSet),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_2D_Gemm_BF16, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_Gemm_2D,
::testing::Values(Precision::FP32),
::testing::Values(Precision::BF16),
::testing::Values(Precision::BF16),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 12, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inShapesGemm2D),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_Gemm_2D)),
::testing::ValuesIn(fusingParamsSetBF16)),
::testing::ValuesIn(fusingParamsSetBF16),
::testing::Values(cpuBF16PluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ============= GroupConvolution (Gemm 3D) ============= */
@ -265,34 +344,44 @@ const std::vector<CPUSpecificParams> CPUParams_Gemm_3D = {
conv_gemm_3D_nspc
};
std::vector<InputShape> inShapesGemm3D = {
{{}, {{ 2, 12, 7, 7, 7 }}},
{
//dynamic shape
{{1, 200}, 12, -1, {1, 200}, -1},
{ //target static shapes
{ 2, 12, 7, 7, 7 },
{ 1, 12, 5, 5, 5 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_3D_Gemm_FP32, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_Gemm_3D,
::testing::Values(Precision::FP32),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 12, 7, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inShapesGemm3D),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_Gemm_3D)),
::testing::ValuesIn(fusingParamsSet)),
::testing::ValuesIn(fusingParamsSet),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_3D_Gemm_BF16, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_Gemm_3D,
::testing::Values(Precision::FP32),
::testing::Values(Precision::BF16),
::testing::Values(Precision::BF16),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 12, 7, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inShapesGemm3D),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_Gemm_3D)),
::testing::ValuesIn(fusingParamsSetBF16)),
::testing::ValuesIn(fusingParamsSetBF16),
::testing::Values(cpuBF16PluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ============= GroupConvolution (2D) ============= */
@ -316,34 +405,44 @@ const std::vector<CPUSpecificParams> CPUParams_2D = {
conv_avx512_2D_nspc
};
std::vector<InputShape> inputShapes2d = {
{{}, {{ 1, 64, 7, 7 }}},
{
//dynamic shapes
{-1, 64, -1, {1, 200}},
{ //target static shapes
{ 2, 64, 7, 7 },
{ 1, 64, 9, 9 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_2D_FP32, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_2D,
::testing::Values(Precision::FP32),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 64, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes2d),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_2D)),
::testing::ValuesIn(fusingParamsSet)),
::testing::ValuesIn(fusingParamsSet),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_2D_BF16, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_2D,
::testing::Values(Precision::FP32),
::testing::Values(Precision::BF16),
::testing::Values(Precision::BF16),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 64, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes2d),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice({conv_avx512_2D, conv_avx512_2D_nspc})),
::testing::ValuesIn(fusingParamsSetBF16)),
::testing::ValuesIn(fusingParamsSetBF16),
::testing::Values(cpuBF16PluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ============= GroupConvolution (3D) ============= */
@ -366,34 +465,44 @@ const std::vector<CPUSpecificParams> CPUParams_3D = {
conv_avx512_3D_nspc
};
std::vector<InputShape> inputShapes3d = {
{{}, {{ 1, 64, 7, 7, 7 }}},
{
//dynamic shapes
{-1, 64, -1, {1, 200}, -1},
{ //target static shapes
{ 2, 64, 7, 7, 7 },
{ 1, 64, 9, 9, 9 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_3D_FP32, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_3D,
::testing::Values(Precision::FP32),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 64, 7, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes3d),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_3D)),
::testing::ValuesIn(fusingParamsSet)),
::testing::ValuesIn(fusingParamsSet),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_3D_BF16, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_3D,
::testing::Values(Precision::FP32),
::testing::Values(Precision::BF16),
::testing::Values(Precision::BF16),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 64, 7, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes3d),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice({conv_avx512_3D, conv_avx512_3D_nspc})),
::testing::ValuesIn(fusingParamsSetBF16)),
::testing::ValuesIn(fusingParamsSetBF16),
::testing::Values(cpuBF16PluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ============= GroupConvolution (DW 2D) ============= */
@ -417,19 +526,30 @@ const std::vector<CPUSpecificParams> CPUParams_DW_2D = {
conv_avx512_dw_2D_nspc
};
std::vector<InputShape> inputShapes2dDW = {
{{}, {{ 2, 32, 7, 7 }}},
{
//dynamic shapes
{-1, 32, -1, {1, 200}},
{ //target static shapes
{ 2, 32, 7, 7 },
{ 1, 32, 9, 9 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_2D_DW_FP32, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_DW_2D,
::testing::Values(Precision::FP32),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 32, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes2dDW),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_DW_2D)),
::testing::ValuesIn(fusingParamsSet)),
::testing::ValuesIn(fusingParamsSet),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
@ -437,15 +557,14 @@ INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_2D_DW_BF16, GroupConvolutionLayerCPUTes
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_DW_2D,
::testing::Values(Precision::FP32),
::testing::Values(Precision::BF16),
::testing::Values(Precision::BF16),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 32, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes2dDW),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice({conv_avx512_dw_2D, conv_avx512_dw_2D_nspc})),
::testing::ValuesIn(fusingParamsSetBF16)),
::testing::ValuesIn(fusingParamsSetBF16),
::testing::Values(cpuBF16PluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ============= GroupConvolution (DW 3D) ============= */
@ -469,57 +588,69 @@ const std::vector<CPUSpecificParams> CPUParams_DW_3D = {
conv_avx512_dw_3D_nspc
};
std::vector<InputShape> inputShapes3dDW = {
{{}, {{ 2, 32, 7, 7, 7 }}},
{
//dynamic shapes
{-1, 32, -1, {1, 200}, -1},
{ //target static shapes
{ 2, 32, 7, 7, 7 },
{ 1, 32, 9, 9, 9 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_3D_DW_FP32, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
groupConvParams_ExplicitPadding_DW_3D,
::testing::Values(Precision::FP32),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(InferenceEngine::Layout::ANY),
::testing::Values(std::vector<size_t >({2, 32, 7, 7, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes3dDW),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_DW_3D)),
::testing::ValuesIn(fusingParamsSet)),
::testing::ValuesIn(fusingParamsSet),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ========= */
/* ============= SINGLE TEST CASES ============= */
using VecFusingParams = std::vector<fusingSpecificParams>;
using PrcConnectedParams = std::tuple<Precision, Precision, VecFusingParams>; // inPrc, outPrc, FusingParamsSet
using VecPrcConnectedParams = std::vector<PrcConnectedParams>;
using ConfigRelatedParams = std::tuple<Config, VecFusingParams>; // Plugin config FusingParamsSet
using VecConfigRelatedParams = std::vector<ConfigRelatedParams>;
std::vector<groupConvLayerCPUTestParamsSet> makeSingleGroupConvCPUTestCases(SizeVector kernels, SizeVector strides, SizeVector dilations,
std::vector<ptrdiff_t> padBegins, std::vector<ptrdiff_t> padEnds,
ngraph::op::PadType padType, int groups, int mb, SizeVector spDims,
int inGroupSize, int outGroupSize,
const std::vector<CPUSpecificParams>& CPUParams,
const VecPrcConnectedParams& vecPrcConnectedParams) {
const VecConfigRelatedParams& vecConfigRelatedParams) {
int inChannels = groups * inGroupSize;
int outChannels = groups * outGroupSize;
SizeVector inputShapes;
inputShapes.push_back(mb);
inputShapes.push_back(inChannels);
inputShapes.insert(inputShapes.end(), spDims.begin(), spDims.end());
InputShape inputShapes;
SizeVector targetShape;
targetShape.push_back(mb);
targetShape.push_back(inChannels);
targetShape.insert(targetShape.end(), spDims.begin(), spDims.end());
inputShapes.second.push_back({targetShape});
groupConvSpecificParams specificParams(kernels, strides, padBegins, padEnds, dilations, outChannels, groups, padType);
std::vector<groupConvLayerCPUTestParamsSet> retVector;
for (auto& prcConnectedParams : vecPrcConnectedParams) {
Precision inPrc, outPrc;
for (auto& configRelatedParams : vecConfigRelatedParams) {
VecFusingParams fusingParams;
std::tie(inPrc, outPrc, fusingParams) = prcConnectedParams;
Config config;
std::tie(config, fusingParams) = configRelatedParams;
groupConvLayerTestParamsSet basicParamsSet(specificParams, Precision::FP32, inPrc, outPrc,
InferenceEngine::Layout::ANY, InferenceEngine::Layout::ANY,
groupConvLayerTestParamsSet basicParamsSet(specificParams, ElementType::f32, ElementType::undefined, ElementType::undefined,
inputShapes, CommonTestUtils::DEVICE_CPU);
for (auto &item : CPUParams) {
for (auto &fusingParam : fusingParams) {
retVector.push_back(groupConvLayerCPUTestParamsSet(basicParamsSet, item, fusingParam));
retVector.push_back(groupConvLayerCPUTestParamsSet(basicParamsSet, item, fusingParam, config));
}
}
}
@ -546,15 +677,13 @@ std::vector<groupConvLayerCPUTestParamsSet> generateSingleGroupConvCPUTestCases(
/* COMMON PARAMS */
const VecPrcConnectedParams vecPrcConnectParamsFP32 = {PrcConnectedParams{Precision::FP32, Precision::FP32, fusingParamsSet}};
const VecPrcConnectedParams vecPrcConnectParams = {PrcConnectedParams{Precision::FP32, Precision::FP32, fusingParamsSet},
PrcConnectedParams{Precision::BF16, Precision::BF16, fusingParamsSetBF16},
PrcConnectedParams{Precision::BF16, Precision::FP32, fusingParamsSetBF16}};
const VecConfigRelatedParams vecPrcConnectParamsFP32 = {ConfigRelatedParams{cpuEmptyPluginConfig, fusingParamsSet}};
const VecConfigRelatedParams vecPrcConnectParams = {ConfigRelatedParams{cpuEmptyPluginConfig, fusingParamsSet},
ConfigRelatedParams{cpuBF16PluginConfig, fusingParamsSetBF16}};
const VecPrcConnectedParams vecPrcConnectParamsFP32Default = {PrcConnectedParams{Precision::FP32, Precision::FP32, VecFusingParams{emptyFusingSpec}}};
const VecPrcConnectedParams vecPrcConnectParamsDefault = {PrcConnectedParams{Precision::FP32, Precision::FP32, VecFusingParams{emptyFusingSpec}},
PrcConnectedParams{Precision::BF16, Precision::BF16, VecFusingParams{emptyFusingSpec}},
PrcConnectedParams{Precision::BF16, Precision::FP32, VecFusingParams{emptyFusingSpec}}};
const VecConfigRelatedParams vecPrcConnectParamsFP32Default = {ConfigRelatedParams{cpuEmptyPluginConfig, VecFusingParams{emptyFusingSpec}}};
const VecConfigRelatedParams vecPrcConnectParamsDefault = {ConfigRelatedParams{cpuEmptyPluginConfig, VecFusingParams{emptyFusingSpec}},
ConfigRelatedParams{cpuBF16PluginConfig, VecFusingParams{emptyFusingSpec}}};
/* ============= GEMM GroupConvolution ============= */
const std::vector<groupConvLayerCPUTestParamsSet> gemmGroupConvTestCases = generateSingleGroupConvCPUTestCases(
@ -718,7 +847,8 @@ const std::vector<groupConvLayerCPUTestParamsSet> JIT_AVX512_GroupConvTestCases
2, 1, {10, 10, 10}, 16, 16, avx512_GroupConv_3D, vecPrcConnectParams)
);
INSTANTIATE_TEST_SUITE_P(smoke_JIT_AVX512_GroupConv, GroupConvolutionLayerCPUTest, ::testing::ValuesIn(filterParamsSetForDevice(JIT_AVX512_GroupConvTestCases)),
INSTANTIATE_TEST_SUITE_P(smoke_JIT_AVX512_GroupConv, GroupConvolutionLayerCPUTest,
::testing::ValuesIn(filterParamsSetForDevice(JIT_AVX512_GroupConvTestCases)),
GroupConvolutionLayerCPUTest::getTestCaseName);
/* ============= JIT SSE42 DW GroupConvolution ============= */
@ -860,19 +990,30 @@ const std::vector<CPUSpecificParams> CPUParams_1D = {
conv_avx512_1D
};
std::vector<InputShape> inputShapes1d = {
{{}, {{ 2, 64, 7 }}},
{
//dynamic shapes
{ {-1, 64, -1} },
{ //target static shapes
{ 2, 64, 7 },
{ 1, 64, 14 }
}
}
};
INSTANTIATE_TEST_SUITE_P(smoke_GroupConv_1D, GroupConvolutionLayerCPUTest,
::testing::Combine(
::testing::Combine(
convParams_1D,
::testing::Values(Precision::FP32),
::testing::Values(Precision::FP32),
::testing::Values(Precision::UNSPECIFIED),
::testing::Values(Layout::ANY),
::testing::Values(Layout::ANY),
::testing::Values(std::vector<size_t >({ 2, 64, 7})),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::f32),
::testing::Values(ElementType::undefined),
::testing::ValuesIn(inputShapes1d),
::testing::Values(CommonTestUtils::DEVICE_CPU)),
::testing::ValuesIn(filterCPUInfoForDevice(CPUParams_1D)),
::testing::Values(fusingAddPerChannel)),
::testing::Values(fusingAddPerChannel),
::testing::Values(cpuEmptyPluginConfig)),
GroupConvolutionLayerCPUTest::getTestCaseName);
} // namespace

View File

@ -151,8 +151,13 @@ void CPUTestsBase::CheckPluginRelatedResultsImpl(std::shared_ptr<const ov::Funct
return value->get();
};
// skip policy
auto should_be_skipped = [] (const ngraph::Shape &shape, cpu_memory_format_t fmt) {
bool skip_unsquized_1D = std::count(shape.begin(), shape.end(), 1) == shape.size() - 1;
auto should_be_skipped = [] (const ngraph::PartialShape &partialShape, cpu_memory_format_t fmt) {
if (partialShape.is_dynamic()) {
return false;
}
auto shape = partialShape.get_shape();
bool skip_unsquized_1D = std::count(shape.begin(), shape.end(), 1) == shape.size() - 1;
bool permule_of_1 = (fmt == cpu_memory_format_t::nhwc || fmt == cpu_memory_format_t::ndhwc || fmt == cpu_memory_format_t::nwc) && shape[1] == 1;
return skip_unsquized_1D || permule_of_1;
};
@ -165,7 +170,7 @@ void CPUTestsBase::CheckPluginRelatedResultsImpl(std::shared_ptr<const ov::Funct
const auto port = node->inputs()[i];
if ((parentPort.get_tensor_ptr() == port.get_tensor_ptr())) {
auto parentNode = parentPort.get_node_shared_ptr();
auto shape = parentNode->get_output_tensor(0).get_shape();
auto shape = parentNode->get_output_tensor(0).get_partial_shape();
auto actualInputMemoryFormat = getExecValueOutputsLayout(parentNode);
if (!should_be_skipped(shape, inFmts[i])) {
@ -204,7 +209,7 @@ void CPUTestsBase::CheckPluginRelatedResultsImpl(std::shared_ptr<const ov::Funct
for (size_t i = 0; i < fmtsNum; i++) {
const auto actualOutputMemoryFormat = getExecValue(ExecGraphInfoSerialization::OUTPUT_LAYOUTS);
const auto shape = node->get_output_shape(i);
const auto shape = node->get_output_partial_shape(i);
if (should_be_skipped(shape, outFmts[i]))
continue;
@ -278,7 +283,7 @@ CPUTestsBase::makeCPUInfo(std::vector<cpu_memory_format_t> inFmts, std::vector<c
std::shared_ptr<ngraph::Function>
CPUTestsBase::makeNgraphFunction(const ngraph::element::Type &ngPrc, ngraph::ParameterVector &params,
const std::shared_ptr<ngraph::Node> &lastNode, std::string name) const {
const std::shared_ptr<ngraph::Node> &lastNode, std::string name) {
auto newLastNode = modifyGraph(ngPrc, params, lastNode);
ngraph::ResultVector results;
@ -289,7 +294,7 @@ CPUTestsBase::makeNgraphFunction(const ngraph::element::Type &ngPrc, ngraph::Par
}
std::shared_ptr<ngraph::Node>
CPUTestsBase::modifyGraph(const ngraph::element::Type &ngPrc, ngraph::ParameterVector &params, const std::shared_ptr<ngraph::Node> &lastNode) const {
CPUTestsBase::modifyGraph(const ngraph::element::Type &ngPrc, ngraph::ParameterVector &params, const std::shared_ptr<ngraph::Node> &lastNode) {
lastNode->get_rt_info() = getCPUInfo();
return lastNode;
}

View File

@ -127,13 +127,14 @@ public:
static CPUInfo makeCPUInfo(std::vector<cpu_memory_format_t> inFmts,
std::vector<cpu_memory_format_t> outFmts,
std::vector<std::string> priority);
//TODO: change to setter method
static std::string makeSelectedTypeStr(std::string implString, ngraph::element::Type_t elType);
CPUInfo getCPUInfo() const;
std::shared_ptr<ngraph::Function> makeNgraphFunction(const ngraph::element::Type &ngPrc,
ngraph::ParameterVector &params,
const std::shared_ptr<ngraph::Node> &lastNode,
std::string name) const;
std::string name);
void CheckPluginRelatedResults(InferenceEngine::ExecutableNetwork &execNet, std::string nodeType) const;
void CheckPluginRelatedResults(ov::runtime::ExecutableNetwork &execNet, std::string nodeType) const;
@ -149,7 +150,7 @@ protected:
*/
virtual std::shared_ptr<ngraph::Node> modifyGraph(const ngraph::element::Type &ngPrc,
ngraph::ParameterVector &params,
const std::shared_ptr<ngraph::Node> &lastNode) const;
const std::shared_ptr<ngraph::Node> &lastNode);
protected:
std::string getPrimitiveType() const;
@ -158,7 +159,12 @@ protected:
std::string selectedType;
};
// common parameters
const auto emptyCPUSpec = CPUSpecificParams{{}, {}, {}, {}};
const std::map<std::string, std::string> cpuEmptyPluginConfig;
const std::map<std::string, std::string> cpuBF16PluginConfig =
{ { InferenceEngine::PluginConfigParams::KEY_ENFORCE_BF16, InferenceEngine::PluginConfigParams::YES } };
// utility functions
std::vector<CPUSpecificParams> filterCPUSpecificParams(std::vector<CPUSpecificParams>& paramsVector);

View File

@ -26,7 +26,7 @@ std::string CpuTestWithFusing::getTestCaseName(fusingSpecificParams params) {
}
std::shared_ptr<ngraph::Node>
CpuTestWithFusing::modifyGraph(const ngraph::element::Type &ngPrc, ngraph::ParameterVector &params, const std::shared_ptr<ngraph::Node> &lastNode) const {
CpuTestWithFusing::modifyGraph(const ngraph::element::Type &ngPrc, ngraph::ParameterVector &params, const std::shared_ptr<ngraph::Node> &lastNode) {
CPUTestsBase::modifyGraph(ngPrc, params, lastNode);
std::shared_ptr<ngraph::Node> retNode = lastNode;
if (postOpMgrPtr) {
@ -101,7 +101,7 @@ std::string postNodesMgr::getFusedOpsNames() const {
const char* separator = "";
for (const auto& item : _postNodes) {
result << separator << item.name;
separator = ",";
separator = ".";
}
return result.str();
}

View File

@ -62,7 +62,7 @@ protected:
*/
std::shared_ptr<ngraph::Node> modifyGraph(const ngraph::element::Type &ngPrc,
ngraph::ParameterVector &params,
const std::shared_ptr<ngraph::Node> &lastNode) const override;
const std::shared_ptr<ngraph::Node> &lastNode) override;
void CheckPluginRelatedResultsImpl(std::shared_ptr<const ov::Function> function, std::string nodeType) const override;
@ -120,11 +120,11 @@ const auto fusingSqrt = fusingSpecificParams{std::make_shared<postNodesMgr>(std:
const auto fusingPReluPerChannel = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
auto data = NGraphFunctions::Utils::generateVector<ngraph::element::Type_t::f32>(ngraph::shape_size(newShape));
return ngraph::builder::makeActivation(inpNode, ngPrc, ngraph::helpers::LeakyRelu, newShape, data);
}, "PRelu(PerChannel)"}}), {"PRelu"}};
@ -166,11 +166,11 @@ const auto fusingReluAdd = fusingSpecificParams{std::make_shared<postNodesMgr>(s
return ngraph::builder::makeActivation(inpNode, ngPrc, ngraph::helpers::Relu);
}, "Relu"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
auto constNode = ngraph::builder::makeConstant(ngPrc, newShape, std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Add>(inpNode, constNode);
}, "Add(PerChannel)"}}), {"Relu", "Add"}};
@ -180,40 +180,40 @@ const auto fusingReluScaleShift = fusingSpecificParams{std::make_shared<postNode
return ngraph::builder::makeActivation(inpNode, ngPrc, ngraph::helpers::Relu);
}, "Relu"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
auto constNode = ngraph::builder::makeConstant(ngPrc, newShape, std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Multiply>(inpNode, constNode);
}, "Multiply(PerChannel)"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
auto constNode = ngraph::builder::makeConstant(ngPrc, newShape, std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Add>(inpNode, constNode);
}, "Add(PerChannel)"}}), {"Relu", "Add"}};
const auto fusingScaleShift = fusingSpecificParams{ std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params) {
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
auto constNode = ngraph::builder::makeConstant(ngPrc, newShape, std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Multiply>(inpNode, constNode);
}, "Multiply(PerChannel)"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params) {
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
auto constNode = ngraph::builder::makeConstant(ngPrc, newShape, std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Add>(inpNode, constNode);
}, "Add(PerChannel)"}}), {"Add"} };
@ -239,11 +239,11 @@ const auto fusingFakeQuantizePerChannel = fusingSpecificParams{std::make_shared<
const auto fusingFakeQuantizePerChannelRelu = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto localPrc = inpNode->get_element_type();
auto shape = inpNode->get_shape();
auto shape = inpNode->get_output_partial_shape(0);
if (shape.size() == 1)
IE_THROW() << "If shape.size() == 1 then Granularity can be PerTensor only";
ngraph::Shape newShape(shape.size(), 1);
newShape[1] = shape[1];
newShape[1] = shape[1].get_length();
return ngraph::builder::makeFakeQuantize(inpNode, localPrc, 256, newShape);
}, "FakeQuantize(PerChannel)"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
@ -253,7 +253,7 @@ const auto fusingFakeQuantizePerChannelRelu = fusingSpecificParams{std::make_sha
const auto fusingFakeQuantizePerTensorRelu = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params) {
auto localPrc = inpNode->get_element_type();
auto newShape = ngraph::Shape(inpNode->get_shape().size(), 1);
auto newShape = ngraph::Shape(inpNode->get_output_partial_shape(0).size(), 1);
return ngraph::builder::makeFakeQuantize(inpNode, localPrc, 256, newShape);
}, "FakeQuantize(PerTensor)"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
@ -262,8 +262,8 @@ const auto fusingFakeQuantizePerTensorRelu = fusingSpecificParams{std::make_shar
const auto fusingSum = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
ngraph::ParameterVector newParams = ngraph::builder::makeParams(ngPrc, {shape});
auto shape = inpNode->get_output_partial_shape(0);
ngraph::ParameterVector newParams = ngraph::builder::makeDynamicParams(ngPrc, {shape});
params.insert(params.end(), newParams.begin(), newParams.end());
auto newParamOuts = ngraph::helpers::convert2OutputVector(
ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(newParams));
@ -272,8 +272,8 @@ const auto fusingSum = fusingSpecificParams{std::make_shared<postNodesMgr>(std::
const auto fusingSumEluFQ = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
ngraph::ParameterVector newParams = ngraph::builder::makeParams(ngPrc, {shape});
auto shape = inpNode->get_output_partial_shape(0);
ngraph::ParameterVector newParams = ngraph::builder::makeDynamicParams(ngPrc, {shape});
params.insert(params.end(), newParams.begin(), newParams.end());
auto newParamOuts = ngraph::helpers::convert2OutputVector(
ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(newParams));
@ -284,7 +284,7 @@ const auto fusingSumEluFQ = fusingSpecificParams{std::make_shared<postNodesMgr>(
}, "Elu"},
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params) {
auto localPrc = inpNode->get_element_type();
auto newShape = ngraph::Shape(inpNode->get_shape().size(), 1);
auto newShape = ngraph::Shape(inpNode->get_output_partial_shape(0).size(), 1);
return ngraph::builder::makeFakeQuantize(inpNode, localPrc, 256, newShape);
}, "FakeQuantize(PerTensor)"}}), {"Add", "Elu", "FakeQuantize"}};
@ -297,8 +297,8 @@ const auto fusingMultiplyPerTensor = fusingSpecificParams{std::make_shared<postN
const auto fusingMultiplyPerChannel = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
ngraph::Shape secondMultInShape(inpNode->get_shape().size(), 1);
secondMultInShape[1] = inpNode->get_shape()[1];
ngraph::Shape secondMultInShape(inpNode->get_output_partial_shape(0).size(), 1);
secondMultInShape[1] = inpNode->get_output_partial_shape(0)[1].get_length();
auto secondMultInput = ngraph::builder::makeConstant(ngPrc, ngraph::Shape(secondMultInShape), std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Multiply>(inpNode, secondMultInput);
}, "Multiply(PerChannel)"}}), {"Multiply"}};
@ -312,8 +312,8 @@ const auto fusingAddPerTensor = fusingSpecificParams{std::make_shared<postNodesM
const auto fusingAddPerChannel = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
ngraph::Shape secondMultInShape(inpNode->get_shape().size(), 1);
secondMultInShape[1] = inpNode->get_shape()[1];
ngraph::Shape secondMultInShape(inpNode->get_output_partial_shape(0).size(), 1);
secondMultInShape[1] = inpNode->get_output_partial_shape(0)[1].get_length();
auto secondMultInput = ngraph::builder::makeConstant(ngPrc, ngraph::Shape(secondMultInShape), std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Add>(inpNode, secondMultInput);
}, "Add(PerChannel)"}}), {"Add"}};
@ -327,8 +327,8 @@ const auto fusingSubtractPerTensor = fusingSpecificParams{std::make_shared<postN
const auto fusingSubtractPerChannel = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
ngraph::Shape secondMultInShape(inpNode->get_shape().size(), 1);
secondMultInShape[1] = inpNode->get_shape()[1];
ngraph::Shape secondMultInShape(inpNode->get_output_partial_shape(0).size(), 1);
secondMultInShape[1] = inpNode->get_output_partial_shape(0)[1].get_length();
auto secondMultInput = ngraph::builder::makeConstant(ngPrc, ngraph::Shape(secondMultInShape), std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Subtract>(inpNode, secondMultInput);
}, "Subtract(PerChannel)"}}), {"Subtract"}};
@ -342,16 +342,16 @@ const auto fusingDividePerTensor = fusingSpecificParams{std::make_shared<postNod
const auto fusingDividePerChannel = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
ngraph::Shape secondMultInShape(inpNode->get_shape().size(), 1);
secondMultInShape[1] = inpNode->get_shape()[1];
ngraph::Shape secondMultInShape(inpNode->get_output_partial_shape(0).size(), 1);
secondMultInShape[1] = inpNode->get_output_partial_shape(0)[1].get_length();
auto secondMultInput = ngraph::builder::makeConstant(ngPrc, ngraph::Shape(secondMultInShape), std::vector<float>{}, true);
return std::make_shared<ngraph::opset1::Divide>(inpNode, secondMultInput);
}, "Divide(PerChannel)"}}), {"Divide"}};
const auto fusingPRelu1D = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](std::shared_ptr<ngraph::Node> inpNode, const ngraph::element::Type& ngPrc, ngraph::ParameterVector& params){
auto shape = inpNode->get_shape();
ngraph::Shape newShape({shape[1]});
auto shape = inpNode->get_output_partial_shape(0);
ngraph::Shape newShape({static_cast<size_t>(shape[1].get_length())});
auto data = NGraphFunctions::Utils::generateVector<ngraph::element::Type_t::f32>(ngraph::shape_size(newShape));
return ngraph::builder::makeActivation(inpNode, ngPrc, ngraph::helpers::LeakyRelu, newShape, data);
}, "PRelu1D"}}), {"PRelu"}};

View File

@ -170,7 +170,7 @@ void SubgraphBaseTest::generate_inputs(const std::vector<ov::Shape>& targetInput
ov::runtime::Tensor tensor;
if (funcInput.get_element_type().is_real()) {
tensor = ov::test::utils::create_and_fill_tensor(
funcInput.get_element_type(), targetInputStaticShapes[i], 10, 0, 1000);
funcInput.get_element_type(), targetInputStaticShapes[i], 2560, 0, 256);
} else {
tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), targetInputStaticShapes[i]);
}

View File

@ -23,8 +23,8 @@ std::shared_ptr<Node> makeConvolution(const ngraph::Output<Node> &in,
const std::vector<float> &filterWeights,
const std::vector<float> &biasesWeights) {
bool randomFilterWeights = filterWeights.empty();
auto shape = in.get_shape();
std::vector<size_t> filterWeightsShape = {numOutChannels, shape[1]};
auto shape = in.get_partial_shape();
std::vector<size_t> filterWeightsShape = {numOutChannels, static_cast<size_t>(shape[1].get_length())};
filterWeightsShape.insert(filterWeightsShape.end(), filterSize.begin(), filterSize.end());
auto filterWeightsNode = makeConstant(type, filterWeightsShape, filterWeights, randomFilterWeights);
auto conv = std::make_shared<opset1::Convolution>(in, filterWeightsNode, strides, padsBegin, padsEnd, dilations,

View File

@ -24,8 +24,8 @@ std::shared_ptr<Node> makeGroupConvolution(const ngraph::Output<Node> &in,
const std::vector<float> &filterWeights,
const std::vector<float> &biasesWeights) {
bool randomFilterWeights = filterWeights.empty();
auto shape = in.get_shape();
std::vector<size_t> filterWeightsShape = {numOutChannels, shape[1]};
auto shape = in.get_partial_shape();
std::vector<size_t> filterWeightsShape = {numOutChannels, static_cast<size_t>(shape[1].get_length())};
if (filterWeightsShape[0] % numGroups || filterWeightsShape[1] % numGroups)
throw std::runtime_error("incorrected shape for GroupConvolution");
filterWeightsShape[0] /= numGroups;

View File

@ -390,8 +390,7 @@ TEST(MakeUndefinedDnnlDesc, checkLayout) {
payloadArgs{ memory::format_tag::nchw, {4, 2, 10, 7 }, "abcd" }, // plain
payloadArgs{ memory::format_tag::NChw16n16c, {4, 2, 10, 7 }, "ABcd16a16b" }, // blocked for 2 dims
payloadArgs{ memory::format_tag::Acdb16a, {96, 1, 7, 7 }, "Acdb16a" }, // same strides but not default order
// TODO [DS]: uncomment when serializeFormat() properly handles the permutation
//payloadArgs{ memory::format_tag::BAcd16a16b, {17, 2, 10, 7 }, "BAcd16a16b" }, // blocked and permuted outer dims
payloadArgs{ memory::format_tag::BAcd16a16b, {17, 2, 10, 7 }, "BAcd16a16b" }, // blocked and permuted outer dims
};
ngraph::PartialShape fullyUndef({{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}});

@ -1 +1 @@
Subproject commit 5a715df74a92b81235c70802eeed741c936f10a0
Subproject commit 93ad2b1bf5aa9c6677b09fbd80967e341b50168c