From c9c9a4d918cd62bb28d9925b6ab1ef7a9c16c202 Mon Sep 17 00:00:00 2001 From: Maxim Andronov Date: Mon, 15 Mar 2021 10:15:35 +0300 Subject: [PATCH] [CPU] Interpolate node migration on nGraph (#17) --- .../mkldnn_plugin/mkldnn_graph_optimizer.cpp | 13 +- .../src/mkldnn_plugin/mkldnn_node.cpp | 41 +- .../src/mkldnn_plugin/mkldnn_node.h | 3 + .../nodes/mkldnn_eltwise_node.cpp | 2 +- .../nodes/mkldnn_interpolate_node.cpp | 669 +++++++++--------- .../nodes/mkldnn_interpolate_node.h | 20 +- .../nodes/mkldnn_normalize_node.cpp | 21 +- .../skip_tests_config.cpp | 2 +- .../cpu/single_layer_tests/interpolate.cpp | 168 ++--- 9 files changed, 467 insertions(+), 472 deletions(-) diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp index b9dc2927e325d7..c3444c5e07d9d2 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_graph_optimizer.cpp @@ -1364,12 +1364,7 @@ void MKLDNNGraphOptimizer::FuseInterpolateAndSimpleOperation(MKLDNNGraph &graph) auto& graphNodes = graph.GetNodes(); auto isSuitableParentNode = [](MKLDNNNodePtr node) { - bool isSuitable = (node->getType() == Interpolate); - if (isSuitable) { - return node->getChildEdges().size() == 1; - } else { - return false; - } + return node->getType() == Interpolate && node->getChildEdges().size() == 1; }; auto isSutableChildNode = [&](MKLDNNNodePtr parentNode, MKLDNNNodePtr childNode) { @@ -1421,11 +1416,7 @@ void MKLDNNGraphOptimizer::FuseNormalizeL2AndSimpleOperation(MKLDNNGraph &graph) auto& graphNodes = graph.GetNodes(); auto isSutableParentNode = [](MKLDNNNodePtr node) { - if (node->getType() == NormalizeL2) { - return node->getChildEdges().size() == 1; - } else { - return false; - } + return node->getType() == NormalizeL2 && node->getChildEdges().size() == 1; }; auto parent = graphNodes.begin(); diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp index 1d6af588a0d6bc..7121a6f4293859 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include "mkldnn_extension_utils.h" @@ -187,7 +188,7 @@ static const InferenceEngine::details::caseless_unordered_map { "ScatterUpdate", ScatterUpdate}, { "ScatterElementsUpdate", ScatterElementsUpdate}, { "ScatterNDUpdate", ScatterNDUpdate}, -// { "Interpolate", Interpolate}, + { "Interpolate", Interpolate}, // { "ReduceAnd", ReduceAnd}, // { "ReduceL1", ReduceL1}, // { "ReduceL2", ReduceL2}, @@ -225,6 +226,16 @@ MKLDNNNode::MKLDNNNode(const std::shared_ptr& op, const mkldnn::en algorithm = Algorithm::Undefined; fusingPort = -1; + const std::string errorPrefix = "Ngraph operation " + std::string(op->get_type_name()) + " with name " + op->get_friendly_name(); + for (size_t i = 0; i < op->get_input_size(); i++) { + if (op->get_input_partial_shape(i).is_dynamic()) + THROW_IE_EXCEPTION << errorPrefix << " has dynamic input shape on " << i << " port, but CPU plug-in supports only static shape"; + } + for (size_t i = 0; i < op->get_output_size(); i++) { + if (op->get_output_partial_shape(i).is_dynamic()) + THROW_IE_EXCEPTION << errorPrefix << " has dynamic output shape on " << i << " port, but CPU plug-in supports only static shape"; + } + for (size_t i = 0; i < op->get_input_size(); i++) { inDims.emplace_back(op->get_input_shape(i)); originalInputPrecisions.emplace_back(details::convertPrecision(op->get_input_element_type(i))); @@ -1327,3 +1338,31 @@ MKLDNNNode* MKLDNNNode::NodesFactory::create(const std::shared_ptr return newNode; } + +bool MKLDNNNode::canBePerformedAsScaleShift() const { + bool inputsIsConst = true; + for (size_t i = 1; i < getParentEdges().size(); i++) { + if (!getParentEdgeAt(i)->getParent()->isConstant() || getParentEdgeAt(i)->getParent()->getType() != Input) { + inputsIsConst = false; + } + } + return one_of(getAlgorithm(), EltwiseAdd, EltwiseMultiply, EltwiseSubtract, EltwiseDivide, EltwisePrelu, EltwiseMulAdd) && inputsIsConst && + MKLDNNExtensionUtils::isPerTensorOrPerChannelBroadcastable(getParentEdgeAt(0)->getDims().ToSizeVector(), + getParentEdgeAt(1)->getDims().ToSizeVector()); +} + +bool MKLDNNNode::canFuseSimpleOperation(const MKLDNNNodePtr& node) const { + if (node->getType() == Quantize) { + auto* quantizeNode = dynamic_cast(node.get()); + if (quantizeNode == nullptr) + THROW_IE_EXCEPTION << "Cannot get quantize layer " << node->getName(); + return !quantizeNode->isBinarization(); + } else if (node->getType() == Eltwise) { + return one_of(node->getAlgorithm(), EltwiseRelu, EltwiseGelu, EltwiseElu, EltwiseSigmoid, EltwiseBoundedRelu, EltwiseClamp, EltwiseTanh, + EltwiseSwish, EltwiseHswish, EltwiseMish, EltwiseHsigmoid, EltwiseRoundHalfToEven, + EltwiseRoundHalfAwayFromZero, EltwiseLinear, EltwiseAbs, EltwiseSquare, EltwiseSqrt) || + node->canBePerformedAsScaleShift(); + } + + return false; +} diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.h b/inference-engine/src/mkldnn_plugin/mkldnn_node.h index 2c92f2c5853cec..0e0fe7da5452cf 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.h +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.h @@ -661,6 +661,9 @@ class MKLDNNNode : public InferenceEngine::details::no_copy { } protected: + bool canBePerformedAsScaleShift() const; + bool canFuseSimpleOperation(const MKLDNNNodePtr& node) const; + void setType(Type type) { this->type = type; } diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp index 95b4ecdd1762e7..f335c22ec69611 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_eltwise_node.cpp @@ -1775,7 +1775,7 @@ void MKLDNNEltwiseNode::fuseInto(MKLDNNNodePtr& parentNode) { // Handling Convolution custom Add node fusing case which is processed via dnnl append_sum() API. bool isSpecialConvolutionAddFusing = parentNode->getType() == Convolution && getAlgorithm() == EltwiseAdd && getParentEdgesAtPort(0)[0]->getDims().ToSizeVector() == getParentEdgesAtPort(1)[0]->getDims().ToSizeVector(); - if (!isSpecialConvolutionAddFusing && one_of(getAlgorithm(), EltwiseAdd, EltwiseSubtract, EltwiseMultiply, EltwiseDivide, EltwiseMulAdd, EltwisePrelu)) { + if (!isSpecialConvolutionAddFusing && canBePerformedAsScaleShift()) { fillScalesAndShifts(); } MKLDNNNode::fuseInto(parentNode); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp index 625edf1f5d151f..98792b9757a2da 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.cpp @@ -23,6 +23,9 @@ #include "utils/bfloat16.hpp" #include "emitters/jit_bf16_emitters.hpp" +#include +#include + using namespace mkldnn; using namespace MKLDNNPlugin; using namespace InferenceEngine; @@ -1591,28 +1594,6 @@ struct jit_uni_interpolate_kernel_f32 : public jit_uni_interpolate_kernel, publi } }; -MKLDNNInterpolateNode::MKLDNNInterpolateNode(const std::shared_ptr& op, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache) - : MKLDNNNode(op, eng, cache) { - IE_THROW() << "[NM] Not implemented"; -// std::string modeString = layer->GetParamAsString("mode"); -// if (modeString == "nearest") { -// mode = InterpolateMode::nearest; -// } else if (modeString == "linear") { -// size_t rank = layer->insData[0].lock()->getDims().size(); -// if (rank < 5) { -// mode = InterpolateMode::linear_onnx; -// } else { -// mode = InterpolateMode::linear; -// } -// } else if (modeString == "linear_onnx") { -// mode = InterpolateMode::linear_onnx; -// } else if (modeString == "cubic") { -// mode = InterpolateMode::cubic; -// } else { -// IE_THROW() << "Interpolate layer with name '" << getName() << "' does not support interpolate mode:" << modeString; -// } -} - // shapeND: n c d h w // blockND: ncdhw cdhw dhw hw w 1 // index : 0 1 2 3 4 5 @@ -1648,273 +1629,336 @@ SizeVector to5Dim(SizeVector casesDim) { return dim5; } +using ngInterpMode = ngraph::opset4::Interpolate::InterpolateMode; +using ngInterpCoordTransf = ngraph::opset4::Interpolate::CoordinateTransformMode; +using ngInterpNearMode = ngraph::opset4::Interpolate::NearestMode; +using ngInterpShapeCalcMode = ngraph::opset4::Interpolate::ShapeCalcMode; + +bool MKLDNNInterpolateNode::isSupportedOperation(const std::shared_ptr& op, std::string& errorMessage) noexcept { + try { + const auto interp = std::dynamic_pointer_cast(op); + if (!interp) { + errorMessage = "Only opset4 Interpolate operation is supported"; + return false; + } + const auto &interpAttr = interp->get_attrs(); + const auto &interpMode = interpAttr.mode; + if (!one_of(interpMode, ngInterpMode::nearest, ngInterpMode::linear, ngInterpMode::linear_onnx, ngInterpMode::cubic)) { + errorMessage = "Does not support interpolate mode: " + ngraph::as_string(interpMode); + return false; + } + + const auto &interpCoordTransMode = interpAttr.coordinate_transformation_mode; + if (!one_of(interpCoordTransMode, ngInterpCoordTransf::half_pixel, ngInterpCoordTransf::pytorch_half_pixel, ngInterpCoordTransf::asymmetric, + ngInterpCoordTransf::tf_half_pixel_for_nn, ngInterpCoordTransf::align_corners)) { + errorMessage = "Does not support coordinate transformation mode: " + ngraph::as_string(interpCoordTransMode); + return false; + } + + if (interpMode == ngInterpMode::nearest) { + const auto &interpNearestMode = interpAttr.nearest_mode; + if (!one_of(interpNearestMode, ngInterpNearMode::round_prefer_floor, ngInterpNearMode::round_prefer_ceil, ngInterpNearMode::floor, + ngInterpNearMode::ceil, ngInterpNearMode::simple)) { + errorMessage = "Does not support nearest round mode: " + ngraph::as_string(interpNearestMode); + return false; + } + } + + const auto &interpShapeCalcMode = interpAttr.shape_calculation_mode; + if (!one_of(interpShapeCalcMode, ngInterpShapeCalcMode::scales, ngInterpShapeCalcMode::sizes)) { + errorMessage = "Does not support shape_calculation_mode: " + ngraph::as_string(interpShapeCalcMode); + return false; + } + + const size_t dataRank = interp->get_input_shape(DATA_ID).size(); + if (dataRank < 1 || dataRank > 5) { + errorMessage = "Does not support input tensor of rank : " + std::to_string(dataRank); + return false; + } + + if (dataRank == 5 && interpMode == ngInterpMode::cubic) { + errorMessage = "Doesn't support input tensor with rank: " + std::to_string(dataRank) + " for 'cubic' mode "; + return false; + } + + if (std::dynamic_pointer_cast(interp->get_input_node_shared_ptr(SCALES_ID)) == nullptr) { + errorMessage = "Only const 'scales' input is supported"; + return false; + } + + if (interp->get_input_size() > 3 && std::dynamic_pointer_cast(interp->get_input_node_shared_ptr(AXES_ID)) == nullptr) { + errorMessage = "Only const 'axes' input is supported"; + return false; + } + } catch (...) { + return false; + } + return true; +} + +MKLDNNInterpolateNode::MKLDNNInterpolateNode(const std::shared_ptr& op, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache) + : MKLDNNNode(op, eng, cache) { + std::string errorMessage; + if (isSupportedOperation(op, errorMessage)) { + errorPrefix = "Interpolate node with name '" + getName() + "'"; + + const auto interp = std::dynamic_pointer_cast(op); + + if (interp->get_input_size() != 3 && interp->get_input_size() != 4) + IE_THROW() << errorPrefix << " has incorrect number of input edges"; + if (interp->get_output_size() != 1) + IE_THROW() << errorPrefix << " has incorrect number of output edges"; + isAxesSpecified = interp->get_input_size() != 3; + + const auto &interpAttr = interp->get_attrs(); + + const size_t dataRank = interp->get_input_shape(DATA_ID).size(); + const auto &interpMode = interpAttr.mode; + if (interpMode == ngInterpMode::nearest) { + mode = InterpolateMode::nearest; + } else if (interpMode == ngInterpMode::linear) { + if (dataRank < 5) { + mode = InterpolateMode::linear_onnx; + } else { + mode = InterpolateMode::linear; + } + } else if (interpMode == ngInterpMode::linear_onnx) { + mode = InterpolateMode::linear_onnx; + } else if (interpMode == ngInterpMode::cubic) { + mode = InterpolateMode::cubic; + } + + switch (dataRank) { + case 1: + case 3: + spatialDimSize = 1; + break; + case 2: + case 4: + spatialDimSize = 2; + break; + case 5: + spatialDimSize = 3; + break; + } + + const auto &interpCoordTransMode = interpAttr.coordinate_transformation_mode; + if (interpCoordTransMode == ngInterpCoordTransf::half_pixel) { + coordTransMode = InterpolateCoordTransMode::half_pixel; + } else if (interpCoordTransMode == ngInterpCoordTransf::pytorch_half_pixel) { + coordTransMode = InterpolateCoordTransMode::pytorch_half_pixel; + } else if (interpCoordTransMode == ngInterpCoordTransf::asymmetric) { + coordTransMode = InterpolateCoordTransMode::asymmetric; + } else if (interpCoordTransMode == ngInterpCoordTransf::tf_half_pixel_for_nn) { + coordTransMode = InterpolateCoordTransMode::tf_half_pixel_for_nn; + } else if (interpCoordTransMode == ngInterpCoordTransf::align_corners) { + coordTransMode = InterpolateCoordTransMode::align_corners; + } + + if (mode == InterpolateMode::nearest) { + const auto &interpNearestMode = interpAttr.nearest_mode; + if (interpNearestMode == ngInterpNearMode::round_prefer_floor) { + nearestMode = InterpolateNearestMode::round_prefer_floor; + } else if (interpNearestMode == ngInterpNearMode::round_prefer_ceil) { + nearestMode = InterpolateNearestMode::round_prefer_ceil; + } else if (interpNearestMode == ngInterpNearMode::floor) { + nearestMode = InterpolateNearestMode::floor; + } else if (interpNearestMode == ngInterpNearMode::ceil) { + nearestMode = InterpolateNearestMode::ceil; + } else if (interpNearestMode == ngInterpNearMode::simple) { + nearestMode = InterpolateNearestMode::simple; + } + } else if (mode == InterpolateMode::cubic) { + cubeCoeff = static_cast(interpAttr.cube_coeff); + } + antialias = interpAttr.antialias; + + const auto &interpShapeCalcMode = interpAttr.shape_calculation_mode; + if (interpShapeCalcMode == ngInterpShapeCalcMode::scales) { + shapeCalcMode = InterpolateShapeCalcMode::scales; + } else if (interpShapeCalcMode == ngInterpShapeCalcMode::sizes) { + shapeCalcMode = InterpolateShapeCalcMode::sizes; + } + + if (interpAttr.pads_begin.empty()) { + padBegin.resize(dataRank, 0); + } else { + padBegin.resize(interpAttr.pads_begin.size()); + for (size_t i = 0; i < interpAttr.pads_begin.size(); i++) + padBegin[i] = static_cast(interpAttr.pads_begin[i]); + } + + if (interpAttr.pads_end.empty()) { + padEnd.resize(dataRank, 0); + } else { + padEnd.resize(interpAttr.pads_end.size()); + for (size_t i = 0; i < interpAttr.pads_end.size(); i++) + padEnd[i] = static_cast(interpAttr.pads_end[i]); + } + + scales = std::dynamic_pointer_cast(interp->get_input_node_shared_ptr(SCALES_ID))->cast_vector(); + + if (isAxesSpecified) { + axes = std::dynamic_pointer_cast(interp->get_input_node_shared_ptr(AXES_ID))->cast_vector(); + } else { + axes.resize(dataRank); + for (int i = 0; i < dataRank; i++) { + axes[i] = i; + } + } + + if (scales.size() != axes.size()) { + IE_THROW() << errorPrefix << " does not have the same number elements in scales as in axis."; + } + } else { + IE_THROW(NotImplemented) << errorMessage; + } +} + void MKLDNNInterpolateNode::getSupportedDescriptors() { - IE_THROW() << "[NM] Not implemented"; -// if (!descs.empty()) -// return; -// -// if (getParentEdges().size() != 3 && getParentEdges().size() != 4) -// // data, target_shape, scale, axis(optional). -// IE_THROW() << "Interpolate layer with name '" << getName() << "' has incorrect number of input edges"; -// isAxesSpecified = (getParentEdges().size() == 3) ? false : true; -// if (getChildEdges().empty()) -// IE_THROW() << "Interpolate layer with name '" << getName() << "' has incorrect number of output edges"; -// -// srcDim = getParentEdgeAt(DATA_ID)->getDims().ToSizeVector(); -// int dataRank = srcDim.size(); -// switch (dataRank) { -// case 1: -// case 3: -// spatialDimSize = 1; -// break; -// case 2: -// case 4: -// spatialDimSize = 2; -// break; -// case 5: -// if (mode != InterpolateMode::cubic) { -// spatialDimSize = 3; -// } else { -// IE_THROW() << "Interpolate layer with name '" << getName() << -// "' of 'cubic' mode only support input tensor of 2 or 4 rank"; -// } -// break; -// default: -// IE_THROW() << "Interpolate layer with name '" << getName() << -// "' does not support input tensor of rank :" << dataRank; -// break; -// } -// -// auto *layer = getCnnLayer().get(); -// std::string modeString = layer->GetParamAsString("coordinate_transformation_mode", "half_pixel"); -// if (modeString == "half_pixel") { -// coordTransMode = InterpolateCoordTransMode::half_pixel; -// } else if (modeString == "pytorch_half_pixel") { -// coordTransMode = InterpolateCoordTransMode::pytorch_half_pixel; -// } else if (modeString == "asymmetric") { -// coordTransMode = InterpolateCoordTransMode::asymmetric; -// } else if (modeString == "tf_half_pixel_for_nn") { -// coordTransMode = InterpolateCoordTransMode::tf_half_pixel_for_nn; -// } else if (modeString == "align_corners") { -// coordTransMode = InterpolateCoordTransMode::align_corners; -// } else { -// IE_THROW() << "Interpolate layer with name '" << getName() << "' does not support coordinate transformation mode: " << modeString; -// } -// -// if (mode == InterpolateMode::nearest) { -// modeString = layer->GetParamAsString("nearest_mode", "round_prefer_floor"); -// if (modeString == "round_prefer_floor") { -// nearestMode = InterpolateNearestMode::round_prefer_floor; -// } else if (modeString == "round_prefer_ceil") { -// nearestMode = InterpolateNearestMode::round_prefer_ceil; -// } else if (modeString == "floor") { -// nearestMode = InterpolateNearestMode::floor; -// } else if (modeString == "ceil") { -// nearestMode = InterpolateNearestMode::ceil; -// } else if (modeString == "simple") { -// nearestMode = InterpolateNearestMode::simple; -// } else { -// IE_THROW() << "Interpolate layer with name '" << getName() << "' does not support nearest round mode: " << modeString; -// } -// } else if (mode == InterpolateMode::cubic) { -// cubeCoeff = layer->GetParamAsFloat("cube_coeff", -0.75); -// } -// antialias = layer->GetParamAsBool("antialias", false); -// shapeInferMode = layer->GetParamAsString("shape_calculation_mode"); -// -// // get pad -// std::vector defPad(dataRank, 0); -// padBegin = layer->GetParamAsInts("pads_begin", defPad); -// padEnd = layer->GetParamAsInts("pads_end", defPad); -// for (int i = 0; i < padBegin.size(); i++) { -// if (padBegin[i] != 0) { -// hasPad = true; -// break; -// } -// } -// for (int i = 0; i < padEnd.size(); i++) { -// if (padEnd[i] != 0) { -// hasPad = true; -// break; -// } -// } -// //correct pad -// if (hasPad) { -// auto correctPad = [&](std::vector pad, int rank) { -// int padLen = pad.size(); -// if (padLen == rank) { -// return pad; -// } -// std::vector result; -// if (padLen > rank) { -// result.insert(result.end(), pad.begin(), pad.begin() + rank); -// } else { -// result = pad; -// result.insert(result.end(), rank - padLen, 0); -// } -// return result; -// }; -// -// padBegin = correctPad(padBegin, dataRank); -// padEnd = correctPad(padEnd, dataRank); -// srcDimPad = getPaddedInputShape(); -// } else { -// srcDimPad = srcDim; -// } -// dstDim = getChildEdgeAt(0)->getDims().ToSizeVector(); -// -// // extract const buffer -// auto scalesLayer = getParentEdgesAtPort(SCALES_ID)[0]->getParent()->getCnnLayer(); -// if (scalesLayer->type == "Const") { -// auto scalesBlob = dynamic_cast*>(scalesLayer->blobs["custom"].get()); -// auto scalesData = scalesBlob->buffer().as(); -// int scalesLen = getParentEdgeAt(SCALES_ID)->getDims()[0]; -// scales.resize(scalesLen); -// for (int i = 0; i < scalesLen; i++) { -// scales[i] = scalesData[i]; -// } -// } else { -// IE_THROW() << "Interpolate layer with name '" << getName() << "' only supports const 'scales' input."; -// } -// -// if (isAxesSpecified) { -// auto axesLayer = getParentEdgesAtPort(AXES_ID)[0]->getParent()->getCnnLayer(); -// if (axesLayer->type == "Const") { -// auto axesBlob = dynamic_cast*>(axesLayer->blobs["custom"].get()); -// auto axesData = axesBlob->buffer().as(); -// int axesLen = getParentEdgeAt(AXES_ID)->getDims()[0]; -// axes.resize(axesLen); -// for (int i = 0; i < axesLen; i++) { -// axes[i] = axesData[i]; -// } -// } else { -// IE_THROW() << "Interpolate layer with name '" << getName() << "' only supports const 'axes' input."; -// } -// } else { -// int dataRank = srcDim.size(); -// axes.resize(dataRank); -// for (int i = 0; i < dataRank; i++) { -// axes[i] = i; -// } -// } -// -// if (scales.size() != axes.size()) { -// IE_THROW() << "Interpolate layer with name '" << getName() << -// "' does not have the same number elements in scales as in axis."; -// } + if (getParentEdges().size() != 3 && getParentEdges().size() != 4) + // data, target_shape, scale, axis(optional). + IE_THROW() << errorPrefix << " has incorrect number of input edges"; + if (getChildEdges().empty()) + IE_THROW() << errorPrefix << " has incorrect number of output edges"; + + srcDim = getParentEdgeAt(DATA_ID)->getDims().ToSizeVector(); + int dataRank = srcDim.size(); + + // get pad + for (int i = 0; i < padBegin.size(); i++) { + if (padBegin[i] != 0) { + hasPad = true; + break; + } + } + for (int i = 0; i < padEnd.size(); i++) { + if (padEnd[i] != 0) { + hasPad = true; + break; + } + } + //correct pad + if (hasPad) { + auto correctPad = [&](std::vector pad, int rank) { + int padLen = pad.size(); + if (padLen == rank) { + return pad; + } + std::vector result; + if (padLen > rank) { + result.insert(result.end(), pad.begin(), pad.begin() + rank); + } else { + result = pad; + result.insert(result.end(), rank - padLen, 0); + } + return result; + }; + + padBegin = correctPad(padBegin, dataRank); + padEnd = correctPad(padEnd, dataRank); + srcDimPad = getPaddedInputShape(); + } else { + srcDimPad = srcDim; + } + dstDim = getChildEdgeAt(0)->getDims().ToSizeVector(); } void MKLDNNInterpolateNode::initSupportedPrimitiveDescriptors() { - IE_THROW() << "[NM] Not implemented"; -// if (!supportedPrimitiveDescriptors.empty()) -// return; -// -// setPostOps(attr, true); -// -// Precision inputPrecision = getCnnLayer()->insData[DATA_ID].lock()->getPrecision(); -// if ((inputPrecision != Precision::I8) && (inputPrecision != Precision::U8) && (inputPrecision != Precision::BF16)) { -// inputPrecision = Precision::FP32; -// } -// if ((inputPrecision == Precision::BF16) && !mayiuse(avx512_core)) { -// inputPrecision = Precision::FP32; -// } -// Precision outputPrecision = inputPrecision; -// -// if (!fusedWith.empty()) { -// auto lastFusedLayer = fusedWith[fusedWith.size() - 1].get()->getCnnLayer(); -// if (lastFusedLayer) { -// outputPrecision = lastFusedLayer->outData[0]->getPrecision(); -// } -// } -// -// if (!mayiuse(cpu::x64::sse41)) { -// inputPrecision = outputPrecision = Precision::FP32; -// } -// -// auto inputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(inputPrecision); -// auto outputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(outputPrecision); -// srcDataSize = MKLDNNExtensionUtils::sizeOfDataType(inputDataType); -// dstDataSize = MKLDNNExtensionUtils::sizeOfDataType(outputDataType); -// -// inputPrec = inputPrecision; -// outputPrec = outputPrecision; -// -// InferenceEngine::LayerConfig config; -// config.dynBatchSupport = false; -// if (isAxesSpecified) { -// config.inConfs.resize(4); -// } else { -// config.inConfs.resize(3); -// } -// config.outConfs.resize(1); -// config.inConfs[DATA_ID].constant = false; -// config.inConfs[TARGET_SHAPE_ID].constant = false; -// config.inConfs[SCALES_ID].constant = false; -// config.outConfs[0].constant = false; -// config.inConfs[DATA_ID].inPlace = -1; -// config.inConfs[TARGET_SHAPE_ID].inPlace = -1; -// config.inConfs[SCALES_ID].inPlace = -1; -// config.outConfs[0].inPlace = -1; -// if (isAxesSpecified) { -// config.inConfs[AXES_ID].constant = false; -// config.inConfs[AXES_ID].inPlace = -1; -// } -// -// auto targetShapeType = MKLDNNExtensionUtils::IEPrecisionToDataType(Precision::I32); -// auto scalesType = MKLDNNExtensionUtils::IEPrecisionToDataType(Precision::FP32); -// auto axesType = MKLDNNExtensionUtils::IEPrecisionToDataType(Precision::I32); -// -// auto pushDesc = [&](memory::format_tag dataFormat, impl_desc_type implDetail) { -// config.inConfs[DATA_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(DATA_ID)->getDims(), inputDataType, dataFormat); -// config.inConfs[TARGET_SHAPE_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(TARGET_SHAPE_ID)->getDims(), targetShapeType, memory::format_tag::x); -// config.inConfs[SCALES_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(SCALES_ID)->getDims(), scalesType, memory::format_tag::x); -// if (isAxesSpecified) -// config.inConfs[AXES_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(AXES_ID)->getDims(), axesType, memory::format_tag::x); -// config.outConfs[0].desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, dataFormat); -// supportedPrimitiveDescriptors.push_back({config, implDetail, dataFormat}); -// }; -// -// auto channels = getParentEdgeAt(DATA_ID)->getDims().ndims() > 1 ? getParentEdgeAt(DATA_ID)->getDims()[1] : 1; -// -// if (!mayiuse(cpu::x64::sse41) || mode == InterpolateMode::linear) { -// pushDesc(MKLDNNMemory::GetPlainFormat(getParentEdgeAt(DATA_ID)->getDims()), ref); -// } else { -// // blk and by_channel JIT kernel on sse41 or above machine -// if (getParentEdgeAt(DATA_ID)->getDims().ndims() == 4) { -// if (mayiuse(cpu::x64::avx512_common)) { -// pushDesc(memory::format_tag::nhwc, jit_avx512); -// if (channels != 1) -// pushDesc(memory::format_tag::nChw16c, jit_avx512); -// } else if (mayiuse(cpu::x64::avx2)) { -// pushDesc(memory::format_tag::nhwc, jit_avx2); -// if (channels != 1) -// pushDesc(memory::format_tag::nChw8c, jit_avx2); -// } else { -// pushDesc(memory::format_tag::nhwc, jit_sse42); -// if (channels != 1) -// pushDesc(memory::format_tag::nChw8c, jit_sse42); -// } -// } else if (getParentEdgeAt(DATA_ID)->getDims().ndims() == 5 && mode != InterpolateMode::cubic) { -// if (mayiuse(cpu::x64::avx512_common)) { -// pushDesc(memory::format_tag::ndhwc, jit_avx512); -// if (channels != 1) -// pushDesc(memory::format_tag::nCdhw16c, jit_avx512); -// } else if (mayiuse(cpu::x64::avx2)) { -// pushDesc(memory::format_tag::ndhwc, jit_avx2); -// if (channels != 1) -// pushDesc(memory::format_tag::nCdhw8c, jit_avx2); -// } else { -// pushDesc(memory::format_tag::ndhwc, jit_sse42); -// if (channels != 1) -// pushDesc(memory::format_tag::nCdhw8c, jit_sse42); -// } -// } -// -// // planar for 1.ref on machine without sse41(if no sse41, canFuse() is false). 2.JIT kernel for f32 && avx2(gather).(with fuse) -// if (mayiuse(cpu::x64::avx2) && inputPrec == Precision::FP32) { -// pushDesc(MKLDNNMemory::GetPlainFormat(getParentEdgeAt(DATA_ID)->getDims()), jit_avx2); -// } -// } + if (!supportedPrimitiveDescriptors.empty()) + return; + + setPostOps(attr, true); + + Precision inputPrecision = getOriginalInputPrecisionAtPort(DATA_ID); + if ((inputPrecision != Precision::I8) && (inputPrecision != Precision::U8) && (inputPrecision != Precision::BF16)) { + inputPrecision = Precision::FP32; + } + if ((inputPrecision == Precision::BF16) && !mayiuse(avx512_core)) { + inputPrecision = Precision::FP32; + } + Precision outputPrecision = inputPrecision; + + if (!fusedWith.empty()) { + outputPrecision = fusedWith[fusedWith.size() - 1]->getOriginalOutputPrecisionAtPort(DATA_ID); + } + + if (!mayiuse(cpu::x64::sse41)) { + inputPrecision = outputPrecision = Precision::FP32; + } + + auto inputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(inputPrecision); + auto outputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(outputPrecision); + srcDataSize = MKLDNNExtensionUtils::sizeOfDataType(inputDataType); + dstDataSize = MKLDNNExtensionUtils::sizeOfDataType(outputDataType); + + inputPrec = inputPrecision; + outputPrec = outputPrecision; + + InferenceEngine::LayerConfig config; + config.dynBatchSupport = false; + if (isAxesSpecified) { + config.inConfs.resize(4); + } else { + config.inConfs.resize(3); + } + config.outConfs.resize(1); + + auto targetShapeType = MKLDNNExtensionUtils::IEPrecisionToDataType(Precision::I32); + auto scalesType = MKLDNNExtensionUtils::IEPrecisionToDataType(Precision::FP32); + auto axesType = MKLDNNExtensionUtils::IEPrecisionToDataType(Precision::I32); + + auto pushDesc = [&](memory::format_tag dataFormat, impl_desc_type implDetail) { + config.inConfs[DATA_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(DATA_ID)->getDims(), inputDataType, dataFormat); + config.inConfs[TARGET_SHAPE_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(TARGET_SHAPE_ID)->getDims(), targetShapeType, memory::format_tag::x); + config.inConfs[SCALES_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(SCALES_ID)->getDims(), scalesType, memory::format_tag::x); + if (isAxesSpecified) + config.inConfs[AXES_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(AXES_ID)->getDims(), axesType, memory::format_tag::x); + config.outConfs[0].desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, dataFormat); + supportedPrimitiveDescriptors.push_back({config, implDetail, dataFormat}); + }; + + auto channels = getParentEdgeAt(DATA_ID)->getDims().ndims() > 1 ? getParentEdgeAt(DATA_ID)->getDims()[1] : 1; + + if (!mayiuse(cpu::x64::sse41) || mode == InterpolateMode::linear) { + pushDesc(MKLDNNMemory::GetPlainFormat(getParentEdgeAt(DATA_ID)->getDims()), ref); + } else { + // blk and by_channel JIT kernel on sse41 or above machine + if (getParentEdgeAt(DATA_ID)->getDims().ndims() == 4) { + if (mayiuse(cpu::x64::avx512_common)) { + pushDesc(memory::format_tag::nhwc, jit_avx512); + if (channels != 1) + pushDesc(memory::format_tag::nChw16c, jit_avx512); + } else if (mayiuse(cpu::x64::avx2)) { + pushDesc(memory::format_tag::nhwc, jit_avx2); + if (channels != 1) + pushDesc(memory::format_tag::nChw8c, jit_avx2); + } else { + pushDesc(memory::format_tag::nhwc, jit_sse42); + if (channels != 1) + pushDesc(memory::format_tag::nChw8c, jit_sse42); + } + } else if (getParentEdgeAt(DATA_ID)->getDims().ndims() == 5 && mode != InterpolateMode::cubic) { + if (mayiuse(cpu::x64::avx512_common)) { + pushDesc(memory::format_tag::ndhwc, jit_avx512); + if (channels != 1) + pushDesc(memory::format_tag::nCdhw16c, jit_avx512); + } else if (mayiuse(cpu::x64::avx2)) { + pushDesc(memory::format_tag::ndhwc, jit_avx2); + if (channels != 1) + pushDesc(memory::format_tag::nCdhw8c, jit_avx2); + } else { + pushDesc(memory::format_tag::ndhwc, jit_sse42); + if (channels != 1) + pushDesc(memory::format_tag::nCdhw8c, jit_sse42); + } + } + + // planar for 1.ref on machine without sse41(if no sse41, canFuse() is false). 2.JIT kernel for f32 && avx2(gather).(with fuse) + if (mayiuse(cpu::x64::avx2) && inputPrec == Precision::FP32) { + pushDesc(MKLDNNMemory::GetPlainFormat(getParentEdgeAt(DATA_ID)->getDims()), jit_avx2); + } + } } void MKLDNNInterpolateNode::createPrimitive() { @@ -1925,18 +1969,18 @@ void MKLDNNInterpolateNode::createPrimitive() { if (getParentEdges().size() > 3) { auto &axesMemPtr = getParentEdgeAt(AXES_ID)->getMemoryPtr(); if (!axesMemPtr || !axesMemPtr->GetPrimitivePtr()) - IE_THROW() << "Interpolate layer with name '" << getName() << "' did not allocate axes memory"; + IE_THROW() << errorPrefix << " did not allocate axes memory"; } if (!dstMemPtr || !dstMemPtr->GetPrimitivePtr()) - IE_THROW() << "Interpolate layer with name '" << getName() << "' did not allocate destination memory"; + IE_THROW() << errorPrefix << " did not allocate destination memory"; if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr()) - IE_THROW() << "Interpolate layer with name '" << getName() << "' did not allocate input memory"; + IE_THROW() << errorPrefix << " did not allocate input memory"; if (!tsMemPtr || !tsMemPtr->GetPrimitivePtr()) - IE_THROW() << "Interpolate layer with name '" << getName() << "' did not allocate target shape memory"; + IE_THROW() << errorPrefix << " did not allocate target shape memory"; if (!scaleMemPtr || !scaleMemPtr->GetPrimitivePtr()) - IE_THROW() << "Interpolate layer with name '" << getName() << "' did not allocate scales memory"; + IE_THROW() << errorPrefix << " did not allocate scales memory"; if (getSelectedPrimitiveDescriptor() == nullptr) - IE_THROW() << "Interpolate layer with name '" << getName() << "' did not set preferable primitive descriptor"; + IE_THROW() << errorPrefix << " did not set preferable primitive descriptor"; auto selectedPD = getSelectedPrimitiveDescriptor(); auto jcp = jit_interpolate_config_params(); @@ -2010,7 +2054,7 @@ void MKLDNNInterpolateNode::createPrimitive() { break; } default: { - IE_THROW() << "Interpolate layer with name '" << getName() << "' does not support interpolate mode:" << mode; + IE_THROW() << errorPrefix << " does not support interpolate mode:" << mode; break; } } @@ -2380,7 +2424,8 @@ std::vector MKLDNNInterpolateNode::getScales() { int axesRank = axes.size(); for (int i = 0; i < axesRank; i++) { int axis = axes[i]; - fullScales[axis] = (shapeInferMode == "scales") ? scales[i] : static_cast(dstDim[axis]) / static_cast(srcDimPad[axis]); + fullScales[axis] = (shapeCalcMode == InterpolateShapeCalcMode::scales) ? scales[i] : + static_cast(dstDim[axis]) / static_cast(srcDimPad[axis]); } return fullScales; } @@ -3135,7 +3180,7 @@ inline float MKLDNNInterpolateNode::coordTransToInput(int outCoord, float scale, break; } default: { - IE_THROW() << "Interpolate layer with name '" << getName() << "' does not support specified coordinate transformation mode"; + IE_THROW() << errorPrefix << " does not support specified coordinate transformation mode"; break; } } @@ -3169,42 +3214,18 @@ inline int MKLDNNInterpolateNode::nearestRound(float originCoord, bool isDownsam return static_cast(originCoord); } default: { - IE_THROW() << "Interpolate layer with name '" << getName() << "' does not support specified nearest round mode"; + IE_THROW() << errorPrefix << " does not support specified nearest round mode"; break; } } } bool MKLDNNInterpolateNode::canFuse(const MKLDNNNodePtr& node) const { - IE_THROW() << "[NM] Not implemented"; -// auto isOneOf = [&](EltwiseOpType alg, std::vector algs) { -// for (auto a : algs) { -// if (alg == a) { -// return true; -// } -// } -// return false; -// }; -// -// if (!mayiuse(cpu::x64::sse41) || mode == InterpolateMode::linear) { -// return false; -// } -// -// if (node->getType() == Quantize) { -// auto* quantizeNode = dynamic_cast(node.get()); -// if (quantizeNode == nullptr) -// IE_THROW() << "Cannot get quantize node " << node->getName(); -// return !quantizeNode->isBinarization(); -// } else if (node->getType() == Eltwise) { -// auto* eltwiseNode = dynamic_cast(node.get()); -// if (eltwiseNode == nullptr) -// IE_THROW() << "Cannot get eltwise node " << node->getName(); -// return isOneOf(eltwiseNode->getOpType(), {Prelu, Relu, Gelu, Elu, Logistic, BoundedRelu, Clamp, -// Tanh, Swish, Hswish, Mish, Hsigmoid, Round, Linear, Abs, Square, Sqrt}) || -// (eltwiseNode->getOpType() == MulAdd && eltwiseNode->getCnnLayer()->blobs.size() == 2); -// } -// -// return false; + if (!mayiuse(cpu::x64::sse41) || mode == InterpolateMode::linear) { + return false; + } + + return canFuseSimpleOperation(node); } bool MKLDNNInterpolateNode::created() const { diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.h index c82f4f858e55a7..5912ddaa5e8fa6 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.h +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_interpolate_node.h @@ -44,6 +44,11 @@ enum class InterpolateNearestMode { simple }; +enum class InterpolateShapeCalcMode { + sizes, + scales +}; + struct jit_interpolate_config_params { InterpolateLayoutType layout; InterpolateMode mode; @@ -98,6 +103,8 @@ class MKLDNNInterpolateNode : public MKLDNNNode { } bool canFuse(const MKLDNNNodePtr& node) const override; + static bool isSupportedOperation(const std::shared_ptr& op, std::string& errorMessage) noexcept; + private: // nearest neighbor void NNPlanar(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int ID, int IH, int IW, int OD, int OH, int OW); @@ -135,10 +142,10 @@ class MKLDNNInterpolateNode : public MKLDNNNode { SizeVector getPaddedInputShape(); std::vector getScales(); - const size_t DATA_ID = 0; - const size_t TARGET_SHAPE_ID = 1; - const size_t SCALES_ID = 2; - const size_t AXES_ID = 3; + static const size_t DATA_ID = 0; + static const size_t TARGET_SHAPE_ID = 1; + static const size_t SCALES_ID = 2; + static const size_t AXES_ID = 3; const int LINEAR_KERNEL = 2; const int CUBIC_GRID_LEN = 4; @@ -149,6 +156,8 @@ class MKLDNNInterpolateNode : public MKLDNNNode { std::vector padEnd; bool hasPad = false; InterpolateNearestMode nearestMode = InterpolateNearestMode::round_prefer_floor; + InterpolateShapeCalcMode shapeCalcMode; + float cubeCoeff = -0.75; bool isAxesSpecified = false; @@ -157,7 +166,6 @@ class MKLDNNInterpolateNode : public MKLDNNNode { std::vector scales; // target shape is dst dim, full size. SizeVector dstDim; - std::string shapeInferMode; SizeVector srcDim; SizeVector srcDimPad; int spatialDimSize; @@ -173,6 +181,8 @@ class MKLDNNInterpolateNode : public MKLDNNNode { std::vector indexTable; std::shared_ptr interpolateKernel = nullptr; + + std::string errorPrefix; }; } // namespace MKLDNNPlugin diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_normalize_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_normalize_node.cpp index 738b86ff99a7f7..c5760506017489 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_normalize_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_normalize_node.cpp @@ -781,26 +781,7 @@ void MKLDNNNormalizeL2Node::initSupportedPrimitiveDescriptors() { } bool MKLDNNNormalizeL2Node::canFuse(const MKLDNNNodePtr& node) const { - auto isConvertableToScaleShift = [](MKLDNNNodePtr node) { - return one_of(node->getAlgorithm(), EltwiseAdd, EltwiseMultiply, EltwiseSubtract, EltwiseDivide, EltwisePrelu) && - node->getParentEdgeAt(1)->getParent()->getType() == Input && node->getParentEdgeAt(1)->getParent()->isConstant() && - MKLDNNExtensionUtils::isPerTensorOrPerChannelBroadcastable(node->getParentEdgeAt(0)->getDims().ToSizeVector(), - node->getParentEdgeAt(1)->getDims().ToSizeVector()); - }; - - if (node->getType() == Quantize) { - auto* quantizeNode = dynamic_cast(node.get()); - if (quantizeNode == nullptr) - IE_THROW() << "Cannot get quantize layer " << node->getName(); - return !quantizeNode->isBinarization(); - } else if (node->getType() == Eltwise) { - return one_of(node->getAlgorithm(), EltwiseRelu, EltwiseGelu, EltwiseElu, EltwiseSigmoid, EltwiseBoundedRelu, EltwiseClamp, EltwiseTanh, - EltwiseSwish, EltwiseHswish, EltwiseMish, EltwiseHsigmoid, EltwiseRoundHalfToEven, - EltwiseRoundHalfAwayFromZero, EltwiseLinear, EltwiseAbs, EltwiseSquare, EltwiseSqrt, EltwiseMulAdd) || - isConvertableToScaleShift(node); - } - - return false; + return canFuseSimpleOperation(node); } void MKLDNNNormalizeL2Node::setPostOps(mkldnn::primitive_attr &attr, bool initWeights) { diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp index 53ae1a04fef438..ed1d25a89c5be2 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/skip_tests_config.cpp @@ -54,7 +54,7 @@ std::vector disabledTestPatterns() { // TODO: Issue 43417 sporadic issue, looks like an issue in test, reproducible only on Windows platform R"(.*decomposition1_batch=5_hidden_size=10_input_size=30_.*tanh.relu.*_clip=0_linear_before_reset=1.*_targetDevice=CPU_.*)", // Skip platforms that do not support BF16 (i.e. sse, avx, avx2) - R"(.*BF16.*(jit_avx(?!5)|jit_sse).*)", + R"(.*BF16.*(jit_avx(?!5)|jit_sse|ref).*)", // TODO: Incorrect blob sizes for node BinaryConvolution_X R"(.*BinaryConvolutionLayerTest.*)", // TODO: 51676. Incorrect conversion of min and max limits from double to integral diff --git a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp index 2ce67191202c3c..75333d50956ef5 100644 --- a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp +++ b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/interpolate.cpp @@ -12,21 +12,18 @@ using namespace CPUTestUtils; namespace CPULayerTestsDefinitions { typedef std::tuple< - LayerTestsDefinitions::InterpolateLayerTestParams, - CPUSpecificParams, - fusingSpecificParams, - std::map - > InterpolateLayerCPUTestParamsSet; + LayerTestsDefinitions::InterpolateLayerTestParams, + CPUSpecificParams, + fusingSpecificParams> InterpolateLayerCPUTestParamsSet; class InterpolateLayerCPUTest : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon, public CpuTestWithFusing { + virtual public LayerTestsUtils::LayerTestsCommon, public CpuTestWithFusing { public: static std::string getTestCaseName(testing::TestParamInfo obj) { LayerTestsDefinitions::InterpolateLayerTestParams basicParamsSet; CPUSpecificParams cpuParams; fusingSpecificParams fusingParams; - std::map additionalConfig; - std::tie(basicParamsSet, cpuParams, fusingParams, additionalConfig) = obj.param; + std::tie(basicParamsSet, cpuParams, fusingParams) = obj.param; std::ostringstream result; result << LayerTestsDefinitions::InterpolateLayerTest::getTestCaseName(testing::TestParamInfo( @@ -35,13 +32,6 @@ class InterpolateLayerCPUTest : public testing::WithParamInterface filterCPUInfoForDevice() { } return resCPUParams; } -/* ========== */ + +const std::vector fusingParamsSet { + emptyFusingSpec, + fusingRelu, + fusingSubtractPerChannel, + fusingPReluPerTensor +}; const std::vector netPrecisions = { + InferenceEngine::Precision::BF16, InferenceEngine::Precision::FP32 }; @@ -220,28 +214,6 @@ const auto interpolateCasesLinear = ::testing::Combine( ::testing::ValuesIn(defaultAxes), ::testing::ValuesIn(defaultScales)); -const auto interpolateCasesCubic = ::testing::Combine( - ::testing::Values(ngraph::op::v4::Interpolate::InterpolateMode::cubic), - ::testing::ValuesIn(shapeCalculationMode), - ::testing::ValuesIn(coordinateTransformModes), - ::testing::ValuesIn(defNearestModes), - ::testing::ValuesIn(antialias), - ::testing::ValuesIn(pads), - ::testing::ValuesIn(pads), - ::testing::ValuesIn(cubeCoefs), - ::testing::ValuesIn(defaultAxes), - ::testing::ValuesIn(defaultScales)); - -const std::vector interpolateFusingParamsSet{ - emptyFusingSpec, - fusingRelu, -}; - -std::vector> bf16EnforceFlags = { - {{PluginConfigParams::KEY_ENFORCE_BF16, PluginConfigParams::NO}}, - {{PluginConfigParams::KEY_ENFORCE_BF16, PluginConfigParams::YES}} -}; - INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN_Layout_Test, InterpolateLayerCPUTest, ::testing::Combine( ::testing::Combine( @@ -255,8 +227,7 @@ INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN_Layout_Test, InterpolateLayerCPUTest ::testing::Values(std::vector({1, 21, 50, 60})), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice()), - ::testing::ValuesIn(interpolateFusingParamsSet), - ::testing::ValuesIn(bf16EnforceFlags)), + ::testing::ValuesIn(fusingParamsSet)), InterpolateLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinearOnnx_Layout_Test, InterpolateLayerCPUTest, @@ -272,8 +243,7 @@ INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinearOnnx_Layout_Test, InterpolateLaye ::testing::Values(std::vector({1, 21, 50, 60})), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice()), - ::testing::ValuesIn(interpolateFusingParamsSet), - ::testing::ValuesIn(bf16EnforceFlags)), + ::testing::ValuesIn(fusingParamsSet)), InterpolateLayerCPUTest::getTestCaseName); INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinear_Layout_Test, InterpolateLayerCPUTest, @@ -289,44 +259,25 @@ INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinear_Layout_Test, InterpolateLayerCPU ::testing::Values(std::vector({1, 21, 50, 60})), ::testing::Values(CommonTestUtils::DEVICE_CPU)), ::testing::ValuesIn(filterCPUInfoForDevice()), - ::testing::ValuesIn(interpolateFusingParamsSet), - ::testing::ValuesIn(bf16EnforceFlags)), - InterpolateLayerCPUTest::getTestCaseName); - -INSTANTIATE_TEST_CASE_P(smoke_InterpolateCubic_Layout_Test, InterpolateLayerCPUTest, - ::testing::Combine( - ::testing::Combine( - interpolateCasesCubic, - ::testing::ValuesIn(netPrecisions), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({1, 21, 40, 40})), - ::testing::Values(std::vector({1, 21, 50, 60})), - ::testing::Values(CommonTestUtils::DEVICE_CPU)), - ::testing::ValuesIn(filterCPUInfoForDevice()), - ::testing::ValuesIn(interpolateFusingParamsSet), - ::testing::ValuesIn(bf16EnforceFlags)), + ::testing::ValuesIn(fusingParamsSet)), InterpolateLayerCPUTest::getTestCaseName); ////////////////////////5D///////////////////////////// std::vector filterCPUInfoForDevice5D() { std::vector resCPUParams; if (with_cpu_x86_avx512f()) { - resCPUParams.push_back(CPUSpecificParams{{nCdhw16c, x, x}, {nCdhw16c}, {"jit_avx512"}, "jit_avx512_FP32"}); - resCPUParams.push_back(CPUSpecificParams{{ndhwc, x, x}, {ndhwc}, {"jit_avx512"}, "jit_avx512_FP32"}); - resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"jit_avx512"}, "jit_avx512_FP32"}); + resCPUParams.push_back(CPUSpecificParams{{nCdhw16c, x, x}, {nCdhw16c}, {"jit_avx512"}, "jit_avx512"}); + resCPUParams.push_back(CPUSpecificParams{{ndhwc, x, x}, {ndhwc}, {"jit_avx512"}, "jit_avx512"}); + resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"jit_avx2"}, "jit_avx2"}); } else if (with_cpu_x86_avx2()) { - resCPUParams.push_back(CPUSpecificParams{{nCdhw8c, x, x}, {nCdhw8c}, {"jit_avx2"}, "jit_avx2_FP32"}); - resCPUParams.push_back(CPUSpecificParams{{ndhwc, x, x}, {ndhwc}, {"jit_avx2"}, "jit_avx2_FP32"}); - resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"jit_avx2"}, "jit_avx2_FP32"}); + resCPUParams.push_back(CPUSpecificParams{{nCdhw8c, x, x}, {nCdhw8c}, {"jit_avx2"}, "jit_avx2"}); + resCPUParams.push_back(CPUSpecificParams{{ndhwc, x, x}, {ndhwc}, {"jit_avx2"}, "jit_avx2"}); + resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"jit_avx2"}, "jit_avx2"}); } else if (with_cpu_x86_sse42()) { - resCPUParams.push_back(CPUSpecificParams{{nCdhw8c, x, x}, {nCdhw8c}, {"jit_sse42"}, "jit_sse42_FP32"}); - resCPUParams.push_back(CPUSpecificParams{{ndhwc, x, x}, {ndhwc}, {"jit_sse42"}, "jit_sse42_FP32"}); - resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"jit_sse42"}, "jit_sse42_FP32"}); + resCPUParams.push_back(CPUSpecificParams{{nCdhw8c, x, x}, {nCdhw8c}, {"jit_sse42"}, "jit_sse42"}); + resCPUParams.push_back(CPUSpecificParams{{ndhwc, x, x}, {ndhwc}, {"jit_sse42"}, "jit_sse42"}); } else { - resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"ref"}, "ref_FP32"}); + resCPUParams.push_back(CPUSpecificParams{{ncdhw, x, x}, {ncdhw}, {"ref"}, "ref"}); } return resCPUParams; } @@ -356,7 +307,7 @@ const auto interpolateCasesLinearOnnx5D = ::testing::Combine( ::testing::ValuesIn(defaultScales5D)); const auto interpolateCasesNN5D = ::testing::Combine( - ::testing::Values(ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx), + ::testing::Values(ngraph::op::v4::Interpolate::InterpolateMode::nearest), ::testing::ValuesIn(shapeCalculationMode), ::testing::ValuesIn(coordinateTransformModes), ::testing::ValuesIn(defNearestModes), @@ -367,38 +318,37 @@ const auto interpolateCasesNN5D = ::testing::Combine( ::testing::ValuesIn(defaultAxes5D), ::testing::ValuesIn(defaultScales5D)); -// open when ref merged -// INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinearOnnx5D_Layout_Test, InterpolateLayerCPUTest, -// ::testing::Combine( -// ::testing::Combine( -// interpolateCasesLinearOnnx5D, -// ::testing::ValuesIn(netPrecisions), -// ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), -// ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), -// ::testing::Values(InferenceEngine::Layout::ANY), -// ::testing::Values(InferenceEngine::Layout::ANY), -// ::testing::Values(std::vector({1, 21, 4, 10, 10})), -// ::testing::Values(std::vector({1, 21, 5, 15, 15})), -// ::testing::Values(CommonTestUtils::DEVICE_CPU)), -// ::testing::Values(std::map {}), -// ::testing::ValuesIn(filterCPUInfoForDevice5D())), -// InterpolateLayerCPUTest::getTestCaseName); - -// INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN5D_Layout_Test, InterpolateLayerCPUTest, -// ::testing::Combine( -// ::testing::Combine( -// interpolateCasesNN5D, -// ::testing::ValuesIn(netPrecisions), -// ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), -// ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), -// ::testing::Values(InferenceEngine::Layout::ANY), -// ::testing::Values(InferenceEngine::Layout::ANY), -// ::testing::Values(std::vector({1, 21, 4, 10, 10})), -// ::testing::Values(std::vector({1, 21, 5, 15, 15})), -// ::testing::Values(CommonTestUtils::DEVICE_CPU)), -// ::testing::Values(std::map {}), -// ::testing::ValuesIn(filterCPUInfoForDevice5D())), -// InterpolateLayerCPUTest::getTestCaseName); +INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinearOnnx5D_Layout_Test, InterpolateLayerCPUTest, + ::testing::Combine( + ::testing::Combine( + interpolateCasesLinearOnnx5D, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 21, 4, 10, 10})), + ::testing::Values(std::vector({1, 21, 5, 15, 15})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice5D()), + ::testing::ValuesIn(fusingParamsSet)), + InterpolateLayerCPUTest::getTestCaseName); + +INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN5D_Layout_Test, InterpolateLayerCPUTest, + ::testing::Combine( + ::testing::Combine( + interpolateCasesNN5D, + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({1, 21, 4, 10, 10})), + ::testing::Values(std::vector({1, 21, 5, 15, 15})), + ::testing::Values(CommonTestUtils::DEVICE_CPU)), + ::testing::ValuesIn(filterCPUInfoForDevice5D()), + ::testing::ValuesIn(fusingParamsSet)), + InterpolateLayerCPUTest::getTestCaseName); } // namespace