mkldnn_input_node.cpp 4.75 KB
Newer Older
openvino-pushbot's avatar
openvino-pushbot committed
1 2 3 4 5 6 7 8
// Copyright (C) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//

#include "mkldnn_input_node.h"
#include "../mkldnn_extension_utils.h"
#include <string>
Alexey Suhov's avatar
Alexey Suhov committed
9
#include "details/caseless.hpp"
openvino-pushbot's avatar
openvino-pushbot committed
10 11 12

using namespace mkldnn;
using namespace MKLDNNPlugin;
Alexey Suhov's avatar
Alexey Suhov committed
13
using namespace InferenceEngine::details;
openvino-pushbot's avatar
openvino-pushbot committed
14 15 16 17 18 19

MKLDNNInputNode::MKLDNNInputNode(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng) : MKLDNNNode(layer, eng) {}

void MKLDNNInputNode::getSupportedDescriptors() {
    if (getType() == Input) {
        if (!getParentEdges().empty())
Alexey Suhov's avatar
Alexey Suhov committed
20
            THROW_IE_EXCEPTION << "Incorrect number of input edges for layer " << getName();
openvino-pushbot's avatar
openvino-pushbot committed
21
        if (getChildEdges().empty())
Alexey Suhov's avatar
Alexey Suhov committed
22
            THROW_IE_EXCEPTION << "Incorrect number of output edges for layer " << getName();
openvino-pushbot's avatar
openvino-pushbot committed
23 24
    } else if (getType() == Output) {
        if (getParentEdges().size() != 1)
Alexey Suhov's avatar
Alexey Suhov committed
25
            THROW_IE_EXCEPTION << "Incorrect number of input edges for layer " << getName();
openvino-pushbot's avatar
openvino-pushbot committed
26
        if (!getChildEdges().empty())
Alexey Suhov's avatar
Alexey Suhov committed
27
            THROW_IE_EXCEPTION << "Incorrect number of output edges for layer " << getName();
openvino-pushbot's avatar
openvino-pushbot committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
    }
    constant = ConstantType::NoConst;
    auto layer = getCnnLayer();
    if (layer && CaselessEq<std::string>()(layer->type, "const")) {
        constant = ConstantType::Const;
        if (layer->blobs.size() != 1 || getType() != Input || !layer->blobs.begin()->second)
            THROW_IE_EXCEPTION << "Incorrect const input " << getName();
        constBlob = layer->blobs.begin()->second;
    }
}

void MKLDNNInputNode::initSupportedPrimitiveDescriptors() {
    if (!supportedPrimitiveDescriptors.empty())
        return;

    InferenceEngine::LayerConfig config;
    config.dynBatchSupport = true;
    if (getType() == Input || getType() == MemoryInput) {
Alexey Suhov's avatar
Alexey Suhov committed
46
        InferenceEngine::Precision precision = getCnnLayer()->precision;
openvino-pushbot's avatar
openvino-pushbot committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        if (precision == InferenceEngine::Precision::U16 || isMeanImage)
            precision = InferenceEngine::Precision::FP32;
        auto outputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(precision);
        InferenceEngine::DataConfig dataConfig;
        dataConfig.inPlace = -1;
        dataConfig.constant = false;

        memory::format layout = MKLDNNMemory::Convert(getCnnLayer()->outData[0]->getLayout());
        dataConfig.desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, layout);
        config.outConfs.push_back(dataConfig);
    } else if (getType() == Output) {
        InferenceEngine::Precision precision = getCnnLayer()->insData[0].lock()->getPrecision();
        if (precision == InferenceEngine::Precision::U16) precision = InferenceEngine::Precision::FP32;
        auto inputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(precision);
        InferenceEngine::DataConfig dataConfig;
        dataConfig.inPlace = -1;
        dataConfig.constant = false;

        memory::format layout = MKLDNNMemory::Convert(getCnnLayer()->insData[0].lock()->getLayout());
        dataConfig.desc = MKLDNNMemoryDesc(getParentEdgeAt(0)->getDims(), inputDataType, layout);
        config.inConfs.push_back(dataConfig);
    }
    supportedPrimitiveDescriptors.emplace_back(config, impl_desc_type::unknown);
}

void MKLDNNInputNode::createPrimitive() {
    for (size_t i = 0; i < getChildEdges().size(); i++) {
        auto &dstMemPtr = getChildEdgeAt(i)->getMemoryPtr();
        if (!dstMemPtr || !dstMemPtr->GetPrimitivePtr())
            THROW_IE_EXCEPTION << "Destination memory didn't allocate for node " << getName()
                               << " to node " << getChildEdgeAt(i)->getChild()->getName() << ".";
    }
    for (size_t i = 0; i < getParentEdges().size(); i++) {
        auto &srcMemPtr = getParentEdgeAt(i)->getMemoryPtr();
        if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr())
            THROW_IE_EXCEPTION << "Destination memory didn't allocate for node " << getName()
                               << " from node " << getParentEdgeAt(i)->getParent()->getName() << ".";
    }

    const PrimitiveDescInfo *selected_pd = getSelectedPrimitiveDescriptor();
    if (selected_pd == nullptr)
        THROW_IE_EXCEPTION << "Preferable primitive descriptor does not set for node " << getName() << ".";
}

bool MKLDNNInputNode::created() const {
    return getType() == Input || getType() == Output;
}

void MKLDNNInputNode::execute(mkldnn::stream strm) {
    if (!constBlob)
        return;
    auto dstBlob = getChildEdgeAt(0)->getBlob();
    const float *srcData = constBlob->cbuffer().as<float *>();
    float *dstData = dstBlob->buffer();
    if (constBlob->size() != dstBlob->size()) {
        THROW_IE_EXCEPTION << "Incorrect blob sizes for node " << getName();
    }
    for (size_t i = 0; i < constBlob->size(); i++) {
        // srcData without offset() because constBlob should be planar
        dstData[dstBlob->getTensorDesc().offset(i)] = srcData[i];
    }
}