[CPU] Fix for the convolution node dummy shapes generation (#14521)
This commit is contained in:
parent
7e1b9353d5
commit
ad0ef56665
|
|
@ -157,5 +157,18 @@ Shape MemoryDescUtils::makeDummyShape(const Shape &shape, Dim dummyVal) {
|
|||
return Shape(dummyDims);
|
||||
}
|
||||
|
||||
Shape MemoryDescUtils::makeDummyShape(const Shape &shape, const VectorDims& dummyVals) {
|
||||
if (shape.getRank() != dummyVals.size()) {
|
||||
IE_THROW() << "makeDummyShape(): dummyVals vector size and shape ranks mismatch";
|
||||
}
|
||||
const auto& minDims = shape.getMinDims();
|
||||
const auto& maxDims = shape.getMaxDims();
|
||||
const auto& dims = shape.getDims();
|
||||
VectorDims dummyDims(dims.size());
|
||||
for (size_t i = 0; i < dims.size(); ++i) {
|
||||
dummyDims[i] = dims[i] == Shape::UNDEFINED_DIM ? std::min(maxDims[i], std::max(minDims[i], dummyVals[i])) : dims[i];
|
||||
}
|
||||
return Shape(dummyDims);
|
||||
}
|
||||
} // namespace intel_cpu
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -93,12 +93,20 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Makes a static dummy shape where all undefined values are replaced with the smallest value between the parameter and the upper bound dim
|
||||
* @param shape a shape from which the new static shape is generated
|
||||
* @param shape a Shape object from which the new static shape is generated
|
||||
* @param dummyVal Dim value to replace undefined dimensions
|
||||
* @return a new Shape with dummy values instead of undefined dims
|
||||
*/
|
||||
static Shape makeDummyShape(const Shape& shape, Dim dummyVal = DEFAULT_DUMMY_VAL);
|
||||
|
||||
/**
|
||||
* @brief Makes a static dummy shape where all undefined values are replaced with the smallest value between the parameter and the upper bound dim
|
||||
* @param shape a Shape object from which the new static shape is generated
|
||||
* @param dummyVals vector of values to replace undefined dimensions
|
||||
* @return a new Shape with dummy values instead of undefined dims
|
||||
*/
|
||||
static Shape makeDummyShape(const Shape& shape, const VectorDims& dummyVals);
|
||||
|
||||
/**
|
||||
* @brief Converts dim to string, undefined dim represented as ?
|
||||
* @param dim Dim to be converted
|
||||
|
|
|
|||
|
|
@ -826,8 +826,7 @@ void Convolution::createDescriptor(const std::vector<MemoryDescPtr>& inputDesc,
|
|||
if (inputDesc[0]->isDefined()) {
|
||||
inpDesc = inputDesc[0];
|
||||
} else {
|
||||
auto dummyInDims = MemoryDescUtils::makeDummyShape(inputDesc[0]->getShape()).getStaticDims();
|
||||
dummyInDims[1] = IC;
|
||||
auto dummyInDims = makeInputDummyShape(inputDesc[0]->getShape());
|
||||
inpDesc = inputDesc[0]->cloneWithNewDims(dummyInDims);
|
||||
}
|
||||
DnnlMemoryDescPtr definedInpMemDesc = MemoryDescUtils::convertToDnnlMemoryDesc(inpDesc);
|
||||
|
|
@ -917,7 +916,8 @@ void Convolution::addLegacyZeroPoints(dnnl::primitive_attr& attr) {
|
|||
void Convolution::SetPostOpsAndZeroPoints(std::vector<dnnl::primitive_attr> &attrs) {
|
||||
// attr[0] - Legacy post ops + Legacy zero points.
|
||||
attrs.resize(1);
|
||||
setPostOps(attrs[0], MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims(), true);
|
||||
auto outputShape = outputStaticShape();
|
||||
setPostOps(attrs[0], outputShape, true);
|
||||
addLegacyZeroPoints(attrs[0]);
|
||||
//dw-conv would be fused into conv only on AVX2 platform. no need attr[1]. Avoid extra useless attribute.
|
||||
if (attrs[0].get_post_ops().get()->find(dnnl::impl::primitive_kind::convolution) != -1) {
|
||||
|
|
@ -939,9 +939,9 @@ void Convolution::SetPostOpsAndZeroPoints(std::vector<dnnl::primitive_attr> &att
|
|||
//WR to ONEDNN limitation. attr[1] - legacy post ops + stock zero point.
|
||||
//@todo:Unify to use binary postops+stock zero point when limitation is fixed.
|
||||
//For now, have to adapt to JIT_AMX kernel for performance.
|
||||
setPostOps(attrs[1], MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims(), true);
|
||||
setPostOps(attrs[1], outputShape, true);
|
||||
else
|
||||
setPostOps(attrs[1], MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims(), false);
|
||||
setPostOps(attrs[1], outputShape, false);
|
||||
addZeroPoints(attrs[1]);
|
||||
}
|
||||
|
||||
|
|
@ -1613,7 +1613,7 @@ void Convolution::initTryBrgconvFlag() {
|
|||
// should remove after binary postops performance issue resolved
|
||||
// heuristics: if it's avx512 ISA model && it doesn't have binary post ops or per channel zero point.
|
||||
dnnl::primitive_attr attr;
|
||||
setPostOps(attr, MemoryDescUtils::makeDummyShape(getOutputShapeAtPort(0)).getStaticDims(), false);
|
||||
setPostOps(attr, outputStaticShape(), false);
|
||||
const auto& ops = attr.get_post_ops();
|
||||
if (ops.get()->find(dnnl::impl::primitive_kind::binary) != -1) {
|
||||
shouldTryBrgconv = false;
|
||||
|
|
@ -1641,6 +1641,39 @@ void Convolution::initializeInputZeroPoints(const uint8_t* inputZpData, const si
|
|||
inputZeroPoints.push_back(static_cast<int32_t>(inputZpData[0]));
|
||||
}
|
||||
|
||||
VectorDims Convolution::makeInputDummyShape(const Shape& inpShape) const {
|
||||
// There are a bunch of heuristics mostly aimed to guess the most appropriate oneDNN implementation, to reduce the
|
||||
// amount of the implementation mismatch and the internal reordering as a consequence.
|
||||
constexpr Dim dummyInputDim = 64;
|
||||
|
||||
const size_t spatialRank = stride.size();
|
||||
const size_t filterStartIndx = weightDims.size() - spatialRank;
|
||||
|
||||
VectorDims dummyInputShapeVals(inpShape.getRank(), dummyInputDim);
|
||||
dummyInputShapeVals[1] = IC; //channels
|
||||
|
||||
for (size_t i = 0; i < spatialRank; i++) {
|
||||
if (weightDims[filterStartIndx + i] > dummyInputShapeVals[2 + i]) {
|
||||
constexpr Dim dummyOutputDim = 16;
|
||||
dummyInputShapeVals[2 + i] = (dummyOutputDim - 1) * stride[i] -
|
||||
(paddingL[i] + paddingR[i]) +
|
||||
weightDims[filterStartIndx + i] +
|
||||
(weightDims[filterStartIndx + i]- 1) * (dilation[i]);
|
||||
}
|
||||
}
|
||||
return MemoryDescUtils::makeDummyShape(inpShape, dummyInputShapeVals).getStaticDims();
|
||||
}
|
||||
|
||||
VectorDims Convolution::outputStaticShape() const {
|
||||
auto& outputShape = getOutputShapeAtPort(0);
|
||||
if (outputShape.isDynamic()) {
|
||||
auto inpDummyShape = makeInputDummyShape(getInputShapeAtPort(0));
|
||||
auto outputDims = shapeInferGeneric({ Shape(inpDummyShape), Shape(weightDims) });
|
||||
return Shape(outputDims.front()).getStaticDims();
|
||||
}
|
||||
return outputShape.getStaticDims();
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
} // namespace intel_cpu
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -112,7 +112,8 @@ private:
|
|||
void updatePadding();
|
||||
MemoryDescPtr getSumMemDesc(dnnl::primitive_desc_iterator &primitive_desc_it);
|
||||
MemoryPtr getOutputMemory() const;
|
||||
|
||||
VectorDims makeInputDummyShape(const Shape& inpShape) const;
|
||||
VectorDims outputStaticShape() const;
|
||||
void appendLegacyZeroPointsArgs();
|
||||
void appendZeroPointsArgs();
|
||||
void initTryBrgconvFlag();
|
||||
|
|
|
|||
|
|
@ -214,31 +214,33 @@ TEST_P(ConvolutionLayerCPUTest, CompareWithRefs) {
|
|||
}
|
||||
}
|
||||
|
||||
// Skip tests for brgconv convolution where kernel size = 1x1
|
||||
if (priority[0] == "brgconv_avx512" || priority[0] == "brgconv_avx512_amx") {
|
||||
bool is_1x1 = true;
|
||||
for (const auto &i : kernel) {
|
||||
if (i != 1) {
|
||||
is_1x1 = false;
|
||||
break;
|
||||
}
|
||||
if (!priority.empty()) {
|
||||
// Skip tests for brgconv convolution where kernel size = 1x1
|
||||
if (priority[0] == "brgconv_avx512" || priority[0] == "brgconv_avx512_amx") {
|
||||
bool is_1x1 = true;
|
||||
for (const auto &i : kernel) {
|
||||
if (i != 1) {
|
||||
is_1x1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_1x1) {
|
||||
GTEST_SKIP() << "Disabled test due to the brgconv does not support 1x1 convolution kernel." << std::endl;
|
||||
}
|
||||
}
|
||||
if (is_1x1) {
|
||||
GTEST_SKIP() << "Disabled test due to the brgconv does not support 1x1 convolution kernel." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip tests for brgconv_amx convolution where dilation is not 1
|
||||
if (priority[0].find("amx") != std::string::npos) {
|
||||
bool dilation_is_1x1 = true;
|
||||
for (const auto &i : dilation) {
|
||||
if (i != 1) {
|
||||
dilation_is_1x1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dilation_is_1x1) {
|
||||
GTEST_SKIP() << "Disabled test due to the brgconv amx does not support non 1 dilation convolution kernel." << std::endl;
|
||||
// Skip tests for brgconv_amx convolution where dilation is not 1
|
||||
if (priority[0].find("amx") != std::string::npos) {
|
||||
bool dilation_is_1x1 = true;
|
||||
for (const auto &i : dilation) {
|
||||
if (i != 1) {
|
||||
dilation_is_1x1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dilation_is_1x1) {
|
||||
GTEST_SKIP() << "Disabled test due to the brgconv amx does not support non 1 dilation convolution kernel." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1683,4 +1685,53 @@ INSTANTIATE_TEST_SUITE_P(smoke_Conv_winograd, ConvolutionLayerCPUTest,
|
|||
|
||||
} // namespace winograd
|
||||
|
||||
/* ============= Large Filter Test ============= */
|
||||
namespace {
|
||||
|
||||
const size_t outChannels = 80;
|
||||
|
||||
const SizeVector kernel = { 251 };
|
||||
const SizeVector stride = { 10 };
|
||||
const std::vector<ptrdiff_t> padBegins = { 0 };
|
||||
const std::vector<ptrdiff_t> padEnds = { 0 };
|
||||
const SizeVector dilations = { 1 };
|
||||
|
||||
const auto convParams_1D = ::testing::Combine(
|
||||
::testing::Values(kernel),
|
||||
::testing::Values(stride),
|
||||
::testing::Values(padBegins),
|
||||
::testing::Values(padEnds),
|
||||
::testing::Values(dilations),
|
||||
::testing::Values(outChannels),
|
||||
::testing::Values(ngraph::op::PadType::EXPLICIT)
|
||||
);
|
||||
|
||||
std::vector<InputShape> inShapes = {
|
||||
{{}, {{ 1, 1, 600 }}},
|
||||
{
|
||||
//dynamic shape
|
||||
{ -1, 1, -1 },
|
||||
{ //target static shapes
|
||||
{ 1, 1, 600 },
|
||||
{ 10, 1, 700 },
|
||||
{ 1, 1, 600 }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_Conv_Large_Filter, ConvolutionLayerCPUTest,
|
||||
::testing::Combine(
|
||||
::testing::Combine(
|
||||
convParams_1D,
|
||||
::testing::Values(ElementType::f32),
|
||||
::testing::Values(ElementType::f32),
|
||||
::testing::Values(ElementType::undefined),
|
||||
::testing::ValuesIn(inShapes),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||
::testing::Values(CPUSpecificParams{{}, {}, {}, CPUTestsBase::any_type}),
|
||||
::testing::Values(emptyFusingSpec),
|
||||
::testing::Values(cpuEmptyPluginConfig)),
|
||||
ConvolutionLayerCPUTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
} // namespace CPULayerTestsDefinitions
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ void CPUTestsBase::CheckPluginRelatedResultsImpl(const std::shared_ptr<const ov:
|
|||
}
|
||||
|
||||
bool CPUTestsBase::primTypeCheck(std::string primType) const {
|
||||
return selectedType == CPUTestsBase::any_type || selectedType == primType;
|
||||
return selectedType.find(CPUTestsBase::any_type) != std::string::npos || selectedType == primType;
|
||||
}
|
||||
|
||||
std::string CPUTestsBase::getTestCaseName(CPUSpecificParams params) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue