Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / engines / mkldnn / graph / layers / internal / graph_leaks_test.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <gtest/gtest.h>
6 #include <gmock/gmock-spec-builders.h>
7 #include "mkldnn_plugin/mkldnn_graph.h"
8
9 #include "test_graph.hpp"
10
11 #include <mkldnn_plugin/mkldnn_extension_utils.h>
12 #include <mkldnn_plugin/mkldnn_plugin.h>
13 #include <mkldnn_plugin/config.h>
14
15 using namespace std;
16 using namespace mkldnn;
17
18 class MKLDNNTestExecNetwork: public MKLDNNPlugin::MKLDNNExecNetwork {
19 public:
20     MKLDNNTestExecNetwork(InferenceEngine::ICNNNetwork &network, const MKLDNNPlugin::Config &cfg)
21             : MKLDNNExecNetwork(network, cfg, {}) {}
22     MKLDNNPlugin::MKLDNNGraph& getGraph() {
23         return *graphs[0];
24     }
25 };
26
27 class MKLDNNTestEngine: public MKLDNNPlugin::Engine {
28 public:
29     MKLDNNPlugin::MKLDNNGraph& getGraph() {
30         auto * execNetworkInt =
31                 dynamic_cast<InferenceEngine::ExecutableNetworkBase<InferenceEngine::ExecutableNetworkInternal> *>(_loadedNetwork.get());
32         if (!execNetworkInt)
33             THROW_IE_EXCEPTION << "Cannot find loaded network!";
34
35         auto * network = reinterpret_cast<MKLDNNTestExecNetwork *>(execNetworkInt->getImpl().get());
36         if (!network)
37             THROW_IE_EXCEPTION << "Cannot get mkldnn graph!";
38         return network->getGraph();
39     }
40 };
41
42 class MKLDNNGraphLeaksTests: public ::testing::Test {
43 protected:
44     void addOutputToEachNode(InferenceEngine::CNNNetReader& net_reader, std::vector<std::string>& new_outputs,
45                              InferenceEngine::CNNLayerPtr cnnLayer) {
46         auto outputs = net_reader.getNetwork().getOutputsInfo();
47         if (outputs.find(cnnLayer->name) != outputs.end())
48             return;
49
50         net_reader.getNetwork().addOutput(cnnLayer->name);
51         new_outputs.push_back(cnnLayer->name);
52
53         for (const auto &layer : cnnLayer->outData) {
54             for (const auto &data : layer->getInputTo()) {
55                 addOutputToEachNode(net_reader, new_outputs, data.second);
56             }
57         }
58     }
59
60     void fill_data(float *data, size_t size, size_t duty_ratio = 10) {
61         for (size_t i = 0; i < size; i++) {
62             if ( ( i / duty_ratio)%2 == 1) {
63                 data[i] = 0.0;
64             } else {
65                 data[i] = (float) sin((float)i);
66             }
67         }
68     }
69 };
70
71 TEST_F(MKLDNNGraphLeaksTests, MKLDNN_not_release_outputs_fp32) {
72     try {
73         InferenceEngine::CNNNetReader net_reader;
74         std::string model = "<net name=\"LeNet\" version=\"2\" batch=\"1\">\n"
75                 "    <layers>\n"
76                 "        <layer name=\"data\" type=\"Input\" precision=\"FP32\" id=\"0\">\n"
77                 "            <output>\n"
78                 "                <port id=\"0\">\n"
79                 "                    <dim>1</dim>\n"
80                 "                    <dim>1</dim>\n"
81                 "                    <dim>28</dim>\n"
82                 "                    <dim>28</dim>\n"
83                 "                </port>\n"
84                 "            </output>\n"
85                 "        </layer>\n"
86                 "        <layer name=\"conv1\" type=\"Convolution\" precision=\"FP32\" id=\"1\">\n"
87                 "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"0\" pad-y=\"0\" kernel-x=\"5\" kernel-y=\"5\" output=\"20\" group=\"1\"/>\n"
88                 "            <input>\n"
89                 "                <port id=\"1\">\n"
90                 "                    <dim>1</dim>\n"
91                 "                    <dim>1</dim>\n"
92                 "                    <dim>28</dim>\n"
93                 "                    <dim>28</dim>\n"
94                 "                </port>\n"
95                 "            </input>\n"
96                 "            <output>\n"
97                 "                <port id=\"2\">\n"
98                 "                    <dim>1</dim>\n"
99                 "                    <dim>20</dim>\n"
100                 "                    <dim>24</dim>\n"
101                 "                    <dim>24</dim>\n"
102                 "                </port>\n"
103                 "            </output>\n"
104                 "            <weights offset=\"0\" size=\"2000\"/>\n"
105                 "            <biases offset=\"2000\" size=\"80\"/>\n"
106                 "        </layer>\n"
107                 "        <layer name=\"pool1\" type=\"Pooling\" precision=\"FP32\" id=\"2\">\n"
108                 "            <pooling_data kernel-x=\"2\" kernel-y=\"2\" pad-x=\"0\" pad-y=\"0\" stride-x=\"2\" stride-y=\"2\" rounding-type=\"ceil\" pool-method=\"max\"/>\n"
109                 "            <input>\n"
110                 "                <port id=\"3\">\n"
111                 "                    <dim>1</dim>\n"
112                 "                    <dim>20</dim>\n"
113                 "                    <dim>24</dim>\n"
114                 "                    <dim>24</dim>\n"
115                 "                </port>\n"
116                 "            </input>\n"
117                 "            <output>\n"
118                 "                <port id=\"4\">\n"
119                 "                    <dim>1</dim>\n"
120                 "                    <dim>20</dim>\n"
121                 "                    <dim>12</dim>\n"
122                 "                    <dim>12</dim>\n"
123                 "                </port>\n"
124                 "            </output>\n"
125                 "        </layer>\n"
126                 "        <layer name=\"conv2\" type=\"Convolution\" precision=\"FP32\" id=\"3\">\n"
127                 "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"0\" pad-y=\"0\" kernel-x=\"5\" kernel-y=\"5\" output=\"50\" group=\"1\"/>\n"
128                 "            <input>\n"
129                 "                <port id=\"5\">\n"
130                 "                    <dim>1</dim>\n"
131                 "                    <dim>20</dim>\n"
132                 "                    <dim>12</dim>\n"
133                 "                    <dim>12</dim>\n"
134                 "                </port>\n"
135                 "            </input>\n"
136                 "            <output>\n"
137                 "                <port id=\"6\">\n"
138                 "                    <dim>1</dim>\n"
139                 "                    <dim>50</dim>\n"
140                 "                    <dim>8</dim>\n"
141                 "                    <dim>8</dim>\n"
142                 "                </port>\n"
143                 "            </output>\n"
144                 "            <weights offset=\"2080\" size=\"100000\"/>\n"
145                 "            <biases offset=\"102080\" size=\"200\"/>\n"
146                 "        </layer>\n"
147                 "        <layer name=\"pool2\" type=\"Pooling\" precision=\"FP32\" id=\"4\">\n"
148                 "            <pooling_data kernel-x=\"2\" kernel-y=\"2\" pad-x=\"0\" pad-y=\"0\" stride-x=\"2\" stride-y=\"2\" rounding-type=\"ceil\" pool-method=\"max\"/>\n"
149                 "            <input>\n"
150                 "                <port id=\"7\">\n"
151                 "                    <dim>1</dim>\n"
152                 "                    <dim>50</dim>\n"
153                 "                    <dim>8</dim>\n"
154                 "                    <dim>8</dim>\n"
155                 "                </port>\n"
156                 "            </input>\n"
157                 "            <output>\n"
158                 "                <port id=\"8\">\n"
159                 "                    <dim>1</dim>\n"
160                 "                    <dim>50</dim>\n"
161                 "                    <dim>4</dim>\n"
162                 "                    <dim>4</dim>\n"
163                 "                </port>\n"
164                 "            </output>\n"
165                 "        </layer>\n"
166                 "        <layer name=\"ip1\" type=\"FullyConnected\" precision=\"FP32\" id=\"5\">\n"
167                 "            <fc_data out-size=\"500\"/>\n"
168                 "            <input>\n"
169                 "                <port id=\"9\">\n"
170                 "                    <dim>1</dim>\n"
171                 "                    <dim>50</dim>\n"
172                 "                    <dim>4</dim>\n"
173                 "                    <dim>4</dim>\n"
174                 "                </port>\n"
175                 "            </input>\n"
176                 "            <output>\n"
177                 "                <port id=\"10\">\n"
178                 "                    <dim>1</dim>\n"
179                 "                    <dim>500</dim>\n"
180                 "                </port>\n"
181                 "            </output>\n"
182                 "            <weights offset=\"102280\" size=\"1600000\"/>\n"
183                 "            <biases offset=\"1702280\" size=\"2000\"/>\n"
184                 "        </layer>\n"
185                 "        <layer name=\"relu1\" type=\"ReLU\" precision=\"FP32\" id=\"6\">\n"
186                 "            <input>\n"
187                 "                <port id=\"11\">\n"
188                 "                    <dim>1</dim>\n"
189                 "                    <dim>500</dim>\n"
190                 "                </port>\n"
191                 "            </input>\n"
192                 "            <output>\n"
193                 "                <port id=\"12\">\n"
194                 "                    <dim>1</dim>\n"
195                 "                    <dim>500</dim>\n"
196                 "                </port>\n"
197                 "            </output>\n"
198                 "        </layer>\n"
199                 "        <layer name=\"ip2\" type=\"FullyConnected\" precision=\"FP32\" id=\"7\">\n"
200                 "            <fc_data out-size=\"10\"/>\n"
201                 "            <input>\n"
202                 "                <port id=\"13\">\n"
203                 "                    <dim>1</dim>\n"
204                 "                    <dim>500</dim>\n"
205                 "                </port>\n"
206                 "            </input>\n"
207                 "            <output>\n"
208                 "                <port id=\"14\">\n"
209                 "                    <dim>1</dim>\n"
210                 "                    <dim>10</dim>\n"
211                 "                </port>\n"
212                 "            </output>\n"
213                 "            <weights offset=\"1704280\" size=\"20000\"/>\n"
214                 "            <biases offset=\"1724280\" size=\"40\"/>\n"
215                 "        </layer>\n"
216                 "        <layer name=\"prob\" type=\"SoftMax\" precision=\"FP32\" id=\"8\">\n"
217                 "            <input>\n"
218                 "                <port id=\"15\">\n"
219                 "                    <dim>1</dim>\n"
220                 "                    <dim>10</dim>\n"
221                 "                </port>\n"
222                 "            </input>\n"
223                 "            <output>\n"
224                 "                <port id=\"16\">\n"
225                 "                    <dim>1</dim>\n"
226                 "                    <dim>10</dim>\n"
227                 "                </port>\n"
228                 "            </output>\n"
229                 "        </layer>\n"
230                 "    </layers>\n"
231                 "    <edges>\n"
232                 "        <edge from-layer=\"0\" from-port=\"0\" to-layer=\"1\" to-port=\"1\"/>\n"
233                 "        <edge from-layer=\"1\" from-port=\"2\" to-layer=\"2\" to-port=\"3\"/>\n"
234                 "        <edge from-layer=\"2\" from-port=\"4\" to-layer=\"3\" to-port=\"5\"/>\n"
235                 "        <edge from-layer=\"3\" from-port=\"6\" to-layer=\"4\" to-port=\"7\"/>\n"
236                 "        <edge from-layer=\"4\" from-port=\"8\" to-layer=\"5\" to-port=\"9\"/>\n"
237                 "        <edge from-layer=\"5\" from-port=\"10\" to-layer=\"6\" to-port=\"11\"/>\n"
238                 "        <edge from-layer=\"6\" from-port=\"12\" to-layer=\"7\" to-port=\"13\"/>\n"
239                 "        <edge from-layer=\"7\" from-port=\"14\" to-layer=\"8\" to-port=\"15\"/>\n"
240                 "    </edges>\n"
241                 "</net>";
242
243         size_t weights_size = 1724320;
244         net_reader.ReadNetwork(model.c_str(), model.size());
245
246         InferenceEngine::TBlob<uint8_t> *weights = new InferenceEngine::TBlob<uint8_t>(InferenceEngine::Precision::U8, InferenceEngine::C, {weights_size});
247         weights->allocate();
248         fill_data((float *) weights->buffer(), weights->size() / sizeof(float));
249         InferenceEngine::TBlob<uint8_t>::Ptr weights_ptr = InferenceEngine::TBlob<uint8_t>::Ptr(weights);
250
251         net_reader.SetWeights(weights_ptr);
252
253         auto outputs = net_reader.getNetwork().getOutputsInfo();
254         std::vector<std::string> new_outputs;
255
256         for (auto input : net_reader.getNetwork().getInputsInfo()) {
257             for (const auto &layer : input.second->getInputData()->getInputTo()) {
258                 addOutputToEachNode(net_reader, new_outputs, layer.second);
259             }
260         }
261
262         ASSERT_NE(1, net_reader.getNetwork().getOutputsInfo().size());
263
264         std::shared_ptr<MKLDNNTestEngine> score_engine(new MKLDNNTestEngine());
265         ASSERT_NO_THROW(score_engine->LoadNetwork(net_reader.getNetwork()));
266
267         size_t modified_outputs_size = score_engine->getGraph().GetOutputNodes().size();
268
269         InferenceEngine::CNNNetReader net_reader2;
270         net_reader2.ReadNetwork(model.c_str(), model.size());
271         net_reader2.SetWeights(weights_ptr);
272         ASSERT_EQ(1, net_reader2.getNetwork().getOutputsInfo().size());
273
274         ASSERT_NO_THROW(score_engine->LoadNetwork(net_reader2.getNetwork()));
275
276         size_t original_outputs_size = score_engine->getGraph().GetOutputNodes().size();
277
278         ASSERT_NE(modified_outputs_size, original_outputs_size);
279         ASSERT_EQ(1, original_outputs_size);
280     } catch (...) {
281         FAIL();
282     }
283 }