-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <nodes/mkldnn_permute_node.h>
#include <nodes/mkldnn_memory_node.hpp>
#include <nodes/mkldnn_rnn.h>
+#include <nodes/mkldnn_quantize_node.h>
+#include <nodes/mkldnn_bin_conv_node.h>
#include <mkldnn_types.h>
#include "mkldnn_extension_utils.h"
#include "mkldnn_plugin.h"
MKLDNNNode::Register<MKLDNNSplitNode> MKLDNNSplitNode::reg;
MKLDNNNode::Register<MKLDNNTileNode> MKLDNNTileNode::reg;
MKLDNNNode::Register<MKLDNNPermuteNode> MKLDNNPermuteNode::reg;
+MKLDNNNode::Register<MKLDNNQuantizeNode> MKLDNNQuantizeNode::reg;
+MKLDNNNode::Register<MKLDNNBinaryConvolutionNode> MKLDNNBinaryConvolutionNode::reg;
MKLDNNNode::Register<MKLDNNMemoryInputNode> MKLDNNMemoryInputNode::reg;
MKLDNNNode::Register<MKLDNNMemoryOutputNode> MKLDNNMemoryOutputNode::reg;
MKLDNNNode::Register<MKLDNNRNN> MKLDNNRNN::reg;
}
}
- parentEdges.resize(layer->insData.size());
for (const auto& inData : layer->insData) {
inDims.emplace_back(inData.lock()->getDims());
}
}
}
-void MKLDNNNode::addEdge(const MKLDNNEdgeWeakPtr& edge, size_t pIndex, size_t cIndex, bool insertChildIndex) {
+void MKLDNNNode::addEdge(const MKLDNNEdgeWeakPtr& edge) {
auto edgePtr = edge.lock();
if (!edgePtr)
return;
auto childPtr = edgePtr->getChild();
if (!parentPtr || !childPtr)
return;
- if (cIndex < parentPtr->childEdges.size()) {
- if (insertChildIndex) {
- parentPtr->childEdges.insert(parentPtr->childEdges.begin() + cIndex, edge);
- } else {
- removeEdge(parentPtr->childEdges[cIndex]);
- parentPtr->childEdges[cIndex] = edge;
- }
- } else {
- parentPtr->childEdges.push_back(edge);
- }
- if (pIndex < childPtr->parentEdges.size()) {
- removeEdge(childPtr->parentEdges[pIndex]);
- childPtr->parentEdges[pIndex] = edge;
- } else {
- childPtr->parentEdges.push_back(edge);
- }
+
+ parentPtr->childEdges.push_back(edge);
+ childPtr->parentEdges.push_back(edge);
}
void MKLDNNNode::removeEdge(const MKLDNNEdgeWeakPtr& edge) {
for (auto it = childPtr->parentEdges.begin(); it != childPtr->parentEdges.end(); it++) {
auto parentEdge = (*it).lock();
if (parentEdge && parentEdge->getChild() == childPtr && parentEdge->getParent() == parentPtr) {
- (*it).reset();
+ childPtr->parentEdges.erase(it);
break;
}
}
for (auto it = parentPtr->childEdges.begin(); it != parentPtr->childEdges.end(); it++) {
auto childEdge = (*it).lock();
if (childEdge && childEdge->getChild() == childPtr && childEdge->getParent() == parentPtr) {
- (*it).reset();
+ parentPtr->childEdges.erase(it);
break;
}
}
}
void MKLDNNNode::remove() {
- for (const auto &parentEdge : parentEdges) {
+ auto parent_edges = parentEdges;
+ for (const auto &parentEdge : parent_edges) {
removeEdge(parentEdge);
}
- for (const auto &childEdge : childEdges) {
+ auto child_edges = childEdges;
+ for (const auto &childEdge : child_edges) {
removeEdge(childEdge);
}
}
return childEdgePtr;
}
+const std::vector<MKLDNNEdgePtr> MKLDNNNode::getParentEdgesAtPort(size_t idx) const {
+ if (idx >= inDims.size())
+ THROW_IE_EXCEPTION << "Node " << getName() << " contains less input ports than " << idx;
+
+ std::vector<MKLDNNEdgePtr> res;
+ for (auto &edge_w : parentEdges) {
+ auto edge = edge_w.lock();
+ if (!edge)
+ THROW_IE_EXCEPTION << "Node " << getName() << " contains dead weak ptr";
+ if (edge->getOutputNum() == idx) res.push_back(edge);
+ }
+ return res;
+}
+
+const std::vector<MKLDNNEdgePtr> MKLDNNNode::getChildEdgesAtPort(size_t idx) const {
+ if (idx >= outDims.size())
+ THROW_IE_EXCEPTION << "Node " << getName() << " contains less output ports than " << idx;
+
+ std::vector<MKLDNNEdgePtr> res;
+ for (auto &edge_w : childEdges) {
+ auto edge = edge_w.lock();
+ if (!edge)
+ THROW_IE_EXCEPTION << "Node " << getName() << " contains dead weak ptr";
+ if (edge->getInputNum() == idx) res.push_back(edge);
+ }
+ return res;
+}
+
+
std::vector<memory::format> MKLDNNNode::getAvailableFormatsForDims(const MKLDNNDims &dims) const {
if (dims.ndims() == 1)
return {memory::format::x};
else if (dims.ndims() == 2)
return {memory::format::nc};
+ else if (dims.ndims() == 3)
+ return {memory::format::tnc, memory::format::ntc};
else if (dims.ndims() == 4)
return {memory::format::nchw, memory::format::nChw8c, memory::format::nChw16c};
else if (dims.ndims() == 5)
for (auto& desc : descs) {
try {
- primitive_desc_iterator itpd = desc.createPrimitiveDescriptorIterator(engine);
+ std::shared_ptr<primitive_desc_iterator> itpd = std::make_shared<primitive_desc_iterator>(desc.createPrimitiveDescriptorIterator(engine));
do {
InferenceEngine::LayerConfig config;
config.dynBatchSupport = true;
InferenceEngine::DataConfig dataConfig;
dataConfig.inPlace = -1;
dataConfig.constant = false;
- dataConfig.desc = MKLDNNExtensionUtils::getUninitTensorDesc(getSrcMemDesc(itpd, i));
+ dataConfig.desc = MKLDNNExtensionUtils::getUninitTensorDesc(getSrcMemDesc(*itpd, i));
config.inConfs.push_back(dataConfig);
}
InferenceEngine::DataConfig dataConfig;
dataConfig.inPlace = canBeInPlace() ? 0 : -1;
dataConfig.constant = false;
- dataConfig.desc = MKLDNNExtensionUtils::getUninitTensorDesc(getDstMemDesc(itpd, i));
+ dataConfig.desc = MKLDNNExtensionUtils::getUninitTensorDesc(getDstMemDesc(*itpd, i));
config.outConfs.push_back(dataConfig);
}
- impl_desc_type impl_type = parse_impl_name(itpd.get_impl_info_str());
+ impl_desc_type impl_type = parse_impl_name(itpd->get_impl_info_str());
supportedPrimitiveDescriptors.emplace_back(config, impl_type);
- } while (itpd.next());
+ } while (itpd->next());
} catch (std::exception& e) {
// it throw exception in case of no implementation found
continue;
outDescs.push_back(outConf.desc);
createDescriptor({inDescs}, {outDescs});
+ std::shared_ptr<mkldnn::primitive_attr> attr = initPrimitiveAttr();
+
InferenceEngine::LayerConfig rightConfig = getSelectedPrimitiveDescriptor()->getConfig();
size_t selected_count = 0;
for (size_t j = 0; j < descs.size(); j++) {
try {
const auto &desc = descs[j];
- primitive_desc_iterator itpd = desc.createPrimitiveDescriptorIterator(engine);
+ std::shared_ptr<primitive_desc_iterator> itpd;
+ if (attr == nullptr) {
+ itpd = std::make_shared<primitive_desc_iterator>(desc.createPrimitiveDescriptorIterator(engine));
+ } else {
+ itpd = std::make_shared<primitive_desc_iterator>(desc.createPrimitiveDescriptorIterator(engine, *(attr.get())));
+ }
do {
InferenceEngine::LayerConfig cfg;
cfg.dynBatchSupport = true;
InferenceEngine::DataConfig dataConfig;
dataConfig.inPlace = canBeInPlace() ? 0 : -1;
dataConfig.constant = false;
- dataConfig.desc = getSrcMemDesc(itpd, i);
+ dataConfig.desc = getSrcMemDesc(*itpd, i);
cfg.inConfs.push_back(dataConfig);
}
InferenceEngine::DataConfig dataConfig;
dataConfig.inPlace = -1;
dataConfig.constant = false;
- dataConfig.desc = getDstMemDesc(itpd, i);
+ dataConfig.desc = getDstMemDesc(*itpd, i);
cfg.outConfs.push_back(dataConfig);
}
- impl_desc_type impl_type = parse_impl_name(itpd.get_impl_info_str().c_str());
+ impl_desc_type impl_type = parse_impl_name(itpd->get_impl_info_str().c_str());
if (selected_count == selectedPrimitiveDescriptorIndex) {
if (impl_type != selectedPD->getImplementationType()) {
THROW_IE_EXCEPTION << "Cannot get the original layer configuration!";
}
}
selected_count++;
- } while (itpd.next());
+ } while (itpd->next());
} catch(...) {}
}
intLayout = InferenceEngine::Layout::OIHW;
InferenceEngine::TensorDesc desc(blb->precision(), dims, intLayout);
- InferenceEngine::TBlob<float>::Ptr internalBlob = InferenceEngine::make_shared_blob<float>(desc);
- internalBlob->allocate();
- char *data = internalBlob->buffer();
- size_t intBuffSize = internalBlob->byteSize();
-
- size_t offset = blb->byteSize();
- checkSize(intBuffSize, offset);
- ie_memcpy(data, internalBlob->byteSize(), blb->buffer(), blb->byteSize());
- data += blb->byteSize();
- for (const auto &merged : getMergeWith()) {
- wLayer = dynamic_cast<InferenceEngine::WeightableLayer*>(merged->getCnnLayer().get());
- if (wLayer == nullptr)
- THROW_IE_EXCEPTION << "Cannot convert merged weightable layer for node "
- << getName() << ".";
- blb = weights ? wLayer->_weights : wLayer->_biases;
-
- if (blb == nullptr)
- THROW_IE_EXCEPTION << "Cannot get internal blob layer for node " << getName() << ".";
- offset += blb->byteSize();
+
+ auto fillInternalBlob = [&](char *data, size_t intBuffSize) {
+ size_t offset = blb->byteSize();
checkSize(intBuffSize, offset);
- ie_memcpy(data, internalBlob->byteSize(), blb->buffer(), blb->byteSize());
+ ie_memcpy(data, intBuffSize, blb->buffer(), blb->byteSize());
data += blb->byteSize();
- }
+ for (const auto &merged : getMergeWith()) {
+ wLayer = dynamic_cast<InferenceEngine::WeightableLayer*>(merged->getCnnLayer().get());
+ if (wLayer == nullptr)
+ THROW_IE_EXCEPTION << "Cannot convert merged weightable layer for node "
+ << getName() << ".";
+ blb = weights ? wLayer->_weights : wLayer->_biases;
+
+ if (blb == nullptr)
+ THROW_IE_EXCEPTION << "Cannot get internal blob layer for node " << getName() << ".";
+ offset += blb->byteSize();
+ checkSize(intBuffSize, offset);
+ ie_memcpy(data, intBuffSize, blb->buffer(), blb->byteSize());
+ data += blb->byteSize();
+ }
+ };
- return internalBlob;
+ if (blb->precision() == Precision::BIN) {
+ InferenceEngine::TBlob<int8_t>::Ptr internalBlob = InferenceEngine::make_shared_blob<int8_t>(desc);
+
+ internalBlob->allocate();
+ char *data = internalBlob->buffer();
+ size_t intBuffSize = internalBlob->byteSize();
+
+ fillInternalBlob(data, intBuffSize);
+
+ return internalBlob;
+ } else {
+ InferenceEngine::TBlob<float>::Ptr internalBlob = InferenceEngine::make_shared_blob<float>(desc);
+
+ internalBlob->allocate();
+ char *data = internalBlob->buffer();
+ size_t intBuffSize = internalBlob->byteSize();
+
+ fillInternalBlob(data, intBuffSize);
+
+ return internalBlob;
+ }
}
void MKLDNNNode::prepareMemory(const PrimitiveDescInfo *selected_pd, mkldnn::primitive_desc_iterator& itpd) {
return constant;
}
+void MKLDNNNode::addOriginalLayer(const InferenceEngine::CNNLayerPtr &layer) {
+ if (!layer) return;
+ if (originalLayers.empty()) {
+ originalLayers = layer->name;
+ } else {
+ originalLayers += "," + layer->name;
+ }
+}
+
void MKLDNNNode::cleanup() {
internalBlobs.clear();
cnnLayer.reset();
return "Pooling";
case FullyConnected:
return "FullyConnected";
+ case FullyConnected_Activation:
+ return "FullyConnected_Activation";
case Gemm:
return "Gemm";
case SoftMax:
return "MemoryOutput";
case MemoryInput:
return "MemoryInput";
- case RNN:
- return "RNN";
- case LSTMCell:
- return "LSTMCell";
+ case RNNSeq:
+ return "RNNSeq";
+ case RNNCell:
+ return "RNNCell";
default:
return "Unknown";
config.outConfs[i].desc = getConfiguredOutputDesc(config, i);
}
initDescriptor(config);
- } else if (getType() != RNN && getType() != LSTMCell) {
+ } else if (getType() != RNNSeq && getType() != RNNCell) {
initDescriptor(config);
}
}