1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include "mkldnn_input_node.h"
6 #include "../mkldnn_extension_utils.h"
8 #include "details/caseless.hpp"
10 using namespace mkldnn;
11 using namespace MKLDNNPlugin;
12 using namespace InferenceEngine::details;
14 MKLDNNInputNode::MKLDNNInputNode(const InferenceEngine::CNNLayerPtr& layer, const mkldnn::engine& eng) : MKLDNNNode(layer, eng) {}
16 void MKLDNNInputNode::getSupportedDescriptors() {
17 if (getType() == Input) {
18 if (!getParentEdges().empty())
19 THROW_IE_EXCEPTION << "Incorrect number of input edges for layer " << getName();
20 if (getChildEdges().empty())
21 THROW_IE_EXCEPTION << "Incorrect number of output edges for layer " << getName();
22 } else if (getType() == Output) {
23 if (getParentEdges().size() != 1)
24 THROW_IE_EXCEPTION << "Incorrect number of input edges for layer " << getName();
25 if (!getChildEdges().empty())
26 THROW_IE_EXCEPTION << "Incorrect number of output edges for layer " << getName();
28 constant = ConstantType::NoConst;
29 auto layer = getCnnLayer();
30 if (layer && CaselessEq<std::string>()(layer->type, "const")) {
31 constant = ConstantType::Const;
32 if (layer->blobs.size() != 1 || getType() != Input || !layer->blobs.begin()->second)
33 THROW_IE_EXCEPTION << "Incorrect const input " << getName();
34 constBlob = layer->blobs.begin()->second;
38 void MKLDNNInputNode::initSupportedPrimitiveDescriptors() {
39 if (!supportedPrimitiveDescriptors.empty())
42 InferenceEngine::LayerConfig config;
43 config.dynBatchSupport = true;
44 if (getType() == Input || getType() == MemoryInput) {
45 InferenceEngine::Precision precision = getCnnLayer()->precision;
46 if (precision == InferenceEngine::Precision::U16 || isMeanImage)
47 precision = InferenceEngine::Precision::FP32;
48 auto outputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(precision);
49 InferenceEngine::DataConfig dataConfig;
50 dataConfig.inPlace = -1;
51 dataConfig.constant = false;
53 memory::format layout = MKLDNNMemory::Convert(getCnnLayer()->outData[0]->getLayout());
54 dataConfig.desc = MKLDNNMemoryDesc(getChildEdgeAt(0)->getDims(), outputDataType, layout);
55 config.outConfs.push_back(dataConfig);
56 } else if (getType() == Output) {
57 InferenceEngine::Precision precision = getCnnLayer()->insData[0].lock()->getPrecision();
58 if (precision == InferenceEngine::Precision::U16) precision = InferenceEngine::Precision::FP32;
59 auto inputDataType = MKLDNNExtensionUtils::IEPrecisionToDataType(precision);
60 InferenceEngine::DataConfig dataConfig;
61 dataConfig.inPlace = -1;
62 dataConfig.constant = false;
64 memory::format layout = MKLDNNMemory::Convert(getCnnLayer()->insData[0].lock()->getLayout());
65 dataConfig.desc = MKLDNNMemoryDesc(getParentEdgeAt(0)->getDims(), inputDataType, layout);
66 config.inConfs.push_back(dataConfig);
68 supportedPrimitiveDescriptors.emplace_back(config, impl_desc_type::unknown);
71 void MKLDNNInputNode::createPrimitive() {
72 for (size_t i = 0; i < getChildEdges().size(); i++) {
73 auto &dstMemPtr = getChildEdgeAt(i)->getMemoryPtr();
74 if (!dstMemPtr || !dstMemPtr->GetPrimitivePtr())
75 THROW_IE_EXCEPTION << "Destination memory didn't allocate for node " << getName()
76 << " to node " << getChildEdgeAt(i)->getChild()->getName() << ".";
78 for (size_t i = 0; i < getParentEdges().size(); i++) {
79 auto &srcMemPtr = getParentEdgeAt(i)->getMemoryPtr();
80 if (!srcMemPtr || !srcMemPtr->GetPrimitivePtr())
81 THROW_IE_EXCEPTION << "Destination memory didn't allocate for node " << getName()
82 << " from node " << getParentEdgeAt(i)->getParent()->getName() << ".";
85 const PrimitiveDescInfo *selected_pd = getSelectedPrimitiveDescriptor();
86 if (selected_pd == nullptr)
87 THROW_IE_EXCEPTION << "Preferable primitive descriptor does not set for node " << getName() << ".";
90 bool MKLDNNInputNode::created() const {
91 return getType() == Input || getType() == Output;
94 void MKLDNNInputNode::execute(mkldnn::stream strm) {
97 auto dstBlob = getChildEdgeAt(0)->getBlob();
98 const float *srcData = constBlob->cbuffer().as<float *>();
99 float *dstData = dstBlob->buffer();
100 if (constBlob->size() != dstBlob->size()) {
101 THROW_IE_EXCEPTION << "Incorrect blob sizes for node " << getName();
103 for (size_t i = 0; i < constBlob->size(); i++) {
104 // srcData without offset() because constBlob should be planar
105 dstData[dstBlob->getTensorDesc().offset(i)] = srcData[i];