diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp index 181d0525f2db25..0fcac236356f90 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_exec_network.cpp @@ -421,7 +421,6 @@ bool MKLDNNExecNetwork::CanProcessDynBatch(const InferenceEngine::CNNNetwork &ne type != Split && type != Concatenation && type != Eltwise && - type != Crop && type != BatchNormalization && type != Copy) { check_result = false; diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp index a888d38a2ebc45..ebef14038577d8 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include #include #include "mkldnn_extension_utils.h" @@ -93,7 +93,6 @@ static const InferenceEngine::details::caseless_unordered_map { "Eltwise", Eltwise }, { "Mod", Eltwise }, { "Power", Eltwise }, - { "Crop", Crop }, { "Reshape", Reshape }, { "Tile", Tile }, { "SimplerNMS", SimplerNMS }, @@ -103,6 +102,7 @@ static const InferenceEngine::details::caseless_unordered_map { "Flatten", Flatten }, { "Pad", Pad }, { "Permute", Permute }, + { "StridedSlice", StridedSlice }, { "Copy", Copy }, { "LSTMCell", RNNCell }, { "GRUCell", RNNCell }, diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_node.h b/inference-engine/src/mkldnn_plugin/mkldnn_node.h index 83c45610cde678..4ed5daee429f20 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_node.h +++ b/inference-engine/src/mkldnn_plugin/mkldnn_node.h @@ -48,7 +48,6 @@ enum Type { Concatenation, Eltwise, Gemm, - Crop, Reshape, Tile, SimplerNMS, @@ -58,6 +57,7 @@ enum Type { Flatten, Pad, Permute, + StridedSlice, Copy, MemoryOutput, MemoryInput, @@ -122,8 +122,6 @@ static std::string NameFromType(Type type) { return "Concatenation"; case Depthwise: return "Depthwise"; - case Crop: - return "Crop"; case Reshape: return "Reshape"; case Tile: @@ -142,6 +140,8 @@ static std::string NameFromType(Type type) { return "Pad"; case Permute: return "Permute"; + case StridedSlice: + return "StridedSlice"; case Copy: return "Copy"; case MemoryOutput: diff --git a/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp b/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp index fcbcdb33423cc2..5dd4fa84f1dc48 100644 --- a/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp +++ b/inference-engine/src/mkldnn_plugin/mkldnn_plugin.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -333,6 +334,7 @@ static void Transformation(CNNNetwork& clonedNetwork, const Config& conf) { legacyManager.register_pass(); auto legacyPassConfig = legacyManager.get_pass_config(); + legacyPassConfig->disable(); legacyPassConfig->set_callback([](const_node_ptr &node) -> bool { return !MKLDNNQuantizeNode::isNeedToDecompose(node); diff --git a/inference-engine/src/mkldnn_plugin/nodes/list_tbl.hpp b/inference-engine/src/mkldnn_plugin/nodes/list_tbl.hpp index a40e5b57ab8710..12604eef081122 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/list_tbl.hpp +++ b/inference-engine/src/mkldnn_plugin/nodes/list_tbl.hpp @@ -41,7 +41,6 @@ MKLDNN_EXTENSION_NODE(ReverseSequenceImpl, ReverseSequence); MKLDNN_EXTENSION_NODE(DetectionOutputImpl, DetectionOutput); MKLDNN_EXTENSION_NODE(ArgMaxImpl, ArgMax); MKLDNN_EXTENSION_NODE(UnsqueezeImpl, Unsqueeze); -MKLDNN_EXTENSION_NODE(StridedSliceImpl, StridedSlice); MKLDNN_EXTENSION_NODE(ExperimentalDetectronDetectionOutputImpl, ExperimentalDetectronDetectionOutput); MKLDNN_EXTENSION_NODE(RegionYoloImpl, RegionYolo); MKLDNN_EXTENSION_NODE(LogSoftmaxImpl, LogSoftmax); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_crop_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_crop_node.cpp deleted file mode 100644 index 166461b4b0115d..00000000000000 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_crop_node.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "mkldnn_crop_node.h" -#include -#include -#include -#include -#include -#include "ie_parallel.hpp" -#include "common/cpu_memcpy.h" -#include "utils/general_utils.h" - -using namespace mkldnn; -using namespace MKLDNNPlugin; -using namespace InferenceEngine; - -MKLDNNCropNode::MKLDNNCropNode(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache) : - MKLDNNNode(layer, eng, cache) {} - -void MKLDNNCropNode::getSupportedDescriptors() { - CropLayer* cropLayer = dynamic_cast(getCnnLayer().get()); - - if (cropLayer == nullptr) - IE_THROW() << "Cannot convert crop layer."; - - channelAxis = 1; - if (getParentEdges().size() != 1 && getParentEdges().size() != 2) { - IE_THROW() << "Incorrect number of input edges for layer " << getName(); - } - - MKLDNNDims childDims = getChildEdgeAt(0)->getDims(); - - offsets.resize(static_cast(childDims.ndims())); // plus one dim for batch - dims.resize(static_cast(childDims.ndims())); // plus one dim for batch - for (int i = 0; i < childDims.ndims(); i++) - dims[i] = childDims[i]; - - for (int i = 0; i < cropLayer->axis.size(); i++) { - offsets[cropLayer->axis[i]] = cropLayer->offset[i]; - } - - if (cropLayer->axis.size() == dims.size()) { - for (size_t i = 0; i < cropLayer->axis.size(); i++) { - if (cropLayer->axis[i] == 1) { - channelAxis = static_cast(i); - break; - } - } - } - - if (!getChildEdges().size()) - IE_THROW() << "Incorrect number of output edges for layer " << getName(); -} - -void MKLDNNCropNode::initSupportedPrimitiveDescriptors() { - if (!supportedPrimitiveDescriptors.empty()) - return; - - InferenceEngine::Precision precision = getCnnLayer()->insData[0].lock()->getPrecision(); - auto inputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(precision); - precision = getCnnLayer()->outData[0]->getPrecision(); - auto outputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(precision); - if (inputDataType != outputDataType) { - outputDataType = inputDataType; // Crop doesn't convert precisions, only moves data - } - - auto& inDims = getParentEdgeAt(0)->getDims(); - if (inDims.ndims() != 2 && inDims.ndims() != 4 && inDims.ndims() != 5) { - IE_THROW() << "Crop supports only 2d, 4d and 5d blobs."; - } - - memory::format_tag fmt = memory::format_tag::undef; - switch (inDims.ndims()) { - case 2: fmt = memory::format_tag::nc; break; - case 4: fmt = memory::format_tag::nchw; break; - case 5: fmt = memory::format_tag::ncdhw; break; - } - - InferenceEngine::LayerConfig config; - config.dynBatchSupport = true; - config.inConfs.resize(getParentEdges().size()); - config.outConfs.resize(1); - for (size_t i = 0; i < getParentEdges().size(); i++) { - config.inConfs[i].inPlace = -1; - config.inConfs[i].constant = i != 0; - config.inConfs[i].desc = MKLDNNMemoryDesc(getParentEdgeAt(i)->getDims(), inputDataType, fmt); - } - config.outConfs[0].inPlace = -1; - config.outConfs[0].constant = false; - config.outConfs[0].desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, fmt); - - supportedPrimitiveDescriptors.emplace_back(config, impl_desc_type::unknown, fmt); - - if ((inDims.ndims() == 4 || inDims.ndims() == 5) && channelAxis >= 0 && dims[channelAxis] % 8 == 0) { - fmt = inDims.ndims() == 5 ? memory::format_tag::nCdhw8c : memory::format_tag::nChw8c; - config.inConfs[0].desc = MKLDNNMemoryDesc(getParentEdgeAt(0)->getDims(), inputDataType, fmt); - config.outConfs[0].desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, fmt); - supportedPrimitiveDescriptors.emplace_back(config, impl_desc_type::unknown, fmt); - if (dims[channelAxis] % 16 == 0) { - fmt = inDims.ndims() == 5 ? memory::format_tag::nCdhw16c : memory::format_tag::nChw16c; - config.inConfs[0].desc = MKLDNNMemoryDesc(getParentEdgeAt(0)->getDims(), inputDataType, fmt); - config.outConfs[0].desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, fmt); - supportedPrimitiveDescriptors.emplace_back(config, impl_desc_type::unknown, fmt); - } - } -} - -void MKLDNNCropNode::createPrimitive() { - auto& dstMemPtr = getChildEdgeAt(0)->getMemoryPtr(); - auto& srcMemPtr = getParentEdgeAt(0)->getMemoryPtr(); - if (!dstMemPtr || !dstMemPtr->GetPrimitivePtr()) - IE_THROW() << "Destination memory didn't allocate."; - if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr()) - IE_THROW() << "Input memory didn't allocate."; - if (getSelectedPrimitiveDescriptor() == nullptr) - IE_THROW() << "Preferable primitive descriptor is not set."; -} - -void MKLDNNCropNode::execute(mkldnn::stream strm) { - auto& parentMem = getParentEdgeAt(0)->getMemory(); - - int m_block_size = 1; - if (!parentMem.GetDesc().isPlainFormat()) { - const auto &desc = parentMem.GetDescriptor().data; - const auto &blk = desc.format_desc.blocking; - IE_ASSERT(desc.format_kind == dnnl_blocked && - blk.inner_nblks == 1 && - blk.inner_idxs[0] == 1); - m_block_size = blk.inner_blks[0]; - } - const int m_inner_dim = dims[dims.size() - 1] * m_block_size; - - const auto &dst_mem = getChildEdgeAt(0)->getMemory(); - - const int dst_ndims = dst_mem.GetDesc().getDims().ndims(); - - // TODO: Rewrite it in general case. For every tensor - // and rank, without using letter N,C,D,H,W - const int OFFSET_N = (dst_ndims > 0) ? offsets[0] : 0; - const int OFFSET_C = (dst_ndims > 1) ? offsets[1] : 0; - const int OFFSET_D = (dst_ndims > 4) ? offsets[offsets.size() - 3] : 0; - const int OFFSET_H = (dst_ndims > 2) ? offsets[offsets.size() - 2] : 0; - const int OFFSET_W = (dst_ndims > 3) ? offsets[offsets.size() - 1] : 0; - - // TODO: Check applicability of dyn_batch_lim in early steps. - // crop of batch dimension doesn't support dyn batch. - const int ON = (dst_ndims > 0) ? std::min(batchToProcess(), getChildEdgeAt(0)->getDims()[0]) : 1; - const int OC = (dst_ndims > 1) ? dims[1] : 1; - const int OD = (dst_ndims > 4) ? dims[dims.size() - 3] : 1; - const int OH = (dst_ndims > 2) ? dims[dims.size() - 2] : 1; - const int OW = (dst_ndims > 3) ? dims[dims.size() - 1] : 1; - - memory::dims src_dims = parentMem.GetDims(); - int src_ndims = static_cast(src_dims.size()); - - const int IC = (src_ndims > 1) ? rnd_up(src_dims[1], m_block_size) : 1; - const int ID = (src_ndims > 4) ? src_dims[src_dims.size() - 3] : 1; - const int IH = (src_ndims > 2) ? src_dims[src_dims.size() - 2] : 1; - const int IW = (src_ndims > 3) ? src_dims[src_dims.size() - 1] : 1; - - const size_t itemSize = parentMem.GetDesc().GetElementSize(); - - const auto *src_data = reinterpret_cast(parentMem.GetPtr()); - auto *dst_data = reinterpret_cast(getChildEdgeAt(0)->getMemory().GetPtr()); - - if (OD == 1 && OH == 1 && OW == 1 && ID == 1 && IH == 1 && IW == 1) { - parallel_for(ON, [&](int n) { - cpu_memcpy(dst_data + itemSize * n * OC, src_data + itemSize *((n+OFFSET_N)*IC + OFFSET_C), OC * itemSize); - }); - } else { - parallel_for2d(ON, (OC / m_block_size), [&](int n, int c) { - for (int d = 0; d < OD; ++d) { - int dst_ind = (n*OC + c*m_block_size)*OD*OH*OW + d*m_block_size*OH*OW; - - int src_ind = ((n+OFFSET_N)*IC + (c*m_block_size+OFFSET_C))*ID*IH*IW + - ((d+OFFSET_D)*IH*IW + OFFSET_H*IW + OFFSET_W)*m_block_size; - - for (int h = 0; h < OH; ++h) { - cpu_memcpy(dst_data + itemSize * dst_ind, src_data + itemSize * src_ind, m_inner_dim * itemSize); - - src_ind += IW * m_block_size; - dst_ind += OW * m_block_size; - } - } - }); - } -} - -bool MKLDNNCropNode::created() const { - return getType() == Crop; -} -REG_MKLDNN_PRIM_FOR(MKLDNNCropNode, Crop); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_crop_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_crop_node.h deleted file mode 100644 index 3c02b98180d40a..00000000000000 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_crop_node.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include -#include -#include -#include - -namespace MKLDNNPlugin { - -class MKLDNNCropNode : public MKLDNNNode { -public: - MKLDNNCropNode(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache); - ~MKLDNNCropNode() override = default; - - void getSupportedDescriptors() override; - void initSupportedPrimitiveDescriptors() override; - void createPrimitive() override; - void execute(mkldnn::stream strm) override; - bool created() const override; - bool canBeInPlace() const override { - return false; - } - -private: - int channelAxis = 1; - std::vector offsets; - std::vector dims; -}; - -} // namespace MKLDNNPlugin - diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_pad_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_pad_node.cpp index 3c9d9e141e55ae..27554f51237996 100644 --- a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_pad_node.cpp +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_pad_node.cpp @@ -239,10 +239,12 @@ static inline size_t parallel_init(size_t start, size_t nDims, const SizeVector& } static inline void parallel_step(size_t nDims, const SizeVector& dims, SizeVector& indexes) { - for (int j = nDims - 1; j >= 0; j--) { - indexes[j] = (indexes[j] + 1) % dims[j]; - if (indexes[j] != 0) - return; + for (int j = nDims - 1; j >= 0; --j) { + ++indexes[j]; + if (indexes[j] < dims[j]) + break; + else + indexes[j] = 0; } } diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp new file mode 100644 index 00000000000000..37cfc950b9cb8d --- /dev/null +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.cpp @@ -0,0 +1,609 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include "mkldnn_strided_slice_node.h" + +#include +#include + +#include +#include "ie_parallel.hpp" +#include "caseless.hpp" +#include "common/dnnl_thread.hpp" +#include "common/cpu_memcpy.h" +#include "common/tensor_desc_creator.h" +#include "utils/general_utils.h" + +#include +#include +#include +#include "caseless.hpp" + + +#define THROW_ERROR IE_THROW() << "StridedSlice layer with name '" << getName() << "' " + +using namespace mkldnn; +using namespace MKLDNNPlugin; +using namespace InferenceEngine; +using namespace InferenceEngine::details; + +static inline size_t parallel_init(size_t start, size_t nDims, const SizeVector& dims, SizeVector& indexes) { + for (int j = nDims - 1; j >= 0; j--) { + indexes[j] = start % dims[j]; + start = start / dims[j]; + } + return start; +} + +MKLDNNStridedSliceNode::MKLDNNStridedSliceNode(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache) : + MKLDNNNode(layer, eng, cache) {} + +void MKLDNNStridedSliceNode::getSupportedDescriptors() { + auto stridedSliceLayer = getCnnLayer(); + + if (stridedSliceLayer == nullptr) + THROW_ERROR << "cannot convert from CNN layer"; + + auto inData = stridedSliceLayer->insData[DATA_ID].lock(); + auto beginData = stridedSliceLayer->insData[BEGIN_ID].lock(); + auto endData = stridedSliceLayer->insData[END_ID].lock(); + if (!inData || !beginData || !endData) + THROW_ERROR << "has nullable input data"; + + params.parametersAreConstant = CaselessEq()(getParentEdgesAtPort(BEGIN_ID)[0]->getParent()->getCnnLayer()->type, "const") && + CaselessEq()(getParentEdgesAtPort(END_ID)[0]->getParent()->getCnnLayer()->type, "const"); + + const SizeVector srcDims = inData->getTensorDesc().getDims(); + const SizeVector dstDims = stridedSliceLayer->outData[0]->getTensorDesc().getDims(); + const size_t nSrcDims = srcDims.size(); + + if (getParentEdges().size() != 3 && getParentEdges().size() != 4) + THROW_ERROR << "has incorrect number of input edges"; + if (!getChildEdges().size()) + THROW_ERROR << "has incorrect number of output edges"; + + beginDims = beginData->getTensorDesc().getDims(); + if (beginDims.size() != 1) + THROW_ERROR << " should have begin vector with 1 dimension"; + + endDims = endData->getTensorDesc().getDims(); + if (endDims.size() != 1) + THROW_ERROR << "should have end vector with 1 dimension"; + if (beginDims[0] != endDims[0]) + THROW_ERROR << "should have begin vector with size equal to end vector size"; + + if (stridedSliceLayer->insData.size() > STRIDE_ID) { + auto strideData = stridedSliceLayer->insData[STRIDE_ID].lock(); + if (!strideData) + THROW_ERROR << "has nullable input data"; + if (!CaselessEq()(getParentEdgesAtPort(STRIDE_ID)[0]->getParent()->getCnnLayer()->type, "const")) + params.parametersAreConstant = false; + + strideDims = strideData->getTensorDesc().getDims(); + if (strideDims.size() > 1) + THROW_ERROR << "should have stride vector with 1 dimension"; + if (beginDims[0] != strideDims[0]) + THROW_ERROR << "should have stride vector with size equal to begin vector size"; + } + + auto createMask = [&](const char* maskName, std::vector& mask, const int bit = 0) { + mask = stridedSliceLayer->GetParamAsInts(maskName); + if (strcmp(maskName, "ellipsis_mask") != 0 || mask.size() == 0) { + for (size_t i = mask.size(); i < dstDims.size(); ++i) mask.push_back(bit); + } + }; + + createMask("begin_mask", beginMask, 1); + createMask("end_mask", endMask, 1); + createMask("new_axis_mask", newAxisMask); + createMask("shrink_axis_mask", shrinkAxisMask); + createMask("ellipsis_mask", ellipsisMask); + + int ellipsisMaskCounter = 0; + params.ellipsisPos1 = -1; + for (size_t i = 0; i < ellipsisMask.size(); i++) { + ellipsisMaskCounter += ellipsisMask[i]; + params.ellipsisPos1 = ellipsisMask[i] == 1 && params.ellipsisPos1 == -1 ? i : params.ellipsisPos1; + } + if (ellipsisMaskCounter > 1) + THROW_ERROR << "has incorrect 'Ellipsis_mask'. Only one non-zero bit is allowed"; + + int newAxis = std::accumulate(newAxisMask.begin(), newAxisMask.end(), 0); + int shrinkAxis = std::accumulate(shrinkAxisMask.begin(), shrinkAxisMask.end(), 0); + params.equalDims = newAxis == 0 && shrinkAxis == 0; + + if (params.parametersAreConstant) { + auto fillingInParameters = [&](std::vector ¶meter, const size_t type, const size_t size, const int value) { + auto parentLayer = getParentEdgesAtPort(type)[0]->getParent()->getCnnLayer(); + auto blob = parentLayer->blobs["custom"]; + if (blob->getTensorDesc().getPrecision() != Precision::I32) + THROW_ERROR << "supports only parameters input with precision I32"; + const int *ptr = blob->cbuffer().as() + blob->getTensorDesc().getBlockingDesc().getOffsetPadding(); + parameter.assign(ptr, ptr + size); + + if (ellipsisMaskCounter == 0 && size < dstDims.size()) { + for (size_t i = size; i < dstDims.size(); i++) parameter.push_back(value); + } + }; + + if (beginDims.size()) + fillingInParameters(begin, BEGIN_ID, beginDims[0], 0); + if (endDims.size()) + fillingInParameters(end, END_ID, endDims[0], 0); + if (strideDims.size()) + fillingInParameters(stride, STRIDE_ID, strideDims[0], 1); + + if (nSrcDims > 3 && params.equalDims && ellipsisMaskCounter == 1) + addHiddenDims(nSrcDims); + } +} + +void MKLDNNStridedSliceNode::addHiddenDims(const size_t nSrcDims) { + // all masks and input parameters are for planar layouts. So if we use blocked or per channel layout and + // there is ellipsis should to add default values in hidden dimensions to know real order of mask or parameter values + size_t afterDims = ellipsisMask.size() - params.ellipsisPos1 - 1; + size_t ellipsisPos2 = nSrcDims - afterDims - 1; + + auto addHiddenDims = [&](std::vector& data, const int bit = 0) { + std::vector temp; + for (size_t i = 0; i < params.ellipsisPos1; i++) + temp.push_back(data[i]); + for (size_t i = params.ellipsisPos1; i < ellipsisPos2 + 1; i++) + temp.push_back(bit); + for (size_t i = 1; i < nSrcDims - ellipsisPos2; i++) + temp.push_back(data[i + params.ellipsisPos1]); + data = temp; + }; + + addHiddenDims(begin); + addHiddenDims(end); + addHiddenDims(stride, 1); + addHiddenDims(beginMask); + addHiddenDims(endMask); + addHiddenDims(ellipsisMask); + addHiddenDims(newAxisMask); + addHiddenDims(shrinkAxisMask); +} + +void MKLDNNStridedSliceNode::initSupportedPrimitiveDescriptors() { + if (!supportedPrimitiveDescriptors.empty()) + return; + + const bool hasStrides = getParentEdges().size() > 3; + InferenceEngine::Precision dataPrecision = getCnnLayer()->insData[DATA_ID].lock()->getPrecision(); + InferenceEngine::Precision beginPrecision = getCnnLayer()->insData[BEGIN_ID].lock()->getPrecision(); + auto beginDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(beginPrecision); + InferenceEngine::Precision endPrecision = getCnnLayer()->insData[END_ID].lock()->getPrecision(); + auto endDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(endPrecision); + InferenceEngine::Precision stridePrecision; + if (hasStrides) + stridePrecision = getCnnLayer()->insData[STRIDE_ID].lock()->getPrecision(); + + auto srcDims = getParentEdgeAt(DATA_ID)->getDims(); + auto dstDims = getChildEdgeAt(0)->getDims(); + size_t nDims = srcDims.ndims(); + + InferenceEngine::LayerConfig config; + config.dynBatchSupport = false; + config.inConfs.resize(getParentEdges().size()); + config.inConfs[DATA_ID].inPlace = -1; + config.inConfs[BEGIN_ID].inPlace = -1; + config.inConfs[END_ID].inPlace = -1; + config.inConfs[DATA_ID].constant = false; + config.inConfs[BEGIN_ID].constant = true; + config.inConfs[END_ID].constant = true; + if (hasStrides) { + config.inConfs[STRIDE_ID].inPlace = -1; + config.inConfs[STRIDE_ID].constant = true; + } + config.outConfs.resize(1); + + std::vector supportedTypes; + if (nDims > 2 && params.equalDims) { + auto canUseBlocked = [=](const size_t blockSize) { + return srcDims[1] % blockSize == 0 && abs(stride[1]) == 1 && (begin[1] > srcDims[1] || begin[1] % blockSize == 0); + }; + + supportedTypes.push_back(TensorDescCreatorTypes::nspc); + if (canUseBlocked(8lu)) + supportedTypes.push_back(TensorDescCreatorTypes::nCsp8c); + if (canUseBlocked(16lu)) + supportedTypes.push_back(TensorDescCreatorTypes::nCsp16c); + } + supportedTypes.push_back(TensorDescCreatorTypes::ncsp); + auto creators = TensorDescCreator::getCommonCreators(); + auto range = TensorDescCreator::makeFilteredRange(creators, nDims, supportedTypes); + + for (auto itr = range.first; itr != range.second; ++itr) { + config.inConfs[0].desc = itr->second->createDesc(dataPrecision, getParentEdgeAt(DATA_ID)->getDims().ToSizeVector()); + config.inConfs[BEGIN_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(BEGIN_ID)->getDims(), beginDataType, mkldnn::memory::format_tag::x); + config.inConfs[END_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(END_ID)->getDims(), endDataType, mkldnn::memory::format_tag::x); + if (hasStrides) + config.inConfs[STRIDE_ID].desc = MKLDNNMemoryDesc(getParentEdgeAt(STRIDE_ID)->getDims(), + MKLDNNExtensionUtils::IEPrecisionToDataType(stridePrecision), + mkldnn::memory::format_tag::x); + + config.outConfs[0].desc = itr->second->createDesc(dataPrecision, getChildEdgeAt(DATA_ID)->getDims().ToSizeVector()); + supportedPrimitiveDescriptors.emplace_back(config, impl_desc_type::ref, MKLDNNMemoryDesc(config.outConfs.front().desc).getFormat()); + } +} + +void MKLDNNStridedSliceNode::createPrimitive() { + auto& dstMemPtr = getChildEdgeAt(0)->getMemoryPtr(); + auto& srcMemPtr = getParentEdgeAt(0)->getMemoryPtr(); + if (!dstMemPtr || !dstMemPtr->GetPrimitivePtr()) + THROW_ERROR << "has not allocated destination memory."; + if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr()) + THROW_ERROR << "has not allocated input memory."; + if (getSelectedPrimitiveDescriptor() == nullptr) + THROW_ERROR << "has unidentified preferable primitive descriptor."; + + auto srcBlockingDesc = getParentEdgeAt(DATA_ID)->getDesc().getBlockingDesc(); + auto dstBlockingDesc = getChildEdgeAt(0)->getDesc().getBlockingDesc(); + auto srcOrder = srcBlockingDesc.getOrder(); + params.srcDims = srcBlockingDesc.getBlockDims(); + params.dstDims = dstBlockingDesc.getBlockDims(); + params.dataSize = getSelectedPrimitiveDescriptor()->getConfig().inConfs[DATA_ID].desc.getPrecision().size(); + + if (params.parametersAreConstant) { + size_t realNDims = params.dstDims.size(); + if (!getParentEdgeAt(DATA_ID)->getMemory().GetDesc().isPlainFormat()) + orderParametersByLayouts(); + + SizeVector newSrcDims, newDstDims; + dimsNormalization(newSrcDims, newDstDims); + dimsGluing(realNDims, newSrcDims, newDstDims); + + if (params.dstDims.size() == 1 || params.nDimsForWork != 1) + indicesCalculation(); + } +} + +void MKLDNNStridedSliceNode::orderParametersByLayouts() { + const bool isPerChannelLayout = getParentEdgeAt(DATA_ID)->getMemory().GetDesc().isTailCFormat(); + const bool isBlockedLayout = getParentEdgeAt(DATA_ID)->getMemory().GetDesc().isBlockedCFormat(); + auto srcOrder = getParentEdgeAt(DATA_ID)->getDesc().getBlockingDesc().getOrder(); + + if (isBlockedLayout) { + const size_t blk = params.srcDims.back(); + begin[1] = begin[1] / blk; + end[1] = ceil(end[1] / static_cast(blk)); + begin.push_back(0); + end.push_back(0); + stride.push_back(1); + beginMask.push_back(0); + endMask.push_back(0); + ellipsisMask.push_back(0); + newAxisMask.push_back(0); + shrinkAxisMask.push_back(0); + } else if (isPerChannelLayout) { + auto sortByOrder = [&](std::vector& data) { + std::vector temp(srcOrder.size()); + for (size_t i = 0; i < srcOrder.size(); i++) + temp[i] = data[srcOrder[i]]; + data = temp; + }; + + sortByOrder(begin); + sortByOrder(end); + sortByOrder(stride); + sortByOrder(beginMask); + sortByOrder(endMask); + sortByOrder(ellipsisMask); + sortByOrder(newAxisMask); + sortByOrder(shrinkAxisMask); + } +} + +void MKLDNNStridedSliceNode::dimsNormalization(SizeVector& newSrcDims, SizeVector& newDstDims) { + // creating new src and dst dimensions and parameters of the same size using masks + // + // example 1: before srcDims = [5, 6, 8, 3, 2], begin = [1, 0], end = [4, 0], stride = [1, 1] + // beginMask = [0, 1], endMask = [0, 1], ellipsisMask = [1, 0], newAxisMas = [0, 0], shrinkAxisMask = [0, 0] + // after srcDims = [5, 6, 8, 3, 2], begin = [1, 0, 0, 0, 0], end = [4, 5, 7, 2, 1], stride = [1, 1, 1, 1, 1], dstDims = [4, 6, 8, 3, 2] + // + // example 2: before srcDims = [5, 6, 8, 3, 2], begin = [0, 3, 0, 0, 0], end = [0, 3, 0, 0, 0], stride = [1, 1, 1, 1, 1] + // beginMask = [1, 0, 1, 1, 1], endMask = [1, 0, 1, 1, 1], ellipsisMask = [0, 0, 0, 0, 0], newAxisMask = [0, 0, 0, 0, 0], + // shrinkAxisMask = [0, 1, 0, 0, 0] + // after srcDims = [5, 6, 8, 3, 2], begin = [0, 3, 0, 0, 0], end = [4, 3, 7, 2, 1], stride = [1, 1, 1, 1, 1], dstDims = [5, 1, 8, 3, 2] + // + // example 3: before srcDims = [5, 8, 3, 2], begin = [0, 0, 0, 0], end = [0, 0, 0, 0], stride = [1, 1, 1, 1] + // beginMask = [1, 0, 1, 1, 1], endMask = [1, 0, 1, 1, 1], ellipsisMask = [0, 0, 0, 0, 0], newAxisMask = [0, 1, 0, 0, 0], + // shrinkAxisMask = [0, 0, 0, 0, 0] + // after srcDims = [5, 1, 8, 3, 2], begin = [0, 0, 0, 0, 0], end = [4, 0, 7, 2, 1], stride = [1, 1, 1, 1, 1], dstDims = [5, 1, 8, 3, 2] + + auto clipping = [](int& idx, const int min, const int max) { + idx = (idx > min) ? idx : min; + idx = (idx < max) ? idx : (max - 1); + }; + + auto correcting = [](int& dim, const size_t shift) { + dim = dim >= 0 ? dim : shift + dim; + }; + + std::vector beginTemp; + std::vector endTemp; + std::vector strideTemp; + size_t srcIdx = 0; + for (size_t axis = 0; axis < begin.size(); ++axis) { + if (ellipsisMask[axis] == 1) { + int nNewAxisAfterEllipses = 0; + int nSrcAxisBeforeEllipses = 0; + for (size_t i = 0; i < axis; ++i) { + if (newAxisMask[i] != 1) + nSrcAxisBeforeEllipses++; + } + for (size_t i = axis + 1; i < begin.size(); ++i) { + if (newAxisMask[i] == 1) + nNewAxisAfterEllipses++; + } + + size_t nSrcAxisAfterEllipses = (begin.size() - axis - nNewAxisAfterEllipses - 1); + size_t nHiddenDims = params.srcDims.size() - nSrcAxisAfterEllipses - nSrcAxisBeforeEllipses; + for (size_t i = 0; i < nHiddenDims; ++i) { + newSrcDims.push_back(params.srcDims[srcIdx]); + newDstDims.push_back(params.srcDims[srcIdx]); + beginTemp.push_back(0); + endTemp.push_back(params.srcDims[srcIdx] - 1); + strideTemp.push_back(1); + + srcIdx++; + } + } else { + if (newAxisMask[axis] == 1) { + beginTemp.push_back(0); + endTemp.push_back(0); + strideTemp.push_back(1); + newSrcDims.push_back(1); + newDstDims.push_back(1); + } else if (shrinkAxisMask[axis] == 1) { + int b = beginMask[axis] == 1 ? begin[axis] : 0; + correcting(b, params.srcDims[srcIdx]); + clipping(b, 0, params.srcDims[srcIdx]); + beginTemp.push_back(b); + endTemp.push_back(b); + strideTemp.push_back(1); + newSrcDims.push_back(params.srcDims[srcIdx]); + newDstDims.push_back(1); + + srcIdx++; + } else { + int b = beginMask[axis] == 1 ? begin[axis] : (stride[axis] > 0 ? 0 : -1); + correcting(b, params.srcDims[srcIdx]); + clipping(b, 0, params.srcDims[srcIdx]); + + int e = endMask[axis] == 1 ? (stride[axis] > 0 ? end[axis] - 1 : end[axis] + 1) : + (stride[axis] > 0 ? -1 : 0); + correcting(e, params.srcDims[srcIdx]); + clipping(e, 0, params.srcDims[srcIdx]); + + beginTemp.push_back(b); + endTemp.push_back(e); + strideTemp.push_back(stride[axis]); + newSrcDims.push_back(params.srcDims[srcIdx]); + newDstDims.push_back(ceil(static_cast(abs(e - b) + 1) / static_cast(abs(strideTemp.back())))); + + srcIdx++; + } + } + } + + begin = beginTemp; + end = endTemp; + stride = strideTemp; + + params.dstDims = newDstDims; + params.srcDims = newSrcDims; + params.dstStrides.resize(newDstDims.size()); + params.srcStrides.resize(newSrcDims.size()); + params.dstStrides[params.dstStrides.size() - 1] = params.srcStrides[params.srcStrides.size() - 1] = 1; + for (int i = newDstDims.size() - 2; i >= 0; --i) { + params.dstStrides[i] = params.dstStrides[i + 1] * params.dstDims[i + 1]; + params.srcStrides[i] = params.srcStrides[i + 1] * params.srcDims[i + 1]; + } +} + +void MKLDNNStridedSliceNode::dimsGluing(const size_t realNDims, const SizeVector& newSrcDims, const SizeVector& newDstDims) { + // gluing of dimensions if there aren't begin, end and stride != 1 on this axis + // example: before gluing srcDims = [5, 6, 8, 3, 2], begin = [1, 0, 0, 0, 0], stride = [1, 1, 2, 1, 1], dstDims = [4, 6, 4, 3, 2] + // after gluing srcDims = [30, 8, 6], begin = [6, 0, 0], stride = [1, 2, 1], dstDims = [24, 4, 6] + + std::pair secondDim = { 0, begin.size() }; + SizeVector indexes(1, 0); + for (int idx = 0; idx < begin.size(); idx++) { + if (begin[idx] != 0 || end[idx] != params.srcDims[idx] - 1 || stride[idx] != 1) { + indexes.push_back(std::max(idx - 1, 0)); + indexes.push_back(stride[idx] == 1 ? idx : idx + 1); + + if (idx != 0 && secondDim.first == 0) + secondDim.first = idx; + else if (idx != 0 && secondDim.second == begin.size()) + secondDim.second = idx; + } + } + + if (indexes.back() < 2) { + indexes[indexes.size() - 1] = 1; + secondDim.first = 1; + } + + const size_t nGluingLastDims = params.dstStrides[std::max(static_cast(indexes.back() - 1), 0)]; + const bool vLastDim = indexes.back() < begin.size(); + indexes[indexes.size() - 1] = vLastDim ? indexes.back() : begin.size() - 1; + indexes.push_back(begin.size() - 1); + + for (int idx = indexes.size() - 1; idx >= 0; idx -= 2) { + if (indexes[idx - 1] < indexes[idx]) { + for (size_t jdx = indexes[idx]; jdx > indexes[idx - 1]; --jdx) { + params.dstDims[indexes[idx - 1]] *= params.dstDims[jdx]; + params.srcDims[indexes[idx - 1]] *= params.srcDims[jdx]; + params.dstStrides[indexes[idx - 1]] /= params.dstDims[jdx]; + params.srcStrides[indexes[idx - 1]] /= params.srcDims[jdx]; + + begin[indexes[idx - 1]] *= params.dstDims[jdx]; + } + const size_t beginShift = indexes[idx - 1] + 1; + const size_t endShift = indexes[idx] + 1; + + params.dstDims.erase(params.dstDims.begin() + beginShift, params.dstDims.begin() + endShift); + params.srcDims.erase(params.srcDims.begin() + beginShift, params.srcDims.begin() + endShift); + params.dstStrides.erase(params.dstStrides.begin() + beginShift, params.dstStrides.begin() + endShift); + params.srcStrides.erase(params.srcStrides.begin() + beginShift, params.srcStrides.begin() + endShift); + + begin.erase(begin.begin() + beginShift, begin.begin() + endShift); + stride.erase(stride.begin() + beginShift, stride.begin() + endShift); + } + } + + params.workAmount = params.dstDims[0] * params.dstStrides[0] / nGluingLastDims; + params.lastDstDim = nGluingLastDims * params.dataSize; + params.nDimsForWork = params.dstDims.size() - static_cast(vLastDim); + + if (params.nDimsForWork == 1 && realNDims > 2) { + const size_t realSrcDim = newSrcDims[secondDim.first]; + const size_t realDstDim = newDstDims[secondDim.first]; + + params.dstStrides.insert(params.dstStrides.begin() + 1, params.dstStrides[0] / realDstDim); + params.srcStrides.insert(params.srcStrides.begin() + 1, params.srcStrides[0] / realSrcDim); + + for (size_t idx = secondDim.first + 1; idx < secondDim.second; idx++) + begin[1] /= newDstDims[idx]; + + const size_t maxThreads = dnnl_get_max_threads(); + if (params.dstDims[0] < maxThreads) { + params.dstDims[1] /= realDstDim; + params.srcDims[1] /= realSrcDim; + params.dstDims.insert(params.dstDims.begin() + 1, realDstDim); + params.srcDims.insert(params.srcDims.begin() + 1, realSrcDim); + } + + if (params.dstDims.size() > 2) + params.lastDstDim /= newDstDims[secondDim.first]; + } +} + +void MKLDNNStridedSliceNode::indicesCalculation() { + // indices calculation before execution for the best performance + params.nThreads = dnnl_get_max_threads(); + params.srcIndices.resize(params.workAmount, 0); + params.dstIndices.resize(params.workAmount, 0); + + auto getSrcIdx = [this](const SizeVector& indexes){ + size_t srcIdx = 0; + for (int i = 0; i < params.nDimsForWork; ++i) + srcIdx += (begin[i] + indexes[i] * stride[i]) * params.srcStrides[i]; + return srcIdx * params.dataSize; + }; + + parallel_nt(params.nThreads, [&](const int ithr, const int nthr) { + size_t start = 0, end = 0; + SizeVector coords(params.nDimsForWork, 0); + splitter(params.workAmount, nthr, ithr, start, end); + parallel_init(start, params.nDimsForWork, params.dstDims, coords); + + size_t srcIdx = getSrcIdx(coords); + for (size_t j = start; j < end; ++j) { + params.dstIndices[j] = j * params.lastDstDim; + params.srcIndices[j] = srcIdx; + + bool out = false; + for (int k = params.nDimsForWork - 1; k >= 0; k--) { + coords[k]++; + if (coords[k] < params.dstDims[k]) { + srcIdx += stride[k] * params.srcStrides[k] * params.dataSize; + break; + } else { + coords[k] = 0; + out = true; + } + } + + if (out) + srcIdx = getSrcIdx(coords); + } + }); +} + +void MKLDNNStridedSliceNode::execute(mkldnn::stream strm) { + if (!params.parametersAreConstant) { + auto srcDims = getParentEdgeAt(DATA_ID)->getDims(); + auto dstDims = getChildEdgeAt(0)->getDims(); + const size_t ellipsisMaskCounter = std::accumulate(ellipsisMask.begin(), ellipsisMask.end(), 0); + + auto fillingInParameters = [&](std::vector ¶meter, const size_t type, const size_t size, const int value) { + const int *ptr = reinterpret_cast(this->getParentEdgeAt(type)->getMemoryPtr()->GetPtr()); + parameter.assign(ptr, ptr + size); + + if (ellipsisMaskCounter == 0 && size < dstDims.ndims()) { + for (size_t i = size; i < dstDims.ndims(); i++) parameter.push_back(value); + } + }; + + if (beginDims.size()) + fillingInParameters(begin, BEGIN_ID, beginDims[0], 0); + if (endDims.size()) + fillingInParameters(end, END_ID, endDims[0], 0); + if (strideDims.size()) + fillingInParameters(stride, STRIDE_ID, strideDims[0], 1); + + if (srcDims.ndims() > 3 && params.equalDims && ellipsisMaskCounter != 0) + addHiddenDims(srcDims.ndims()); + + if (!getParentEdgeAt(DATA_ID)->getMemory().GetDesc().isPlainFormat()) + orderParametersByLayouts(); + + SizeVector newSrcDims, newDstDims; + dimsNormalization(newSrcDims, newDstDims); + dimsGluing(dstDims.ndims(), newSrcDims, newDstDims); + + if (params.dstDims.size() == 1 || params.nDimsForWork != 1) + indicesCalculation(); + } + + if (params.dstDims.size() > 1 && params.nDimsForWork == 1) + stridedSliceV(); + else + stridedSlice(); +} + +void MKLDNNStridedSliceNode::stridedSliceV() { + const uint8_t* srcData = reinterpret_cast(this->getParentEdgeAt(DATA_ID)->getMemoryPtr()->GetPtr()) + + (begin[0] * params.srcStrides[0] + begin[1] * params.srcStrides[1]) * params.dataSize; + uint8_t* dstData = reinterpret_cast(this->getChildEdgeAt(0)->getMemoryPtr()->GetPtr()); + + const size_t dstIdx = params.dstStrides[0] * params.dataSize; + const size_t srcIdx = stride[0] * params.srcStrides[0] * params.dataSize; + const size_t dstShift = params.dstStrides[1] * params.dataSize; + const size_t srcShift = stride[1] * params.srcStrides[1] * params.dataSize; + + if (params.dstDims.size() > 2) { + parallel_for2d(params.dstDims[0], params.dstDims[1], [&](const size_t i, const size_t j) { + cpu_memcpy(&dstData[i * dstIdx + j * dstShift], &srcData[i * srcIdx + j * srcShift], params.lastDstDim); + }); + } else { + parallel_for(params.dstDims[0], [&](const size_t i) { + cpu_memcpy(&dstData[i * dstIdx], &srcData[i * srcIdx], params.lastDstDim); + }); + } +} + +void MKLDNNStridedSliceNode::stridedSlice() { + const uint8_t* srcData = reinterpret_cast(this->getParentEdgeAt(DATA_ID)->getMemoryPtr()->GetPtr()) + + (stride.back() == 1 && stride.size() > 1 ? begin[params.nDimsForWork] * params.srcStrides[params.nDimsForWork] * params.dataSize : 0); + uint8_t* dstData = reinterpret_cast(this->getChildEdgeAt(0)->getMemoryPtr()->GetPtr()); + + parallel_nt(params.nThreads, [&](const int ithr, const int nthr) { + size_t start = 0, end = 0; + splitter(params.workAmount, nthr, ithr, start, end); + + for (size_t iwork = start; iwork < end; ++iwork) + cpu_memcpy(&dstData[params.dstIndices[iwork]], &srcData[params.srcIndices[iwork]], params.lastDstDim); + }); +} + +bool MKLDNNStridedSliceNode::created() const { + return getType() == StridedSlice; +} + +REG_MKLDNN_PRIM_FOR(MKLDNNStridedSliceNode, StridedSlice); diff --git a/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h new file mode 100644 index 00000000000000..577757791ffa1b --- /dev/null +++ b/inference-engine/src/mkldnn_plugin/nodes/mkldnn_strided_slice_node.h @@ -0,0 +1,76 @@ +// Copyright (C) 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include +#include +#include +#include + +namespace MKLDNNPlugin { + +class MKLDNNStridedSliceNode : public MKLDNNNode { +public: + MKLDNNStridedSliceNode(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng, MKLDNNWeightsSharing::Ptr &cache); + ~MKLDNNStridedSliceNode() override = default; + + void getSupportedDescriptors() override; + void initSupportedPrimitiveDescriptors() override; + void createPrimitive() override; + void execute(mkldnn::stream strm) override; + bool created() const override; + bool canBeInPlace() const override { + return false; + } + +private: + void stridedSliceV(); + void stridedSlice(); + + void addHiddenDims(const size_t nSrcDims); + void orderParametersByLayouts(); + void dimsNormalization(InferenceEngine::SizeVector& newSrcDims, InferenceEngine::SizeVector& newDstDims); + void dimsGluing(const size_t realNDims, const InferenceEngine::SizeVector& newSrcDims, const InferenceEngine::SizeVector& newDstDims); + void indicesCalculation(); + + const size_t DATA_ID = 0; + const size_t BEGIN_ID = 1; + const size_t END_ID = 2; + const size_t STRIDE_ID = 3; + + std::vector begin; + std::vector end; + std::vector stride; + + std::vector beginMask; + std::vector endMask; + std::vector ellipsisMask; + std::vector newAxisMask; + std::vector shrinkAxisMask; + + InferenceEngine::SizeVector beginDims; + InferenceEngine::SizeVector endDims; + InferenceEngine::SizeVector strideDims; + + struct { + InferenceEngine::SizeVector srcDims; + InferenceEngine::SizeVector dstDims; + InferenceEngine::SizeVector srcStrides; + InferenceEngine::SizeVector dstStrides; + InferenceEngine::SizeVector srcIndices; + InferenceEngine::SizeVector dstIndices; + int ellipsisPos1 = -1; + int ellipsisPos2 = 0; + size_t nThreads = 0; + size_t nDimsForWork = 0; + size_t workAmount = 0; + size_t lastDstDim = 0; + size_t dataSize = 0; + bool equalDims = false; + bool parametersAreConstant = true; + } params; +}; + +} // namespace MKLDNNPlugin diff --git a/inference-engine/src/mkldnn_plugin/nodes/strided_slice.cpp b/inference-engine/src/mkldnn_plugin/nodes/strided_slice.cpp deleted file mode 100644 index a99a8454430dd5..00000000000000 --- a/inference-engine/src/mkldnn_plugin/nodes/strided_slice.cpp +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "base.hpp" - -#include -#include -#include -#include -#include -#include "ie_parallel.hpp" -#include "common/cpu_memcpy.h" - -namespace InferenceEngine { -namespace Extensions { -namespace Cpu { - -inline void clipping(int *idx, const int min, const int max) { - (*idx) = ((*idx) > min) ? (*idx) : min; - (*idx) = ((*idx) < max) ? (*idx) : (max - 1); - return; -} - -class StridedSliceImpl: public ExtLayerBase { -public: - explicit StridedSliceImpl(const CNNLayer* layer) { - try { - if (layer->insData.size() > 4 || layer->outData.size() != 1) - IE_THROW() << layer->name << " Incorrect number of input/output edges!"; - - src_dims = layer->insData[STRIDEDSLICE_DATA].lock()->getTensorDesc().getDims(); - - bounds_size = 0; - begin_dims = {}; - if (layer->insData.size() > 1) { - begin_dims = layer->insData[STRIDEDSLICE_BEGIN].lock()->getTensorDesc().getDims(); - if (begin_dims.size() > 1) - IE_THROW() << layer->name << " Begin vector should be 1 dimension"; - bounds_size = begin_dims[0]; - } - - if (layer->insData.size() > 2) { - end_dims = layer->insData[STRIDEDSLICE_END].lock()->getTensorDesc().getDims(); - if (end_dims.size() > 1) - IE_THROW() << layer->name << " End vector should be 1 dimension"; - if (begin_dims[0] != end_dims[0]) - IE_THROW() << layer->name << " Begin vector size should be equal end vectror size"; - } - - if (layer->insData.size() > 3) { - stride_dims = layer->insData[STRIDEDSLICE_STRIDE].lock()->getTensorDesc().getDims(); - if (stride_dims.size() > 1) - IE_THROW() << layer->name << " End vector should be 1 dimension"; - if (begin_dims[0] != stride_dims[0]) - IE_THROW() << layer->name << " Stride vector size should be equal begin vectror size"; - } - dst_dims = layer->outData[0]->getTensorDesc().getDims(); - - std::string::size_type i; - std::string begin_mask_str = layer->GetParamAsString("begin_mask", ""); - for (i = 0; i < begin_mask_str.size(); ++i) { - if (begin_mask_str[i] == '1') begin_mask.push_back(1); - else if (begin_mask_str[i] == '0') begin_mask.push_back(0); - } - for (; i < src_dims.size(); ++i) begin_mask.push_back(1); - - std::string end_mask_str = layer->GetParamAsString("end_mask", ""); - for (i = 0; i < end_mask_str.size(); ++i) { - if (end_mask_str[i] == '1') end_mask.push_back(1); - else if (end_mask_str[i] == '0') end_mask.push_back(0); - } - for (; i < src_dims.size(); ++i) end_mask.push_back(1); - - std::string ellipsis_mask_str = layer->GetParamAsString("ellipsis_mask", ""); - size_t ellipsis_mask_counter = 0; - for (i = 0; i < ellipsis_mask_str.size(); ++i) { - if (ellipsis_mask_str[i] == '1') { - ellipsis_mask_counter++; - ellipsis_mask.push_back(1); - } else if (ellipsis_mask_str[i] == '0') { - ellipsis_mask.push_back(0); - } - } - if (ellipsis_mask_counter > 1) - IE_THROW() << layer->name << " 'Ellipsis_mask' must be a power of two (only one ellipsis)!"; - for (; i < src_dims.size(); ++i) ellipsis_mask.push_back(0); - - std::string new_axis_mask_str = layer->GetParamAsString("new_axis_mask", ""); - for (i = 0; i < new_axis_mask_str.size(); ++i) { - if (new_axis_mask_str[i] == '1') new_axis_mask.push_back(1); - else if (new_axis_mask_str[i] == '0') new_axis_mask.push_back(0); - } - for (; i < src_dims.size(); ++i) new_axis_mask.push_back(0); - - std::string shrink_axis_mask_str = layer->GetParamAsString("shrink_axis_mask", ""); - for (i = 0; i < shrink_axis_mask_str.size(); ++i) { - if (shrink_axis_mask_str[i] == '1') shrink_axis_mask.push_back(1); - else if (shrink_axis_mask_str[i] == '0') shrink_axis_mask.push_back(0); - } - for (; i < src_dims.size(); ++i) shrink_axis_mask.push_back(0); - - - int new_axis = 0; - for (auto& na : new_axis_mask) - new_axis += na; - - shrink_axis = 0; - for (auto& sa : shrink_axis_mask) - shrink_axis += sa; - max_dims = src_dims.size() + new_axis; - - // ellipsis_mask must be a power of two (only one ellipsis), so to take a first position - ellipsis_pos1 = ellipsis_pos2 = max_dims; - for (i = 0; i < ellipsis_mask.size(); i++) { - if (ellipsis_mask[i] > 0) { - ellipsis_pos1 = i; - break; - } - } - bounds_size -= ellipsis_pos1; - if (bounds_size > 0 && (max_dims - bounds_size) > ellipsis_pos1) - ellipsis_pos2 = max_dims - bounds_size; - - begin_dms.assign(max_dims, 0); - end_dms.assign(max_dims, -1); - stride_dms.assign(max_dims, 1); - - srcStrides = layer->insData[STRIDEDSLICE_DATA].lock()->getTensorDesc().getBlockingDesc().getStrides(); - dstStrides = layer->outData[0]->getTensorDesc().getBlockingDesc().getStrides(); - Precision dataPrecision = layer->insData[STRIDEDSLICE_DATA].lock()->getTensorDesc().getPrecision(); - if (layer->insData.size() == 1) { - addConfig(layer, { DataConfigurator(ConfLayout::PLN, dataPrecision) }, { DataConfigurator(ConfLayout::PLN, dataPrecision) }); - } else if (layer->insData.size() == 2) { - addConfig(layer, { DataConfigurator(ConfLayout::PLN, dataPrecision), DataConfigurator(ConfLayout::PLN, Precision::I32) }, - { DataConfigurator(ConfLayout::PLN, dataPrecision) }); - } else if (layer->insData.size() == 3) { - addConfig(layer, { DataConfigurator(ConfLayout::PLN, dataPrecision), DataConfigurator(ConfLayout::PLN, Precision::I32), - DataConfigurator(ConfLayout::PLN, Precision::I32) }, { DataConfigurator(ConfLayout::PLN, dataPrecision) }); - } else { - addConfig(layer, { DataConfigurator(ConfLayout::PLN, dataPrecision), DataConfigurator(ConfLayout::PLN, Precision::I32), - DataConfigurator(ConfLayout::PLN, Precision::I32), DataConfigurator(ConfLayout::PLN, Precision::I32) }, - { DataConfigurator(ConfLayout::PLN, dataPrecision) }); - } - } catch (InferenceEngine::Exception &ex) { - errorMsg = ex.what(); - } - } - - StatusCode execute(std::vector& inputs, std::vector& outputs, ResponseDesc *resp) noexcept override { - int *begin = nullptr, *end = nullptr, *stride = nullptr; - if (begin_dims.size()) - begin = inputs[STRIDEDSLICE_BEGIN]->cbuffer().as() + inputs[STRIDEDSLICE_BEGIN]->getTensorDesc().getBlockingDesc().getOffsetPadding(); - if (end_dims.size()) - end = inputs[STRIDEDSLICE_END]->cbuffer().as() + inputs[STRIDEDSLICE_END]->getTensorDesc().getBlockingDesc().getOffsetPadding(); - if (stride_dims.size()) - stride = inputs[STRIDEDSLICE_STRIDE]->cbuffer().as() + inputs[STRIDEDSLICE_STRIDE]->getTensorDesc().getBlockingDesc().getOffsetPadding(); - - InferenceEngine::SizeVector src_dims = inputs[STRIDEDSLICE_DATA]->getTensorDesc().getDims(); - InferenceEngine::SizeVector srcStrides = inputs[STRIDEDSLICE_DATA]->getTensorDesc().getBlockingDesc().getStrides(); - InferenceEngine::SizeVector dst_dims = outputs[0]->getTensorDesc().getDims(); - InferenceEngine::SizeVector dstStrides = outputs[0]->getTensorDesc().getBlockingDesc().getStrides(); - - size_t i, j, k, bj, ej, sj; - InferenceEngine::SizeVector our_dims; - InferenceEngine::SizeVector out_dims; - for (i = 0, j = 0, k = 0, bj = 0, ej = 0, sj = 0; static_cast(i) < max_dims; i++) { - if (static_cast(i) >= ellipsis_pos1 && - static_cast(i) < ellipsis_pos2) { - if (new_axis_mask.size() > i && new_axis_mask[i] == 1) - end_dms[i] = 0; - else - end_dms[i] = end_dms[i] >= 0 ? end_dms[i] : src_dims[j++] + end_dms[i]; - - out_dims.push_back(static_cast(ceil(static_cast(abs(end_dms[i] - begin_dms[i]) + 1) / static_cast(abs(stride_dms[i]))))); - our_dims.push_back(static_cast(ceil(static_cast(abs(end_dms[i] - begin_dms[i]) + 1) / static_cast(abs(stride_dms[i]))))); - k = ellipsis_pos1; - } else { - stride_dms[i] = (stride != nullptr && stride_dims[0] > sj && stride[sj] != 0) ? stride[sj++] : 1; - - if (begin_mask.size() > j && begin_mask[j] == 0) - begin_dms[i] = stride_dms[i] > 0 ? 0 : -1; - else - begin_dms[i] = (begin != nullptr && begin_dims[0] > bj) ? begin[bj] : (stride_dms[i] > 0 ? 0 : -1); - bj++; - begin_dms[i] = begin_dms[i] >= 0 ? begin_dms[i] : src_dims[j] + begin_dms[i]; - // Clipping 'begin' - clipping(&begin_dms[i], 0, src_dims[j]); - - if (end_mask.size() > j && end_mask[j] == 0) { - end_dms[i] = stride_dms[i] > 0 ? -1 : 0; - } else { - int end_dms_tmp = (end != nullptr && end_dims[0] > ej) ? (stride_dms[i] > 0 ? end[ej] - 1 : end[ej] + 1) - : end_dms[i]; - end_dms[i] = (end != nullptr && end_dims[0] > ej) ? end_dms_tmp : (stride_dms[i] > 0 ? -1 : 0); - } - ej++; - end_dms[i] = end_dms[i] >= 0 ? end_dms[i] : src_dims[j] + end_dms[i]; - // Clipping 'end' - clipping(&end_dms[i], 0, src_dims[j]); - - if (new_axis_mask.size() > i && new_axis_mask[i] == 1) - end_dms[i] = 0; - else - j++; - - if (shrink_axis_mask.size() > k && shrink_axis_mask[k] == 1) - end_dms[i] = begin_dms[i]; - else - out_dims.push_back(static_cast(ceil(static_cast(abs(end_dms[i] - begin_dms[i]) + 1) / - static_cast(abs(stride_dms[i]))))); - - our_dims.push_back(static_cast(ceil(static_cast(abs(end_dms[i] - begin_dms[i]) + 1) / - static_cast(abs(stride_dms[i]))))); - k++; - } - } - - for (i = 0; i < (std::min)(out_dims.size(), dst_dims.size()); i++) { - if (out_dims[i] != dst_dims[i]) - return PARAMETER_MISMATCH; - } - - const size_t inputsPrecSize = inputs[STRIDEDSLICE_DATA]->getTensorDesc().getPrecision().size(); - if (static_cast(src_dims.size()) == max_dims && shrink_axis == 0 && - stride_dms[stride_dms.size()-1] == 1 && stride_dms.size() > 1) { - if (inputsPrecSize != outputs[0]->getTensorDesc().getPrecision().size()) { - if (resp) { - std::string errorMsg = "StridedSlice layer doesn't support 'Data' input precision: " - + std::string(inputs[STRIDEDSLICE_DATA]->getTensorDesc().getPrecision().name()); - errorMsg.copy(resp->msg, sizeof(resp->msg) - 1); - } - return GENERAL_ERROR; - } - strided_slice_vp(inputs[STRIDEDSLICE_DATA], outputs[0]); - } else if (static_cast(src_dims.size()) == max_dims && shrink_axis == 0) { - switch (inputsPrecSize) { - case 1: { strided_slice_p(inputs[STRIDEDSLICE_DATA], outputs[0]); break; } - case 2: { strided_slice_p(inputs[STRIDEDSLICE_DATA], outputs[0]); break; } - case 4: { strided_slice_p(inputs[STRIDEDSLICE_DATA], outputs[0]); break; } - case 8: { strided_slice_p(inputs[STRIDEDSLICE_DATA], outputs[0]); break; } - default: { - if (resp) { - std::string errorMsg = "StridedSlice layer doesn't support 'Data' input precision: " - + std::string(inputs[STRIDEDSLICE_DATA]->getTensorDesc().getPrecision().name()); - errorMsg.copy(resp->msg, sizeof(resp->msg) - 1); - } - return GENERAL_ERROR; - } - } - } else { - switch (inputsPrecSize) { - case 1: { strided_slice(inputs[STRIDEDSLICE_DATA], outputs[0], our_dims); break; } - case 2: { strided_slice(inputs[STRIDEDSLICE_DATA], outputs[0], our_dims); break; } - case 4: { strided_slice(inputs[STRIDEDSLICE_DATA], outputs[0], our_dims); break; } - case 8: { strided_slice(inputs[STRIDEDSLICE_DATA], outputs[0], our_dims); break; } - default: { - if (resp) { - std::string errorMsg = "StridedSlice layer doesn't support 'Data' input precision: " - + std::string(inputs[STRIDEDSLICE_DATA]->getTensorDesc().getPrecision().name()); - errorMsg.copy(resp->msg, sizeof(resp->msg) - 1); - } - return GENERAL_ERROR; - } - } - } - - return OK; - } - -private: - const size_t STRIDEDSLICE_DATA = 0; - const size_t STRIDEDSLICE_BEGIN = 1; - const size_t STRIDEDSLICE_END = 2; - const size_t STRIDEDSLICE_STRIDE = 3; - - template - void strided_slice(Blob::Ptr&, Blob::Ptr& dst_data, std::vector &dims); - void strided_slice_vp(Blob::Ptr&, Blob::Ptr& dst_data); - template - void strided_slice_p(Blob::Ptr&, Blob::Ptr& dst_data); - - SizeVector begin_dims; - SizeVector end_dims; - SizeVector stride_dims; - - SizeVector begin_mask; - SizeVector end_mask; - SizeVector ellipsis_mask; - SizeVector new_axis_mask; - SizeVector shrink_axis_mask; - int shrink_axis; - - SizeVector src_dims; - SizeVector dst_dims; - std::vector begin_dms; - std::vector end_dms; - std::vector stride_dms; - SizeVector srcStrides; - SizeVector dstStrides; - int bounds_size; - int max_dims; - int ellipsis_pos1, ellipsis_pos2; -}; - -template -void StridedSliceImpl::strided_slice(Blob::Ptr& input, Blob::Ptr& output, std::vector &dims) { - auto* src_data = input->cbuffer().as() + input->getTensorDesc().getBlockingDesc().getOffsetPadding(); - auto* dst_data = output->buffer().as() + output->getTensorDesc().getBlockingDesc().getOffsetPadding(); - auto dst_size = output->byteSize(); - memset(dst_data, 0, dst_size); - - size_t work_amount_dst = dstStrides[0] * dst_dims[0]; - parallel_nt(0, [&](const int ithr, const int nthr) { - int j; - size_t i, start = 0, end = 0; - SizeVector counters(max_dims, 0); - splitter(work_amount_dst, nthr, ithr, start, end); - for (j = max_dims - 1, i = start; j >= 0; j--) { - counters[j] = i % dims[j]; - i /= dims[j]; - } - for (size_t iwork = start; iwork < end; ++iwork) { - int src_idx = 0; - for (i = 0, j = 0; static_cast(i) < max_dims; ++i) { - if (!(new_axis_mask.size() > i && new_axis_mask[i] == 1)) - src_idx += (begin_dms[i] + counters[i] * stride_dms[i]) * srcStrides[j++]; - } - - dst_data[iwork] = src_data[src_idx]; - - for (j = max_dims - 1; j >= 0; j--) { - counters[j]++; - if (counters[j] < dims[j]) - break; - else - counters[j] = 0; - } - } - }); -} - -void StridedSliceImpl::strided_slice_vp(Blob::Ptr& input, Blob::Ptr& output) { - size_t dataSize = input->getTensorDesc().getPrecision().size(); - const uint8_t* src_data = input->cbuffer().as() + input->getTensorDesc().getBlockingDesc().getOffsetPadding() * dataSize; - uint8_t* dst_data = output->buffer().as() + output->getTensorDesc().getBlockingDesc().getOffsetPadding() * dataSize; - auto dst_size = output->byteSize(); - memset(dst_data, 0, dst_size); - - // Vectorized copy - size_t dims_size_1 = dst_dims.size() - 1; - size_t len = dst_dims[dims_size_1] * dataSize; - size_t work_amount_dst = dstStrides[0] * dst_dims[0] / dst_dims[dims_size_1]; - - parallel_nt(0, [&](const int ithr, const int nthr) { - size_t start = 0, end = 0; - SizeVector counters(dims_size_1, 0); - splitter(work_amount_dst, nthr, ithr, start, end); - size_t src_idx = begin_dms[dims_size_1]; - for (int j = dims_size_1 - 1, i = start; j >= 0; j--) { - counters[j] = i % dst_dims[j]; - src_idx += (begin_dms[j] + counters[j] * stride_dms[j]) * srcStrides[j]; - i /= dst_dims[j]; - } - - for (size_t iwork = start, dst_idx = start * len, i = 1; iwork < end; ++iwork, dst_idx += len) { - cpu_memcpy(&dst_data[dst_idx], &src_data[src_idx * dataSize], len); - for (int j = dims_size_1 - 1; j >= 0; j--) { - counters[j]++; - if (counters[j] < dst_dims[j]) { - src_idx += stride_dms[j] * srcStrides[j]; - break; - } else { - counters[j] = i = 0; - } - } - if (!i) { - for (src_idx = begin_dms[dims_size_1]; i < dims_size_1; ++i) - src_idx += (begin_dms[i] + counters[i] * stride_dms[i]) * srcStrides[i]; - } - } - }); -} - -template -void StridedSliceImpl::strided_slice_p(Blob::Ptr& input, Blob::Ptr& output) { - auto* src_data = input->cbuffer().as() + input->getTensorDesc().getBlockingDesc().getOffsetPadding(); - auto* dst_data = output->buffer().as() + output->getTensorDesc().getBlockingDesc().getOffsetPadding(); - auto dst_size = output->byteSize(); - memset(dst_data, 0, dst_size); - - size_t dims_size = dst_dims.size(); - size_t work_amount_dst = dstStrides[0] * dst_dims[0]; - - parallel_nt(0, [&](const int ithr, const int nthr) { - size_t start = 0, end = 0; - SizeVector counters(dims_size, 0); - splitter(work_amount_dst, nthr, ithr, start, end); - int src_idx = 0; - for (int j = dims_size - 1, i = start; j >= 0; j--) { - counters[j] = i % dst_dims[j]; - src_idx += (begin_dms[j] + counters[j] * stride_dms[j]) * srcStrides[j]; - i /= dst_dims[j]; - } - - for (size_t iwork = start, dst_idx = start, i = 1; iwork < end; ++iwork, dst_idx++) { - dst_data[dst_idx] = src_data[src_idx]; - for (int j = dims_size - 1; j >= 0; j--) { - counters[j]++; - if (counters[j] < dst_dims[j]) { - src_idx += stride_dms[j] * srcStrides[j]; - break; - } else { - counters[j] = i = 0; - } - } - if (!i) { - for (src_idx = 0; i < dims_size; ++i) - src_idx += (begin_dms[i] + counters[i] * stride_dms[i]) * srcStrides[i]; - } - } - }); -} - -REG_FACTORY_FOR(StridedSliceImpl, StridedSlice); - -} // namespace Cpu -} // namespace Extensions -} // namespace InferenceEngine diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/strided_slice.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/strided_slice.cpp index 401e5360eb15f1..01fb2ff0051bd3 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/strided_slice.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/strided_slice.cpp @@ -12,19 +12,27 @@ using namespace LayerTestsDefinitions; namespace { std::vector ss_only_test_cases = { + StridedSliceSpecificParams{ { 16 }, { 4 }, { 12 }, { 1 }, + { 0 }, { 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 16 }, { 0 }, { 8 }, { 2 }, + { 1 }, { 0 }, { }, { }, { } }, StridedSliceSpecificParams{ { 128, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 1, 1, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 128, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 1, 1, 1}, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 1, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + StridedSliceSpecificParams{ { 2, 3 }, { 1, 0 }, { 2, 3 }, { 1, 1 }, + { 0, 0 }, { 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 10, 3 }, { 0, 0 }, { 20, 20 }, { 1, 1 }, + { 0, 1 }, { 0, 1 }, { }, { }, { } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, -1, 0 }, { 0, 0, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 9, 0 }, { 0, 11, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 1, 0 }, { 0, -1, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, - StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 9, 0 }, { 0, 7, 0 }, { -1, -1, -1 }, + StridedSliceSpecificParams{ { 2, 12, 100 }, { 0, 9, 0 }, { 0, 7, 0 }, { -1, -1, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, - StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 7, 0 }, { 0, 9, 0 }, { -1, 1, -1 }, + StridedSliceSpecificParams{ { 2, 12, 100 }, { 0, 7, 0 }, { 0, 9, 0 }, { -1, 1, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 4, 0 }, { 0, 9, 0 }, { -1, 2, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, @@ -32,34 +40,72 @@ std::vector ss_only_test_cases = { { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 9, 0 }, { 0, 4, 0 }, { -1, -2, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, - StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 10, 0 }, { 0, 4, 0 }, { -1, -2, -1 }, + StridedSliceSpecificParams{ { 2, 12, 100 }, { 0, 10, 0 }, { 0, 4, 0 }, { -1, -2, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, 11, 0 }, { 0, 0, 0 }, { -1, -2, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100 }, { 0, -6, 0 }, { 0, -8, 0 }, { -1, -2, -1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + StridedSliceSpecificParams{ { 20, 10, 5 }, { 0, 0, 0 }, { 3, 10, 0 }, { 1, 1, 1 }, + { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, + StridedSliceSpecificParams{ { 1, 10, 20 }, { 0, 0, 2 }, { 0, 0, 1000 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 1, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 10, 10 }, { 0, 1, 0 }, { 0, 1000, 0 }, { 1, 1, 1 }, + { 1, 0, 1 }, { 1, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 10, 4 }, { 0, 0, 0 }, { 0, 0, 2 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 1, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 10, 4 }, { 0, 0, 2 }, { 0, 0, 1000 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 1, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 10, 2 }, { 0, 0, 0 }, { 0, 0, 1 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 1, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 10, 2 }, { 0, 0, 0 }, { 1000, 0, 0 }, { 1, 1, 1 }, + { 0, 1, 1 }, { 0, 1, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 10, 2 }, { 0, 0, 0 }, { 0, 1000, 0 }, { 1, 1, 1 }, + { 1, 0, 1 }, { 1, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 20, 10, 5 }, { 0, 3 }, { 0, 4 }, { 1, 1 }, + { 1, 0 }, { 1, 0 }, { }, { }, { 1, 0 } }, + StridedSliceSpecificParams{ { 20, 10, 5 }, { 0, 0 }, { 0, -1 }, { 1, 1 }, + { 1, 0 }, { 1, 0 }, { }, { }, { 1, 0 } }, StridedSliceSpecificParams{ { 1, 12, 100, 1, 1 }, { 0, -1, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 1, 0, 1, 0 }, { 1, 0, 1, 0 }, { }, { 0, 1, 0, 1 }, {} }, StridedSliceSpecificParams{ { 2, 2, 2, 2 }, { 0, 0, 0, 0 }, { 2, 2, 2, 2 }, { 1, 1, 1, 1 }, - {1, 1, 1, 1}, {1, 1, 1, 1}, {}, {}, {} }, + { 1, 1, 1, 1}, { 1, 1, 1, 1}, {}, {}, {} }, + StridedSliceSpecificParams{ { 2, 2, 2, 2 }, { 0, 0 }, { 2, 2 }, { 1, 1 }, + { 1, 1 }, { 1, 1 }, {}, {}, {} }, + StridedSliceSpecificParams{ { 2, 2, 3, 3 }, { 0, -2, -2 }, { 2, -1, -1 }, { 1, 1, 1 }, + { 1, 0 }, { 1, 0 }, {}, {}, {} }, StridedSliceSpecificParams{ { 2, 2, 2, 2 }, { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 1, 1, 1, 1 }, - {0, 0, 0, 0}, {1, 1, 1, 1}, {}, {}, {} }, + { 0, 0, 0, 0}, { 1, 1, 1, 1}, {}, {}, {} }, StridedSliceSpecificParams{ { 2, 2, 2, 2 }, { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 1, 1, 1, 1 }, - {0, 0, 0, 0}, {0, 0, 0, 0}, {}, {}, {} }, + { 0, 0, 0, 0}, { 0, 0, 0, 0}, {}, {}, {} }, + StridedSliceSpecificParams{ { 1, 2, 6, 4 }, { 0, 0, 4, 0 }, { 1, 2, 6, 4 }, { 1, 1, 1, 1 }, + {}, {}, {}, {}, {} }, + StridedSliceSpecificParams{ { 1, 2, 6, 4 }, { 0, 0, -3, 0 }, { 1, 2, 6, 4 }, { 1, 1, 1, 1 }, + {}, {}, {}, {}, {} }, + StridedSliceSpecificParams{ { 1, 2, 6, 4 }, { 0, 0, 4, 0 }, { 1, 2, 6, 4 }, { 1, 1, 1, 1 }, + { 1, 1, 0, 1}, { 1, 1, 1, 1}, {}, {}, {} }, + StridedSliceSpecificParams{ { 10, 2, 2, 2 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 2, 1, 1, 1 }, + { 1, 1, 1, 1}, { 1, 1, 1, 1}, {}, {}, {} }, StridedSliceSpecificParams{ { 2, 2, 4, 3 }, { 0, 0, 0, 0 }, { 2, 2, 4, 3 }, { 1, 1, 2, 1 }, - {1, 1, 1, 1}, {1, 1, 1, 1}, {}, {}, {} }, + { 1, 1, 1, 1}, { 1, 1, 1, 1}, {}, {}, {} }, StridedSliceSpecificParams{ { 2, 2, 4, 2 }, { 1, 0, 0, 1 }, { 2, 2, 4, 2 }, { 1, 1, 2, 1 }, - {0, 1, 1, 0}, {1, 1, 0, 0}, {}, {}, {} }, + { 0, 1, 1, 0}, { 1, 1, 0, 0}, {}, {}, {} }, StridedSliceSpecificParams{ { 1, 2, 4, 2 }, { 1, 0, 0, 0 }, { 1, 2, 4, 2 }, { 1, 1, -2, -1 }, - {1, 1, 1, 1}, {1, 1, 1, 1}, {}, {}, {} }, + { 1, 1, 1, 1}, { 1, 1, 1, 1}, {}, {}, {} }, StridedSliceSpecificParams{ { 2, 2, 4, 2 }, { 1, 0, 0, 0 }, { 1, 2, 4, 2 }, { 1, 1, -2, -1 }, - {0, 1, 1, 1}, {1, 1, 1, 1}, {}, {}, {} }, + { 0, 1, 1, 1}, { 1, 1, 1, 1}, {}, {}, {} }, StridedSliceSpecificParams{ { 2, 3, 4, 5, 6 }, { 0, 1, 0, 0, 0 }, { 2, 3, 4, 5, 6 }, { 1, 1, 1, 1, 1 }, - {1, 0, 1, 1, 1}, {1, 0, 1, 1, 1}, {}, {0, 1, 0, 0, 0}, {} }, + { 1, 0, 1, 1, 1}, { 1, 0, 1, 1, 1}, {}, { 0, 1, 0, 0, 0}, {} }, StridedSliceSpecificParams{ { 10, 12 }, { -1, 1 }, { -9999, 0 }, { -1, 1 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, StridedSliceSpecificParams{ { 5, 5, 5, 5 }, { -1, 0, -1, 0 }, { -50, 0, -60, 0 }, { -1, 1, -1, 1 }, - { 0, 0, 0, 0 }, { 0, 1, 0, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, + { 0, 0, 0, 0 }, { 0, 1, 0, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, + StridedSliceSpecificParams{ { 1, 2, 4 }, { 0, 2000, 3, 5 }, { 0, 0, 0, 2 }, { 1, 1, 1, 1 }, + { 1, 0, 1, 1 }, { 1, 0, 1, 0 }, { 0, 1, 0, 0 }, { }, { } }, + StridedSliceSpecificParams{ { 2, 2, 4, 4 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 2, 0 }, { 1, 1, 1, 1, 1 }, + { 1, 1, 1, 0, 1 }, { 1, 1, 1, 0, 1 }, { 0, 1, 0, 0, 0 }, { }, { } }, + StridedSliceSpecificParams{ { 2, 2, 2, 4, 4 }, { 0, 0, 0, 1, 0 }, { 0, 0, 0, 2, 0 }, { 1, 1, 1, 1, 1 }, + { 1, 1, 1, 0, 1 }, { 1, 1, 1, 0, 1 }, { }, { 0, 1, 0, 0, 0 }, { } }, }; INSTANTIATE_TEST_CASE_P( @@ -75,4 +121,4 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values(std::map())), StridedSliceLayerTest::getTestCaseName); -} // namespace \ No newline at end of file +} // namespace diff --git a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/crop.cpp b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/crop.cpp deleted file mode 100644 index 5bf5d795c8060a..00000000000000 --- a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/crop.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include -#include "ngraph_functions/builders.hpp" -#include "test_utils/cpu_test_utils.hpp" - -// Given that the ngraph opset does not contain crop operation, we use the StridedSlice operation instead, since it is mapped to the Crop node if certain -// conditions are met. - -using namespace InferenceEngine; -using namespace CPUTestUtils; -using namespace LayerTestsDefinitions; - -namespace CPULayerTestsDefinitions { - -typedef std::tuple< - StridedSliceSpecificParams, - InferenceEngine::Precision, // Net precision - std::string, // Device name - std::map, // Additional network configuration - CPUSpecificParams> CropLayerCPUTestParamSet; - -class CropLayerCPUTest : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon, public CPUTestsBase { -public: - static std::string getTestCaseName(testing::TestParamInfo obj) { - StridedSliceSpecificParams params; - InferenceEngine::Precision netPrc; - std::string targetName; - std::map additionalConfig; - CPUSpecificParams cpuParams; - std::tie(params, netPrc, targetName, additionalConfig, cpuParams) = obj.param; - - std::ostringstream result; - result << "inShape=" << CommonTestUtils::vec2str(params.inputShape) << "_"; - result << "netPRC=" << netPrc.name() << "_"; - result << "begin=" << CommonTestUtils::vec2str(params.begin) << "_"; - result << "end=" << CommonTestUtils::vec2str(params.end) << "_"; - result << "stride=" << CommonTestUtils::vec2str(params.strides) << "_"; - result << "begin_m=" << CommonTestUtils::vec2str(params.beginMask) << "_"; - result << "end_m=" << CommonTestUtils::vec2str(params.endMask) << "_"; - if (!params.newAxisMask.empty()) { - result << "new_axis_m=" << (params.newAxisMask.empty() ? "def" : CommonTestUtils::vec2str(params.newAxisMask)) << "_"; - } - if (!params.shrinkAxisMask.empty()) { - result << "shrink_m=" << (params.shrinkAxisMask.empty() ? "def" : CommonTestUtils::vec2str(params.shrinkAxisMask)) << "_"; - } - if (!params.ellipsisAxisMask.empty()) { - result << "ellipsis_m=" << (params.ellipsisAxisMask.empty() ? "def" : CommonTestUtils::vec2str(params.ellipsisAxisMask)) << "_"; - } - result << "trgDev=" << targetName; - result << CPUTestsBase::getTestCaseName(cpuParams); - - return result.str(); - } -protected: - void SetUp() override { - StridedSliceSpecificParams ssParams; - InferenceEngine::Precision netPrecision; - std::map additionalConfig; - CPUSpecificParams cpuParams; - std::tie(ssParams, netPrecision, targetDevice, additionalConfig, cpuParams) = this->GetParam(); - inPrc = outPrc = netPrecision; // because crop does not convert Precisions, but only moves the data - std::tie(inFmts, outFmts, priority, selectedType) = cpuParams; - configuration.insert(additionalConfig.begin(), additionalConfig.end()); - - auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); - auto params = ngraph::builder::makeParams(ngPrc, {ssParams.inputShape}); - auto paramOuts = ngraph::helpers::convert2OutputVector( - ngraph::helpers::castOps2Nodes(params)); - auto ss = ngraph::builder::makeStridedSlice(paramOuts[0], ssParams.begin, ssParams.end, ssParams.strides, ngPrc, ssParams.beginMask, - ssParams.endMask, ssParams.newAxisMask, ssParams.shrinkAxisMask, ssParams.ellipsisAxisMask); - - selectedType = std::string("unknown_") + inPrc.name(); - - ss->get_rt_info() = getCPUInfo(); - - ngraph::ResultVector results{std::make_shared(ss)}; - function = std::make_shared(results, params, "StridedSlice"); - } -}; - -TEST_P(CropLayerCPUTest, CompareWithRefs) { - SKIP_IF_CURRENT_TEST_IS_DISABLED() - - Run(); - CheckPluginRelatedResults(executableNetwork, "Crop"); -} - -namespace { -const std::map additional_config; - -const std::vector netPrc = {Precision::BF16, Precision::FP32}; - -const std::vector testCasesPlain2D = {StridedSliceSpecificParams{ { 32, 32 }, { 0, 20 }, { 32, 30 }, { 1, 1 }, - { 0, 0 }, { 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 32, 20 }, { 2, 10 }, { 32, 20 }, { 1, 1 }, - { 0, 0 }, { 0, 0 }, { }, { }, { } } }; - -const auto CropParamsPlain2D = ::testing::Combine( - ::testing::ValuesIn(testCasesPlain2D), - ::testing::ValuesIn(netPrc), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(emptyCPUSpec)); - -INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Plain_2D, CropLayerCPUTest, CropParamsPlain2D, CropLayerCPUTest::getTestCaseName); - -const std::vector testCasesPlain4D = { - StridedSliceSpecificParams{ { 1, 5, 32, 32 }, { 0, 2, 5, 4 }, { 1, 4, 28, 27 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 1, 5, 32, 32 }, { 0, 0, 20, 20 }, { 1, 5, 25, 25 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 1, 5, 32, 32 }, { 0, 0, 0, 20 }, { 1, 5, 32, 30 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 1, 5, 32, 20 }, { 0, 0, 2, 10 }, { 1, 5, 32, 20 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } } -}; - -std::vector cpuParams_4D = { - CPUSpecificParams({nChw16c}, {nChw16c}, {}, {}), - CPUSpecificParams({nchw}, {nchw}, {}, {}) -}; - -const auto CropParamsPlain4D = ::testing::Combine( - ::testing::ValuesIn(testCasesPlain4D), - ::testing::ValuesIn(netPrc), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(cpuParams_4D.at(1))); - -INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Plain_4D, CropLayerCPUTest, CropParamsPlain4D, CropLayerCPUTest::getTestCaseName); - -const std::vector testCasesBlocked4D = { - StridedSliceSpecificParams{ { 1, 16, 32, 32 }, { 0, 0, 20, 20 }, { 1, 16, 25, 25 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 1, 32, 32, 32 }, { 0, 0, 0, 20 }, { 1, 16, 32, 30 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, -}; - -const auto CropParamsBlocked4D = ::testing::Combine( - ::testing::ValuesIn(testCasesBlocked4D), - ::testing::ValuesIn(netPrc), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config), - ::testing::Values(filterCPUSpecificParams(cpuParams_4D).front())); - -INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Blocked_4D, CropLayerCPUTest, CropParamsBlocked4D, CropLayerCPUTest::getTestCaseName); - -const std::vector testCasesPlain4DynBatch = { - StridedSliceSpecificParams{ { 10, 5, 32, 32 }, { 0, 2, 5, 4 }, { 1, 4, 28, 27 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 10, 5, 32, 32 }, { 0, 0, 20, 20 }, { 1, 5, 25, 25 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 10, 5, 32, 32 }, { 0, 0, 0, 20 }, { 1, 5, 32, 30 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, - StridedSliceSpecificParams{ { 10, 5, 32, 20 }, { 0, 0, 2, 10 }, { 1, 5, 32, 20 }, { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } } -}; - -std::map additional_config_dyn_batch = {{PluginConfigParams::KEY_ENFORCE_BF16, PluginConfigParams::NO}, - {PluginConfigParams::KEY_DYN_BATCH_ENABLED, PluginConfigParams::YES}}; - -const auto CropParamsPlain4DynBatch = ::testing::Combine( - ::testing::ValuesIn(testCasesPlain4DynBatch), - ::testing::ValuesIn(netPrc), - ::testing::Values(CommonTestUtils::DEVICE_CPU), - ::testing::Values(additional_config_dyn_batch), - ::testing::Values(cpuParams_4D.at(1))); - -INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Blocked_4DynBatch, CropLayerCPUTest, CropParamsPlain4DynBatch, CropLayerCPUTest::getTestCaseName); -} // namespace -} // namespace CPULayerTestsDefinitions - diff --git a/inference-engine/tests/functional/plugin/cpu/single_layer_tests/strided_slice.cpp b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/strided_slice.cpp new file mode 100644 index 00000000000000..c4746897552ef2 --- /dev/null +++ b/inference-engine/tests/functional/plugin/cpu/single_layer_tests/strided_slice.cpp @@ -0,0 +1,304 @@ +// Copyright (C) 2020-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include "ngraph_functions/builders.hpp" +#include "test_utils/cpu_test_utils.hpp" + + +using namespace InferenceEngine; +using namespace CPUTestUtils; +using namespace LayerTestsDefinitions; + +namespace CPULayerTestsDefinitions { + +typedef std::tuple< + StridedSliceSpecificParams, + InferenceEngine::Precision, // Net precision + std::string, // Device name + std::map, // Additional network configuration + CPUSpecificParams> StridedSliceLayerCPUTestParamSet; + +class StridedSliceLayerCPUTest : public testing::WithParamInterface, + virtual public LayerTestsUtils::LayerTestsCommon, public CPUTestsBase { +public: + static std::string getTestCaseName(testing::TestParamInfo obj) { + StridedSliceSpecificParams params; + InferenceEngine::Precision netPrc; + std::string targetName; + std::map additionalConfig; + CPUSpecificParams cpuParams; + std::tie(params, netPrc, targetName, additionalConfig, cpuParams) = obj.param; + + std::ostringstream result; + result << "inShape=" << CommonTestUtils::vec2str(params.inputShape) << "_"; + result << "netPRC=" << netPrc.name() << "_"; + result << "begin=" << CommonTestUtils::vec2str(params.begin) << "_"; + result << "end=" << CommonTestUtils::vec2str(params.end) << "_"; + result << "stride=" << CommonTestUtils::vec2str(params.strides) << "_"; + result << "begin_m=" << CommonTestUtils::vec2str(params.beginMask) << "_"; + result << "end_m=" << CommonTestUtils::vec2str(params.endMask) << "_"; + result << "new_axis_m=" << (params.newAxisMask.empty() ? "def" : CommonTestUtils::vec2str(params.newAxisMask)) << "_"; + result << "shrink_m=" << (params.shrinkAxisMask.empty() ? "def" : CommonTestUtils::vec2str(params.shrinkAxisMask)) << "_"; + result << "ellipsis_m=" << (params.ellipsisAxisMask.empty() ? "def" : CommonTestUtils::vec2str(params.ellipsisAxisMask)) << "_"; + result << "trgDev=" << targetName; + result << CPUTestsBase::getTestCaseName(cpuParams); + + return result.str(); + } +protected: + void SetUp() override { + StridedSliceSpecificParams ssParams; + InferenceEngine::Precision netPrecision; + std::map additionalConfig; + CPUSpecificParams cpuParams; + std::tie(ssParams, netPrecision, targetDevice, additionalConfig, cpuParams) = this->GetParam(); + inPrc = outPrc = netPrecision; + std::tie(inFmts, outFmts, priority, selectedType) = cpuParams; + configuration.insert(additionalConfig.begin(), additionalConfig.end()); + + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + auto params = ngraph::builder::makeParams(ngPrc, {ssParams.inputShape}); + auto paramOuts = ngraph::helpers::convert2OutputVector( + ngraph::helpers::castOps2Nodes(params)); + auto ss = ngraph::builder::makeStridedSlice(paramOuts[0], ssParams.begin, ssParams.end, ssParams.strides, ngPrc, ssParams.beginMask, + ssParams.endMask, ssParams.newAxisMask, ssParams.shrinkAxisMask, ssParams.ellipsisAxisMask); + + selectedType = std::string("ref_") + inPrc.name(); + + ss->get_rt_info() = getCPUInfo(); + + ngraph::ResultVector results{std::make_shared(ss)}; + function = std::make_shared(results, params, "StridedSlice"); + } +}; + +TEST_P(StridedSliceLayerCPUTest, CompareWithRefs) { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + + Run(); + CheckPluginRelatedResults(executableNetwork, "StridedSlice"); +} + +namespace { + +const auto cpuParams_nChw16c = CPUSpecificParams {{nChw16c}, {nChw16c}, {}, {}}; +const auto cpuParams_nCdhw16c = CPUSpecificParams {{nCdhw16c}, {nCdhw16c}, {}, {}}; + +const auto cpuParams_nChw8c = CPUSpecificParams {{nChw8c}, {nChw8c}, {}, {}}; +const auto cpuParams_nCdhw8c = CPUSpecificParams {{nCdhw8c}, {nCdhw8c}, {}, {}}; + +const auto cpuParams_nhwc = CPUSpecificParams {{nhwc}, {nhwc}, {}, {}}; +const auto cpuParams_ndhwc = CPUSpecificParams {{ndhwc}, {ndhwc}, {}, {}}; + +const auto cpuParams_nchw = CPUSpecificParams {{nchw}, {nchw}, {}, {}}; +const auto cpuParams_ncdhw = CPUSpecificParams {{ncdhw}, {ncdhw}, {}, {}}; + +const std::map additional_config; + +const std::vector inputPrecisions = { + InferenceEngine::Precision::FP32, + InferenceEngine::Precision::BF16, + InferenceEngine::Precision::I8 +}; + +const std::vector testCasesPlain2D = { + StridedSliceSpecificParams{ { 32, 32 }, { 0, 20 }, { 32, 30 }, { 1, 1 }, + { 0, 0 }, { 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 32, 20 }, { 2, 10 }, { 32, 20 }, { 1, 1 }, + { 0, 0 }, { 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 32, 20 }, { 2, 10 }, { 32, 20 }, { 1, 2 }, + { 0, 1 }, { 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 32, 20 }, { 2, 10 }, { 32, 20 }, { 2, 1 }, + { 0, 0 }, { 1, 0 }, { }, { }, { } }, +}; + +const auto StridedSliceParamsPlain2D = ::testing::Combine( + ::testing::ValuesIn(testCasesPlain2D), + ::testing::ValuesIn(inputPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::Values(emptyCPUSpec)); + +INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Plain_2D, StridedSliceLayerCPUTest, StridedSliceParamsPlain2D, StridedSliceLayerCPUTest::getTestCaseName); + +const std::vector testCasesCommon4D = { + StridedSliceSpecificParams{ { 1, 5, 32, 32 }, { 0, 2, 5, 4 }, { 1, 4, 28, 27 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 32, 20 }, { 0, 1, 0, 0 }, { 1, 3, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 5, 32, 20 }, { 0, 0, 10, 0 }, { 1, 3, 20, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 32, 32 }, { 0, 0, 20, 20 }, { 1, 5, 25, 26 }, { 1, 1, 1, 2 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 5, 32, 32 }, { 0, 0, 0, 20 }, { 1, 2, 30, 30 }, { 1, 1, 2, 1 }, + { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 32, 20 }, { 0, 0, 2, 10 }, { 1, 3, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 1, 1 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 5, 32, 32 }, { 0, 1, 0, 10 }, { 1, 5, 32, 30 }, { 1, 1, 1, 1 }, + { 0, 1, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 32, 20 }, { 0, 1, 2, 10 }, { 1, 5, 32, 18 }, { 1, 1, 1, 2 }, + { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 8, 32, 20 }, { 0, 0, 2, 10 }, { 1, 8, 32, 18 }, { 1, 2, 1, 2 }, + { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 8, 32, 20 }, { 0, 0, 10 }, { 0, 32, 18 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 1, 1, 0 }, { }, { }, { 1, 0, 0 } }, + StridedSliceSpecificParams{ { 2, 8, 32, 20 }, { 0, 0, 10 }, { 1, 0, 20 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 0, 1, 1 }, { }, { }, { 0, 1, 0 } }, + StridedSliceSpecificParams{ { 2, 8, 32, 20 }, { 0, 4, 10 }, { 2, 8, 0 }, { 1, 1, 1 }, + { 1, 0, 1 }, { 1, 1, 1 }, { }, { }, { 0, 0, 1 } } +}; + +const std::vector CPUParamsCommon4D = { + cpuParams_nchw, + cpuParams_nhwc, +}; + +const auto StridedSliceParamsCommon4D = ::testing::Combine( + ::testing::ValuesIn(testCasesCommon4D), + ::testing::ValuesIn(inputPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParamsCommon4D)); + +INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Common_4D, StridedSliceLayerCPUTest, StridedSliceParamsCommon4D, StridedSliceLayerCPUTest::getTestCaseName); + +const std::vector testCasesBlocked4D = { + StridedSliceSpecificParams{ { 1, 16, 32, 32 }, { 0, 0, 5, 4 }, { 1, 16, 28, 27 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 10, 10 }, { 0, 16, 0, 0 }, { 1, 32, 10, 10 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 16, 32, 20 }, { 0, 0, 10, 0 }, { 1, 16, 20, 10 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 32, 32 }, { 0, 0, 20, 20 }, { 1, 32, 25, 25 }, { 1, 1, 1, 1 }, + { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 48, 32, 32 }, { 0, 16, 0, 20 }, { 1, 32, 32, 30 }, { 1, 1, 1, 2 }, + { 1, 0, 1, 0 }, { 1, 0, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 32, 20 }, { 0, 16, 2, 10 }, { 1, 32, 32, 20 }, { 1, 1, 2, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 32, 20 }, { 0, 16, 0, 0 }, { 2, 64, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 32, 20 }, { 0, 32, 0, 0 }, { 2, 50, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 32, 20 }, { 0, 0, 0, 0 }, { 2, 12, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 64, 32, 20 }, { 0, -16, 0, 10 }, { 2, 100, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 32, 20 }, { 0, -16, 0, 0 }, { 2, -4, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 32, 20 }, { 0, -32, 0, 0 }, { 2, -12, 32, 20 }, { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 32, 20 }, { 0, 10 }, { 0, 20 }, { 1, 1 }, + { 1, 0 }, { 1, 0 }, { }, { }, { 1, 0 } }, + StridedSliceSpecificParams{ { 2, 32, 32, 20 }, { 0, 16, 0 }, { 2, 32, 0 }, { 1, 1, 1 }, + { 1, 0, 1 }, { 1, 1, 1 }, { }, { }, { 0, 0, 1 } }, +}; + +const std::vector CPUParamsBlocked4D = { + cpuParams_nChw16c, + cpuParams_nChw8c, +}; + +const auto StridedSliceParamsBlocked4D = ::testing::Combine( + ::testing::ValuesIn(testCasesBlocked4D), + ::testing::ValuesIn(inputPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParamsBlocked4D)); + +INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Blocked_4D, StridedSliceLayerCPUTest, StridedSliceParamsBlocked4D, StridedSliceLayerCPUTest::getTestCaseName); + +const std::vector testCasesCommon5D = { + StridedSliceSpecificParams{ { 1, 5, 20, 32, 32 }, { 0, 2, 0, 5, 4 }, { 1, 4, 5, 28, 27 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 5, 20, 32, 20 }, { 0, 0, 10, 0, 0 }, { 1, 5, 20, 32, 20 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 20, 32, 20 }, { 0, 1, 10, 0, 0 }, { 1, 3, 20, 32, 20 }, { 1, 1, 1, 1, 1 }, + { 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 20, 32, 32 }, { 0, 0, 0, 20, 20 }, { 1, 5, 20, 30, 26 }, { 1, 1, 1, 2, 2 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 5, 20, 32, 32 }, { 0, 0, 10, 0, 20 }, { 1, 2, 20, 30, 30 }, { 1, 1, 2, 1, 1 }, + { 0, 0, 0, 0, 1 }, { 0, 1, 0, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 20, 32, 32 }, { 0, 0, 2, 10, 0 }, { 1, 5, 10, 32, 20 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 5, 20, 32, 32 }, { 0, 1, 0, 10, 0 }, { 1, 5, 20, 32, 32 }, { 1, 1, 1, 1, 1 }, + { 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 5, 20, 32, 32 }, { 0, 0, 0, 0, 0 }, { 1, 5, 10, 16, 16 }, { 1, 1, 2, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 8, 20, 32, 32 }, { 0, 2, 0, 0, 0 }, { 1, 8, 10, 16, 16 }, { 1, 2, 1, 1, 2 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 8, 20, 32, 32 }, { 0, 2, 0, 0, 16 }, { 2, 8, 20, 32, 32 }, { 1, 2, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 8, 10, 10, 10 }, { 0, 5 }, { 0, 10 }, { 1, 1 }, + { 1, 0 }, { 1, 0 }, { }, { }, { 1, 0 } }, + StridedSliceSpecificParams{ { 2, 8, 10, 10, 10 }, { 0, 0, 5 }, { 0, 0, 10 }, { 1, 1, 1 }, + { 1, 1, 0 }, { 1, 1, 0 }, { }, { }, { 0, 1, 0 } }, + StridedSliceSpecificParams{ { 2, 8, 10, 10, 10 }, { 0, 2, 0 }, { 2, 8, 0 }, { 1, 1, 1 }, + { 1, 0, 1 }, { 1, 1, 1 }, { }, { }, { 0, 0, 1 } } +}; + +const std::vector CPUParamsCommon5D = { + cpuParams_ncdhw, + cpuParams_ndhwc, +}; + +const auto StridedSliceParamsCommon5D = ::testing::Combine( + ::testing::ValuesIn(testCasesCommon5D), + ::testing::ValuesIn(inputPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParamsCommon5D)); + +INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Common_5D, StridedSliceLayerCPUTest, StridedSliceParamsCommon5D, StridedSliceLayerCPUTest::getTestCaseName); + +const std::vector testCasesBlocked5D = { + StridedSliceSpecificParams{ { 1, 16, 20, 32, 32 }, { 0, 0, 0, 5, 4 }, { 1, 16, 5, 28, 27 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 32, 20, 32, 20 }, { 0, 0, 10, 0, 0 }, { 1, 16, 20, 32, 20 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 16, 20, 32, 20 }, { 0, 0, 10, 0, 0 }, { 1, 16, 20, 32, 20 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 16, 20, 32, 32 }, { 0, 0, 0, 20, 20 }, { 1, 16, 20, 30, 26 }, { 1, 1, 1, 2, 2 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 16, 20, 32, 32 }, { 0, 0, 10, 0, 20 }, { 1, 16, 20, 30, 30 }, { 1, 1, 2, 1, 1 }, + { 0, 0, 0, 0, 1 }, { 0, 1, 0, 1, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 16, 20, 32, 32 }, { 0, 0, 2, 10, 0 }, { 1, 16, 10, 32, 20 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 1, 1, 0 }, { 0, 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 1, 16, 20, 32, 32 }, { 0, 0, 0, 10, 0 }, { 1, 8, 20, 32, 32 }, { 1, 1, 1, 1, 1 }, + { 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 16, 20, 32, 32 }, { 0, 0, 0, 0, 0 }, { 1, 16, 10, 16, 16 }, { 1, 1, 2, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 0, 0, 0, 0 }, { 1, 25, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 16, 0, 0, 0 }, { 1, 25, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 16, 0, 0, 0 }, { 1, 64, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 0, 0, 0, 0 }, { 2, 25, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 0, 0, 0, 0 }, { 2, 60, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 32, 0, 0, 0 }, { 2, 40, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceSpecificParams{ { 2, 64, 20, 10, 10 }, { 0, 16, 0, 0, 0 }, { 2, 64, 20, 10, 10 }, { 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { }, { }, { } } +}; + +const std::vector CPUParamsBlocked5D = { + cpuParams_nCdhw16c, + cpuParams_nCdhw8c, +}; + +const auto StridedSliceParamsBlocked5D = ::testing::Combine( + ::testing::ValuesIn(testCasesBlocked5D), + ::testing::ValuesIn(inputPrecisions), + ::testing::Values(CommonTestUtils::DEVICE_CPU), + ::testing::Values(additional_config), + ::testing::ValuesIn(CPUParamsBlocked5D)); + +INSTANTIATE_TEST_CASE_P(smoke_CompareWithRefs_Blocked_5D, StridedSliceLayerCPUTest, StridedSliceParamsBlocked5D, StridedSliceLayerCPUTest::getTestCaseName); + +} // namespace +} // namespace CPULayerTestsDefinitions + diff --git a/inference-engine/tests_deprecated/unit/engines/mkldnn/graph/layers/internal/graph_crop_test.cpp b/inference-engine/tests_deprecated/unit/engines/mkldnn/graph/layers/internal/graph_crop_test.cpp deleted file mode 100644 index 6d3769e1932342..00000000000000 --- a/inference-engine/tests_deprecated/unit/engines/mkldnn/graph/layers/internal/graph_crop_test.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (C) 2018-2021 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#include "test_graph.hpp" - -#include "single_layer_common.hpp" -#include "tests_common.hpp" - -#include -#include - -using namespace ::testing; -using namespace std; -using namespace mkldnn; - -struct crop_test_params { - InferenceEngine::SizeVector in; - std::vector axis; - std::vector offsets; - std::vector dims; - - size_t num_prim_desc; - - MKLDNNPlugin::impl_desc_type selectedType; - - std::vector> comp; -}; - - - -template -void ref_crop(InferenceEngine::TBlob &src, InferenceEngine::TBlob &dst, crop_test_params prm) { - data_t *dst_ptr = dst.data(); - - std::vector offsets(4, 0); - for (size_t i = 0; i < prm.offsets.size(); i++) { - offsets[prm.axis[i]] = prm.offsets[i]; - } - int OFFSET_N = offsets.at(0); - int OFFSET_C = offsets.at(1); - int OFFSET_H = offsets.at(2); - int OFFSET_W = offsets.at(3); - - auto dst_dims = dst.getTensorDesc().getDims(); - int dst_ndims = static_cast(dst_dims.size()); - const int ON = (dst_ndims > 0) ? dst_dims[0] : 1; - const int OC = (dst_ndims > 1) ? dst_dims[1] : 1; - const int OH = (dst_ndims > 2) ? dst_dims[2] : 1; - const int OW = (dst_ndims > 3) ? dst_dims[3] : 1; - - auto src_dims = src.getTensorDesc().getDims(); - int src_ndims = static_cast(src_dims.size()); - const int _IN = (src_ndims > 0) ? src_dims[0] : 1; - const int IC = (src_ndims > 1) ? src_dims[1] : 1; - const int IH = (src_ndims > 2) ? src_dims[2] : 1; - const int IW = (src_ndims > 3) ? src_dims[3] : 1; - - auto dst_off = [=](int n, int c, int h, int w) { - return (n * OW * OH * OC + c * OW * OH + h * OW + w); - }; - auto src_off = [=](int n, int c, int h, int w) { - return (n * IW * IH * IC + c * IW * IH + h * IW + w); - }; - - ASSERT_GE(_IN - OFFSET_N, ON); - ASSERT_GE(IC - OFFSET_C, OC); - ASSERT_GE(IH - OFFSET_H, OH); - ASSERT_GE(IW - OFFSET_W, OW); - - data_t* src_ptr = src.data(); - for (int n = 0; n < ON; ++n) { - for (int c = 0; c < OC; ++c) { - for (int h = 0; h < OH; ++h) { - for (int w = 0; w < OW; ++w) { - dst_ptr[dst_off(n, c, h, w)] = src_ptr[src_off(n + OFFSET_N, c + OFFSET_C, - h + OFFSET_H, w + OFFSET_W)]; - } - } - } - } -} - -class MKLDNNGraphCropTests: public TestsCommon, - public WithParamInterface { - std::string model_t = R"V0G0N( - - - - - - _IN_ - - - - - - - - _IN_ - - - - - _OUT_ - - - - - - - - -)V0G0N"; - -protected: - std::string getModel(crop_test_params p) { - std::string model = model_t; - std::string in_shape, out_shape; - - std::string axis, offset, dim; - InferenceEngine::SizeVector outDims = p.in; - for (size_t i = 0; i < p.offsets.size(); i++) { - if (!axis.empty()) - axis += ","; - axis += std::to_string(p.axis[i]); - if (!offset.empty()) - offset += ","; - offset += std::to_string(p.offsets[i]); - if (!dim.empty()) - dim += ","; - dim += std::to_string(p.dims[i]); - outDims[p.axis[i]] = p.dims[i]; - } - - for (size_t i = 0; i < p.in.size(); i++) { - in_shape += ""; - in_shape += std::to_string(p.in[i]) + "\n"; - } - REPLACE_WITH_STR(model, "_IN_", in_shape); - - for (size_t i = 0; i < outDims.size(); i++) { - out_shape += ""; - out_shape += std::to_string(outDims[i]) + "\n"; - } - REPLACE_WITH_STR(model, "_OUT_", out_shape); - - REPLACE_WITH_STR(model, "_AXC_", axis); - REPLACE_WITH_STR(model, "_OFC_", offset); - REPLACE_WITH_STR(model, "_DIMC_", dim); - return model; - } - - virtual void TearDown() { - } - - virtual void SetUp() { - try { - TestsCommon::SetUp(); - crop_test_params p = ::testing::WithParamInterface::GetParam(); - std::string model = getModel(p); - - InferenceEngine::Core core; - InferenceEngine::CNNNetwork network; - ASSERT_NO_THROW(network = core.ReadNetwork(model, InferenceEngine::Blob::CPtr())); - - MKLDNNGraphTestClass graph; - graph.CreateGraph(network); - - auto& nodes = graph.getNodes(); - for (int i = 0; i < nodes.size(); i++) { - if (nodes[i]->getType() == MKLDNNPlugin::Crop) { - ASSERT_EQ(p.num_prim_desc, nodes[i]->getSupportedPrimitiveDescriptors().size()); - for (size_t j = 0; j < p.num_prim_desc && j < p.comp.size(); j++) { - p.comp.at(j)(nodes[i]->getSupportedPrimitiveDescriptors().at(j)); - } - ASSERT_NE(nullptr, nodes[i]->getSelectedPrimitiveDescriptor()); - ASSERT_EQ(p.selectedType, nodes[i]->getSelectedPrimitiveDescriptor()->getImplementationType()); - } - } - - InferenceEngine::Blob::Ptr src = InferenceEngine::make_shared_blob({InferenceEngine::Precision::FP32, p.in, InferenceEngine::TensorDesc::getLayoutByDims(p.in) }); - src->allocate(); - fill_data(src->buffer(), src->size()); - - InferenceEngine::TBlob* srcPtr = dynamic_cast*>(src.get()); - - if (srcPtr == nullptr) - FAIL() << "Cannot cast blob to TBlob."; - - InferenceEngine::BlobMap srcs; - srcs.insert(std::pair("in1", src)); - - InferenceEngine::OutputsDataMap out; - out = network.getOutputsInfo(); - InferenceEngine::BlobMap outputBlobs; - - std::pair item = *out.begin(); - - InferenceEngine::TBlob::Ptr output; - output = InferenceEngine::make_shared_blob(item.second->getTensorDesc()); - output->allocate(); - outputBlobs[item.first] = output; - - graph.Infer(srcs, outputBlobs); - - InferenceEngine::TBlob dst_ref(item.second->getTensorDesc()); - dst_ref.allocate(); - - ref_crop(*srcPtr, dst_ref, p); - - compare(*output, dst_ref); - } catch (const InferenceEngine::Exception &e) { - FAIL() << e.what(); - } - } -}; - -TEST_P(MKLDNNGraphCropTests, TestCrop) {} - - -INSTANTIATE_TEST_CASE_P( - TestCrop, MKLDNNGraphCropTests, - ::testing::Values( - crop_test_params{{1, 5, 32, 32}, {1, 2, 3}, {2, 5, 4}, {2, 23, 23}, 1, MKLDNNPlugin::impl_desc_type::unknown, { - [](MKLDNNPlugin::PrimitiveDescInfo impl) { - ASSERT_EQ(MKLDNNPlugin::impl_desc_type::unknown, impl.getImplementationType()); - ASSERT_EQ(1, impl.getConfig().inConfs.size()); - ASSERT_EQ(1, impl.getConfig().outConfs.size()); - ASSERT_EQ(InferenceEngine::Layout::NCHW, impl.getConfig().inConfs.at(0).desc.getLayout()); - ASSERT_EQ(InferenceEngine::Layout::NCHW, impl.getConfig().outConfs.at(0).desc.getLayout()); - }}}, - crop_test_params{{3, 8, 32, 32}, {0, 1, 2, 3}, {1, 0, 20, 20}, {2, 8, 5, 5}, 2, MKLDNNPlugin::impl_desc_type::unknown, { - [](MKLDNNPlugin::PrimitiveDescInfo impl) { - ASSERT_EQ(MKLDNNPlugin::impl_desc_type::unknown, impl.getImplementationType()); - ASSERT_EQ(1, impl.getConfig().inConfs.size()); - ASSERT_EQ(1, impl.getConfig().outConfs.size()); - ASSERT_EQ(InferenceEngine::Layout::NCHW, impl.getConfig().inConfs.at(0).desc.getLayout()); - ASSERT_EQ(InferenceEngine::Layout::NCHW, impl.getConfig().outConfs.at(0).desc.getLayout()); - }} }, - crop_test_params{{1, 5, 32, 32}, {3}, {10}, {20}, 1, MKLDNNPlugin::impl_desc_type::unknown }, - crop_test_params{{1, 5, 32, 20}, {2, 3}, {30, 10}, {2, 10}, 1, MKLDNNPlugin::impl_desc_type::unknown }, - crop_test_params{ { 32, 32 },{ 1 },{ 10 },{ 20 }, 1, MKLDNNPlugin::impl_desc_type::unknown }, - crop_test_params{ { 32, 20 },{ 0, 1 },{ 30, 10 },{ 2, 10 }, 1, MKLDNNPlugin::impl_desc_type::unknown })); - -class MKLDNNGraphDynBatchCropTests: public MKLDNNGraphCropTests { -protected: - - virtual void SetUp() { - try { - TestsCommon::SetUp(); - crop_test_params p = ::testing::WithParamInterface::GetParam(); - std::string model = getModel(p); - size_t MB = p.in[0]; - if (MB < 2) - MB = 2; - - InferenceEngine::Core core; - InferenceEngine::CNNNetwork network; - ASSERT_NO_THROW(network = core.ReadNetwork(model, InferenceEngine::Blob::CPtr())); - network.setBatchSize(MB); - - MKLDNNGraphTestClass graph; - graph.setProperty({{InferenceEngine::PluginConfigParams::KEY_DYN_BATCH_ENABLED, InferenceEngine::PluginConfigParams::YES}}); - graph.CreateGraph(network); - - InferenceEngine::SizeVector dims_src = p.in; - dims_src[0] = MB; - InferenceEngine::Blob::Ptr src = InferenceEngine::make_shared_blob({InferenceEngine::Precision::FP32, dims_src, InferenceEngine::TensorDesc::getLayoutByDims(dims_src) }); - InferenceEngine::TBlob* srcPtr = dynamic_cast*>(src.get()); - if (srcPtr == nullptr) - FAIL() << "Cannot cast blob to TBlob."; - - src->allocate(); - fill_data(src->buffer(), src->size()); - - InferenceEngine::BlobMap srcs; - srcs.insert(std::pair("in1", src)); - - InferenceEngine::OutputsDataMap out; - out = network.getOutputsInfo(); - InferenceEngine::BlobMap outputBlobs; - - std::pair item = *out.begin(); - - InferenceEngine::TBlob::Ptr output; - output = InferenceEngine::make_shared_blob(item.second->getTensorDesc()); - output->allocate(); - outputBlobs[item.first] = output; - - auto checkCrop = [](const MKLDNNPlugin::MKLDNNNodePtr& node) { - return node->getType() == MKLDNNPlugin::Crop; - }; - - graph.checkDynBatch(srcs, outputBlobs, MB, MB, checkCrop); - graph.checkDynBatch(srcs, outputBlobs, 1, MB, checkCrop); - } catch (const InferenceEngine::Exception &e) { - FAIL() << e.what(); - } - } -}; - -TEST_P(MKLDNNGraphDynBatchCropTests, TestsDynBatchCrop) {} - -INSTANTIATE_TEST_CASE_P( - TestsDynBatchCrop, MKLDNNGraphDynBatchCropTests, - ::testing::Values( - crop_test_params{{1, 5, 32, 32}, {1, 2, 3}, {2, 5, 4}, {2, 23, 23}, 1, MKLDNNPlugin::impl_desc_type::unknown, { - [](MKLDNNPlugin::PrimitiveDescInfo impl) { - ASSERT_EQ(MKLDNNPlugin::impl_desc_type::unknown, impl.getImplementationType()); - ASSERT_EQ(1, impl.getConfig().inConfs.size()); - ASSERT_EQ(1, impl.getConfig().outConfs.size()); - ASSERT_EQ(InferenceEngine::Layout::NCHW, impl.getConfig().inConfs.at(0).desc.getLayout()); - ASSERT_EQ(InferenceEngine::Layout::NCHW, impl.getConfig().outConfs.at(0).desc.getLayout()); - }}}, - crop_test_params{{1, 5, 32, 32}, {3}, {10}, {20}, 1, MKLDNNPlugin::impl_desc_type::unknown }, - crop_test_params{{1, 5, 32, 20}, {2, 3}, {30, 10}, {2, 10}, 1, MKLDNNPlugin::impl_desc_type::unknown }));