1 // Copyright (C) 2018 Intel Corporation
3 // SPDX-License-Identifier: Apache-2.0
8 #include <mkldnn_plugin/mkldnn_graph.h>
9 #include <mkldnn_plugin/mkldnn_memory.h>
10 #include <mkldnn_plugin/mkldnn_extension_utils.h>
11 #include <mkldnn_plugin/mkldnn_graph_optimizer.h>
12 #include <mkldnn_plugin/nodes/mkldnn_input_node.h>
15 #define GARB_VAL(x) ((x + 100.0f + sin(x)) / (x + 150.f))
17 class MKLDNNGraphTestClass: public MKLDNNPlugin::MKLDNNGraph {
19 enum class CheckDynBatchType {
24 MKLDNNGraphTestClass(): MKLDNNPlugin::MKLDNNGraph() {}
25 virtual ~MKLDNNGraphTestClass() = default;
27 static std::string getStrPrimitiveDescriptorType(MKLDNNPlugin::impl_desc_type type) {
30 auto add_type = [&](std::string t) {
31 if (!str_type.empty() && t.c_str()[0] != '_')
36 #define SEARCH_TYPE(_type) \
37 if ((type & MKLDNNPlugin::impl_desc_type::_type) == MKLDNNPlugin::impl_desc_type::_type) \
52 SEARCH_TYPE(winograd);
56 if (type == MKLDNNPlugin::impl_desc_type::unknown)
58 else if (str_type.empty())
63 void PushInputData(const std::string& name, const InferenceEngine::Blob::Ptr &in, int batch) {
64 if (!IsReady()) THROW_IE_EXCEPTION<< "Wrong state. Topology not ready.";
66 auto input = inputNodes.find(name);
67 if (input != inputNodes.end()) {
68 MKLDNNPlugin::MKLDNNDims outDims = input->second->getChildEdgeAt(0)->getDims();
72 const void *ext_data_ptr = in->cbuffer();
73 void *inter_data_ptr = input->second->getChildEdgeAt(0)->getMemory().GetData();
75 if (ext_data_ptr != inter_data_ptr)
76 input->second->getChildEdgeAt(0)->getMemory().SetData(MKLDNNPlugin::MKLDNNExtensionUtils::IEPrecisionToDataType(in->getTensorDesc().getPrecision()),
77 MKLDNNPlugin::MKLDNNMemory::GetPlainFormat(outDims), ext_data_ptr, in->byteSize() / outDims[0] * batch, false);
79 // todo: make sure 'name' exists in this map...
80 if (_meanImages.find(name) != _meanImages.end()) {
81 if (in->getTensorDesc().getPrecision() == InferenceEngine::Precision::FP32) {
82 _meanImages[name].Subtract(outDims, reinterpret_cast<float *>(inter_data_ptr));
84 THROW_IE_EXCEPTION << "Mean image of type " << in->getTensorDesc().getPrecision().name() << " is unsupported";
88 THROW_IE_EXCEPTION << "Input blob for infer '" << name << "' doesn't correspond to input in network";
92 void Infer(const InferenceEngine::BlobMap& inputs, InferenceEngine::BlobMap& result, int batch = -1) {
93 for (auto it = result.begin(); it != result.end(); it++) {
94 InferenceEngine::TBlob<float> *out = dynamic_cast<InferenceEngine::TBlob<float> *>((*it).second.get());
96 FAIL() << "Output data precision not supported. Expected float.";
101 // need to retain converted blobs until infer finish
102 std::vector<InferenceEngine::Blob::Ptr> convertedInputs;
103 for (auto input : inputs) {
104 InferenceEngine::TBlob<float> *in_f = nullptr;
105 switch (input.second->precision()) {
106 case InferenceEngine::Precision::FP32:
107 in_f = dynamic_cast<InferenceEngine::TBlob<float> *>(input.second.get());
110 THROW_IE_EXCEPTION << "Unsupported input precision " << input.second->precision();
113 switch (input.second->precision()) {
114 case InferenceEngine::Precision::FP32: break;
115 default: FAIL() << "Unsupported precision";
118 if (in_f == nullptr) {
119 FAIL() << "Input data precision not supported. Expected float.";
122 if (in_f->readOnly() == nullptr) {
123 THROW_IE_EXCEPTION << "Input data was not allocated.";
126 PushInputData(input.first, input.second, batch);
128 MKLDNNPlugin::MKLDNNGraph::Infer(batch);
129 } catch (const std::exception &e) {
133 PullOutputData(result);
136 std::vector<MKLDNNPlugin::MKLDNNNodePtr>& getNodes() {
140 void CreateGraph(InferenceEngine::ICNNNetwork &network, const MKLDNNPlugin::MKLDNNExtensionManager::Ptr& extMgr) {
141 MKLDNNGraph::CreateGraph(network, extMgr);
144 void CreateGraph(InferenceEngine::ICNNNetwork &network) {
145 MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr;
146 CreateGraph(network, extMgr);
149 void checkDynBatch(InferenceEngine::BlobMap& srcs, InferenceEngine::BlobMap& outputBlobs, int batch, size_t MB,
150 const std::function<bool (const MKLDNNPlugin::MKLDNNNodePtr&)>& comp, CheckDynBatchType type = CheckDynBatchType::Both) {
151 for (auto &node : getNodes()) {
153 auto inputBlob = node->getParentEdgeAt(0)->getBlob();
154 auto *data = inputBlob->buffer().as<float *>();
155 size_t dataSize = inputBlob->getTensorDesc().getBlockingDesc().getStrides()[0] * MB;
156 for (size_t j = 0; j < dataSize; j++) {
157 data[j] = GARB_VAL(j);
160 auto outputBlob = node->getChildEdgeAt(0)->getBlob();
161 data = outputBlob->buffer().as<float *>();
162 dataSize = outputBlob->getTensorDesc().getBlockingDesc().getStrides()[0] * MB;
163 for (size_t j = 0; j < dataSize; j++) {
164 data[j] = GARB_VAL(j);
169 Infer(srcs, outputBlobs, batch);
171 for (auto &node : getNodes()) {
173 auto inputBlob = node->getParentEdgeAt(0)->getBlob();
174 auto *data = inputBlob->buffer().as<float *>();
175 auto inputNoBatchSize = inputBlob->getTensorDesc().getBlockingDesc().getStrides()[0];
176 for (size_t i = 0; i < batch; i++) {
177 for (size_t j = 0; j < inputNoBatchSize; j++) {
178 ASSERT_NE(data[i*inputNoBatchSize + j], GARB_VAL(i*inputNoBatchSize + j));
182 if (type == CheckDynBatchType::Both || type == CheckDynBatchType::Parent) {
183 for (size_t i = static_cast<size_t>(batch); i < MB; i++) {
184 for (size_t j = 0; j < inputNoBatchSize; j++) {
185 ASSERT_NEAR(data[i * inputNoBatchSize + j],
186 GARB_VAL(i * inputNoBatchSize + j), 0.001f);
191 auto outputBlob = node->getChildEdgeAt(0)->getBlob();
192 data = outputBlob->buffer().as<float *>();
193 auto outputNoBatchSize = outputBlob->getTensorDesc().getBlockingDesc().getStrides()[0];
194 for (size_t i = 0; i < batch; i++) {
195 for (size_t j = 0; j < outputNoBatchSize; j++) {
196 ASSERT_NE(data[i*outputNoBatchSize + j], GARB_VAL(i*outputNoBatchSize + j));
199 if (type == CheckDynBatchType::Both || type == CheckDynBatchType::Child) {
200 for (size_t i = static_cast<size_t>(batch); i < MB; i++) {
201 for (size_t j = 0; j < outputNoBatchSize; j++) {
202 ASSERT_NEAR(data[i * outputNoBatchSize + j],
203 GARB_VAL(i * outputNoBatchSize + j), 0.001f);