1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
7 #include <mkldnn_plugin/mkldnn_graph.h>
8 #include <mkldnn_plugin/mkldnn_memory.h>
9 #include <mkldnn_plugin/mkldnn_extension_utils.h>
10 #include <mkldnn_plugin/mkldnn_graph_optimizer.h>
11 #include <mkldnn_plugin/nodes/mkldnn_input_node.h>
14 #define GARB_VAL(x) ((x + 100.0f + sin(x)) / (x + 150.f))
16 class MKLDNNGraphTestClass: public MKLDNNPlugin::MKLDNNGraph {
18 enum class CheckDynBatchType {
23 MKLDNNGraphTestClass(): MKLDNNPlugin::MKLDNNGraph() {}
24 virtual ~MKLDNNGraphTestClass() = default;
26 static std::string getStrPrimitiveDescriptorType(MKLDNNPlugin::impl_desc_type type) {
29 auto add_type = [&](std::string t) {
30 if (!str_type.empty() && t.c_str()[0] != '_')
35 #define SEARCH_TYPE(_type) \
36 if ((type & MKLDNNPlugin::impl_desc_type::_type) == MKLDNNPlugin::impl_desc_type::_type) \
51 SEARCH_TYPE(winograd);
55 if (type == MKLDNNPlugin::impl_desc_type::unknown)
57 else if (str_type.empty())
62 void PushInputData(const std::string& name, const InferenceEngine::Blob::Ptr &in, int batch) {
63 if (!IsReady()) THROW_IE_EXCEPTION<< "Wrong state. Topology not ready.";
65 auto input = inputNodes.find(name);
66 if (input != inputNodes.end()) {
67 MKLDNNPlugin::MKLDNNDims outDims = input->second->getChildEdgeAt(0)->getDims();
71 const void *ext_data_ptr = in->cbuffer();
72 void *inter_data_ptr = input->second->getChildEdgeAt(0)->getMemory().GetData();
74 if (ext_data_ptr != inter_data_ptr)
75 input->second->getChildEdgeAt(0)->getMemory().SetData(MKLDNNPlugin::MKLDNNExtensionUtils::IEPrecisionToDataType(in->getTensorDesc().getPrecision()),
76 MKLDNNPlugin::MKLDNNMemory::GetPlainFormat(outDims), ext_data_ptr, in->byteSize() / outDims[0] * batch, false);
78 // todo: make sure 'name' exists in this map...
79 if (_meanImages.find(name) != _meanImages.end()) {
80 if (in->getTensorDesc().getPrecision() == InferenceEngine::Precision::FP32) {
81 _meanImages[name].Subtract(outDims, reinterpret_cast<float *>(inter_data_ptr), in->getTensorDesc().getLayout());
83 THROW_IE_EXCEPTION << "Mean image of type " << in->getTensorDesc().getPrecision().name() << " is unsupported";
87 THROW_IE_EXCEPTION << "Input blob for infer '" << name << "' doesn't correspond to input in network";
91 void Infer(const InferenceEngine::BlobMap& inputs, InferenceEngine::BlobMap& result, int batch = -1) {
93 // need to retain converted blobs until infer finish
94 std::vector<InferenceEngine::Blob::Ptr> convertedInputs;
95 for (auto input : inputs) {
96 switch (input.second->precision()) {
97 case InferenceEngine::Precision::FP32: {
98 InferenceEngine::TBlob<float> *in_f = nullptr;
99 in_f = dynamic_cast<InferenceEngine::TBlob<float> *>(input.second.get());
100 if (in_f == nullptr) {
101 FAIL() << "Input data precision not supported. Expected float.";
104 if (in_f->readOnly() == nullptr) {
105 THROW_IE_EXCEPTION << "Input data was not allocated.";
109 case InferenceEngine::Precision::I32: {
110 InferenceEngine::TBlob<int32_t> *in_f = nullptr;
111 in_f = dynamic_cast<InferenceEngine::TBlob<int32_t> *>(input.second.get());
112 if (in_f == nullptr) {
113 FAIL() << "Input data precision not supported. Expected float.";
116 if (in_f->readOnly() == nullptr) {
117 THROW_IE_EXCEPTION << "Input data was not allocated.";
121 case InferenceEngine::Precision::U16: {
122 InferenceEngine::TBlob<uint16_t> *in_f = nullptr;
123 in_f = dynamic_cast<InferenceEngine::TBlob<uint16_t> *>(input.second.get());
124 if (in_f == nullptr) {
125 FAIL() << "Input data precision not supported. Expected float.";
128 if (in_f->readOnly() == nullptr) {
129 THROW_IE_EXCEPTION << "Input data was not allocated.";
133 case InferenceEngine::Precision::I16: {
134 InferenceEngine::TBlob<int16_t> *in_f = nullptr;
135 in_f = dynamic_cast<InferenceEngine::TBlob<int16_t> *>(input.second.get());
136 if (in_f == nullptr) {
137 FAIL() << "Input data precision not supported. Expected float.";
140 if (in_f->readOnly() == nullptr) {
141 THROW_IE_EXCEPTION << "Input data was not allocated.";
145 case InferenceEngine::Precision::U8: {
146 InferenceEngine::TBlob<uint8_t> *in_f = nullptr;
147 in_f = dynamic_cast<InferenceEngine::TBlob<uint8_t> *>(input.second.get());
148 if (in_f == nullptr) {
149 FAIL() << "Input data precision not supported. Expected float.";
152 if (in_f->readOnly() == nullptr) {
153 THROW_IE_EXCEPTION << "Input data was not allocated.";
157 case InferenceEngine::Precision::I8: {
158 InferenceEngine::TBlob<int8_t> *in_f = nullptr;
159 in_f = dynamic_cast<InferenceEngine::TBlob<int8_t> *>(input.second.get());
160 if (in_f == nullptr) {
161 FAIL() << "Input data precision not supported. Expected float.";
164 if (in_f->readOnly() == nullptr) {
165 THROW_IE_EXCEPTION << "Input data was not allocated.";
170 THROW_IE_EXCEPTION << "Unsupported input precision " << input.second->precision();
173 PushInputData(input.first, input.second, batch);
175 MKLDNNPlugin::MKLDNNGraph::Infer(batch);
176 } catch (const std::exception &e) {
180 PullOutputData(result);
183 std::vector<MKLDNNPlugin::MKLDNNNodePtr>& getNodes() {
187 void CreateGraph(InferenceEngine::ICNNNetwork &network, const MKLDNNPlugin::MKLDNNExtensionManager::Ptr& extMgr) {
188 MKLDNNGraph::CreateGraph(network, extMgr);
191 void CreateGraph(InferenceEngine::ICNNNetwork &network) {
192 MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr;
193 CreateGraph(network, extMgr);
196 void checkDynBatch(InferenceEngine::BlobMap& srcs, InferenceEngine::BlobMap& outputBlobs, int batch, size_t MB,
197 const std::function<bool (const MKLDNNPlugin::MKLDNNNodePtr&)>& comp, CheckDynBatchType type = CheckDynBatchType::Both) {
198 for (auto &node : getNodes()) {
200 auto inputBlob = node->getParentEdgeAt(0)->getBlob();
201 auto *data = inputBlob->buffer().as<float *>();
202 size_t dataSize = inputBlob->getTensorDesc().getBlockingDesc().getStrides()[0] * MB;
203 for (size_t j = 0; j < dataSize; j++) {
204 data[j] = GARB_VAL(j);
207 auto outputBlob = node->getChildEdgeAt(0)->getBlob();
208 data = outputBlob->buffer().as<float *>();
209 dataSize = outputBlob->getTensorDesc().getBlockingDesc().getStrides()[0] * MB;
210 for (size_t j = 0; j < dataSize; j++) {
211 data[j] = GARB_VAL(j);
216 Infer(srcs, outputBlobs, batch);
218 for (auto &node : getNodes()) {
220 auto inputBlob = node->getParentEdgeAt(0)->getBlob();
221 auto *data = inputBlob->buffer().as<float *>();
222 auto inputNoBatchSize = inputBlob->getTensorDesc().getBlockingDesc().getStrides()[0];
223 for (size_t i = 0; i < batch; i++) {
224 for (size_t j = 0; j < inputNoBatchSize; j++) {
225 ASSERT_NE(data[i*inputNoBatchSize + j], GARB_VAL(i*inputNoBatchSize + j));
229 if (type == CheckDynBatchType::Both || type == CheckDynBatchType::Parent) {
230 for (size_t i = static_cast<size_t>(batch); i < MB; i++) {
231 for (size_t j = 0; j < inputNoBatchSize; j++) {
232 ASSERT_NEAR(data[i * inputNoBatchSize + j],
233 GARB_VAL(i * inputNoBatchSize + j), 0.001f);
238 auto outputBlob = node->getChildEdgeAt(0)->getBlob();
239 data = outputBlob->buffer().as<float *>();
240 auto outputNoBatchSize = outputBlob->getTensorDesc().getBlockingDesc().getStrides()[0];
241 for (size_t i = 0; i < batch; i++) {
242 for (size_t j = 0; j < outputNoBatchSize; j++) {
243 ASSERT_NE(data[i*outputNoBatchSize + j], GARB_VAL(i*outputNoBatchSize + j));
246 if (type == CheckDynBatchType::Both || type == CheckDynBatchType::Child) {
247 for (size_t i = static_cast<size_t>(batch); i < MB; i++) {
248 for (size_t j = 0; j < outputNoBatchSize; j++) {
249 ASSERT_NEAR(data[i * outputNoBatchSize + j],
250 GARB_VAL(i * outputNoBatchSize + j), 0.001f);