fce08b2dd5a9b55391bb0b2436ef818d48bfe7ea
[platform/upstream/dldt.git] / inference-engine / tests / unit / graph_tools / graph_copy_tests.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <gtest/gtest.h>
6 #include <inference_engine/graph_tools.hpp>
7 #include "test_assertions.hpp"
8 #include <unordered_set>
9 #include <gmock/gmock-generated-function-mockers.h>
10 #include <gmock/gmock-generated-matchers.h>
11 #include <gmock/gmock-more-actions.h>
12 #include "xml_father.hpp"
13 #include "ie_common.h"
14 #include "graph_test_base.hpp"
15 #include <memory>
16
17 #ifdef ENABLE_GNA
18 # include <gna_plugin/quantization/model_quantizer.hpp>
19 #endif
20
21 using namespace testing;
22 using namespace InferenceEngine;
23 using namespace std;
24 using namespace GraphTest;
25
26
27 class GraphCopyTests : public GraphTestsBase {
28
29 protected:
30     MockCopier mc;
31
32     void SetUp() override {
33         GraphTestsBase::_batchSize = 12;
34         GraphTestsBase::SetUp();
35         CONNECT(1, 2);
36         CONNECT(3, 4);
37         CONNECT(4, 2);
38         CONNECT(3, 5);
39         CONNECT(5, 2);
40
41         EXPECT_CALL(mockNet, getInputsInfo(_)).WillRepeatedly(WithArg<0>(Invoke([&](InputsDataMap &maps) {
42             prepareInputs(maps, 12);
43         })));
44
45         EXPECT_CALL(mockNet, getOutputsInfo(_)).WillRepeatedly(WithArg<0>(Invoke([&](OutputsDataMap &maps) {
46             prepareOutputs(maps);
47         })));
48
49         EXPECT_CALL(mockNet, getTargetDevice()).WillRepeatedly(Return(TargetDevice::eCPU));
50         EXPECT_CALL(mockNet, getPrecision()).WillRepeatedly(Return(Precision::FP16));
51         EXPECT_CALL(mockNet, getBatchSize()).WillRepeatedly(Return(12));
52         EXPECT_CALL(mockNet, getName(_, _)).WillRepeatedly(Invoke([](char *pName, size_t len) {
53             memcpy(pName, "nm", 3);
54         }));
55
56         EXPECT_CALL(mc, copyLayer(_)).WillRepeatedly(Invoke([](CNNLayerPtr ptr) {
57             return ptr;
58         }));
59     }
60 };
61
62 TEST_F(GraphCopyTests, copyNetworkPreserveBasicParams) {
63
64     auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
65
66     //network was copied not just assigned
67     ASSERT_NE(clone.get(), &mockNet);
68     ASSERT_EQ(clone->getTargetDevice(), TargetDevice::eCPU);
69     ASSERT_EQ(clone->getPrecision(), Precision::FP16);
70
71     char name[20];
72     clone->getName(name, sizeof(name));
73     ASSERT_STREQ(name, "nm");
74 }
75
76 TEST_F(GraphCopyTests, canPreserveBatchWhenCopyNetwork) {
77     auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
78     ASSERT_EQ(clone->getBatchSize(), 12);
79 }
80
81
82 TEST_F(GraphCopyTests, canPreserveInputs) {
83     auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
84
85     InputsDataMap inputs, inputsTarget;
86     InputsDataMap heads, headsTarget;
87
88     clone->getInputsInfo(inputs);
89     mockNet.getInputsInfo(inputsTarget);
90     ASSERT_INPUTS_INFO_EQ(inputs, inputsTarget);
91 }
92
93 TEST_F(GraphCopyTests, canPreserveOutputs) {
94
95     auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
96
97     OutputsDataMap outTarget, outSource;
98     clone->getOutputsInfo(outTarget);
99     mockNet.getOutputsInfo(outSource);
100
101     ASSERT_OUTPUTS_INFO_EQ(outSource, outTarget);
102 }
103
104 TEST_F(GraphCopyTests, canPreserveAttributes) {
105     auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
106     ADD_ATTR(1, "id", "r-1-2-3");
107     ADD_ATTR(2, "id", "r-1-2-3");
108
109     IE_SUPPRESS_DEPRECATED_START
110     CNNNetwork cloned (clone.get());
111     IE_SUPPRESS_DEPRECATED_END
112     auto idMemOutput = cloned.getLayerByName("1")->GetParamAsString("id");
113     auto idMemInput  = cloned.getLayerByName("2")->GetParamAsString("id");
114
115     ASSERT_STREQ(idMemInput.c_str(), idMemOutput.c_str());
116     ASSERT_STREQ(idMemInput.c_str(), "r-1-2-3");
117 }
118
119 TEST_F(GraphCopyTests, canPreserveGetData) {
120     auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
121
122     ASSERT_NE(clone->getData("1"), nullptr);
123     ASSERT_NE(clone->getData("2"), nullptr);
124     ASSERT_NE(clone->getData("3"), nullptr);
125     ASSERT_NE(clone->getData("4"), nullptr);
126     ASSERT_NE(clone->getData("5"), nullptr);
127 }
128
129 TEST_F(GraphCopyTests, canPreserveTopology) {
130     auto iclone = CNNNetCopy<MockCopier>(mockNet, mc);
131     auto clone = CNNNetwork(iclone);
132
133     ASSERT_EQ(clone.layerCount(), 5);
134
135     EXPECT_CALL(*this, visited(1, 0)).Times(1);
136     EXPECT_CALL(*this, visited(2, 1)).Times(1);
137
138     EXPECT_CALL(*this, visited2(3, 0)).Times(1);
139     EXPECT_CALL(*this, visited2(4, AnyOf(1, 2))).Times(1);
140     EXPECT_CALL(*this, visited2(5, AnyOf(1, 2))).Times(1);
141     EXPECT_CALL(*this, visited2(2, 3)).Times(1);
142
143     int idx = 0;
144     CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
145         visited(ID(layer), idx++);
146     });
147
148     idx = 0;
149     CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
150         visited2(ID(layer), idx++);
151     });
152 }
153
154 #ifdef ENABLE_GNA
155 using namespace GNAPluginNS;
156 struct _FP32_2_FP32  : public GNAPluginNS::details::QuantDescTmpl<float, float, float, float, float> {
157 };
158 using FP32_2_FP32 = GNAPluginNS::details::QuantPair<_FP32_2_FP32 , _FP32_2_FP32 >;
159
160 TEST_F(GraphCopyTests, canQuantizeTopology) {
161
162     auto iclone = ModelQuantizer<FP32_2_FP32>().quantize(mockNet, std::vector<float >({1.0f, 1.0f}));
163     auto clone = CNNNetwork(iclone);
164
165     CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
166         auto params = getInjectedData<QuantizedLayerParams>(layer);
167         ASSERT_NE(params, nullptr);
168     });
169
170     CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
171         auto params = getInjectedData<QuantizedLayerParams>(layer);
172         ASSERT_NE(params, nullptr);
173     });
174 }
175
176 #endif
177
178 TEST(CNNSpecificGraphCopyTests, copyNetworkWithClampLayer) {
179     CNNNetReader netReader;
180     //define minimal network with Clamp layer
181     const std::string SINGLE_LAYER_MODEL = R"V0G0N(
182     <net name="SingleLayer" version="2" batch="1">
183         <layers>
184                 <layer id="0" name="InputLayer" precision="FP16" type="Input">
185                         <output>
186                                 <port id="0">
187                                         <dim>1</dim>
188                                         <dim>3</dim>
189                                         <dim>224</dim>
190                                         <dim>224</dim>
191                                 </port>
192                         </output>
193                 </layer>
194                 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
195                     <data max="6" min="0"/>
196                     <input>
197                             <port id="0">
198                                     <dim>1</dim>
199                                     <dim>3</dim>
200                                     <dim>224</dim>
201                                     <dim>224</dim>
202                             </port>
203                     </input>
204                     <output>
205                             <port id="1">
206                                     <dim>1</dim>
207                                     <dim>3</dim>
208                                     <dim>224</dim>
209                                     <dim>224</dim>
210                             </port>
211                     </output>
212                 </layer>
213         </layers>
214         <edges>
215             <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
216         </edges>
217     </net>
218     )V0G0N";
219     ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
220     ASSERT_TRUE(netReader.isParseSuccess());
221     auto network = netReader.getNetwork();
222
223     //copy the network
224     struct EmptyStruct {};
225     auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
226     auto copied_net_ptr = CNNNetCopy(network, visitor);
227     IE_SUPPRESS_DEPRECATED_START
228     auto copied_net = CNNNetwork(copied_net_ptr.get());
229     IE_SUPPRESS_DEPRECATED_END
230
231     //check that Clamp layer was properly copied
232     auto layer = std::dynamic_pointer_cast<ClampLayer>(copied_net.getLayerByName("ClampLayer"));
233     ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Clamp layer pointer. "
234             "Net copy could be incorrect.";
235 }
236
237 TEST(CNNSpecificGraphCopyTests, copyPreprocess) {
238     CNNNetReader netReader;
239     //define minimal network with Clamp layer
240     const std::string SINGLE_LAYER_MODEL = R"V0G0N(
241     <net name="SingleLayer" version="2" batch="1">
242         <layers>
243                 <layer id="0" name="InputLayer" precision="FP16" type="Input">
244                         <output>
245                                 <port id="0">
246                                         <dim>1</dim>
247                                         <dim>3</dim>
248                                         <dim>224</dim>
249                                         <dim>224</dim>
250                                 </port>
251                         </output>
252                 </layer>
253                 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
254                     <data max="6" min="0"/>
255                     <input>
256                             <port id="0">
257                                     <dim>1</dim>
258                                     <dim>3</dim>
259                                     <dim>224</dim>
260                                     <dim>224</dim>
261                             </port>
262                     </input>
263                     <output>
264                             <port id="1">
265                                     <dim>1</dim>
266                                     <dim>3</dim>
267                                     <dim>224</dim>
268                                     <dim>224</dim>
269                             </port>
270                     </output>
271                 </layer>
272         </layers>
273         <edges>
274             <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
275         </edges>
276         <pre-process reference-layer-name="InputLayer">
277             <channel id="0">
278                 <mean value="104"/>
279             </channel>
280             <channel id="1">
281                 <mean value="116"/>
282             </channel>
283             <channel id="2">
284                 <mean value="122"/>
285             </channel>
286         </pre-process>
287     </net>
288     )V0G0N";
289     ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
290     ASSERT_TRUE(netReader.isParseSuccess());
291     auto network = netReader.getNetwork();
292
293     //copy the network
294     struct EmptyStruct {};
295     auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
296     auto copied_net_ptr = CNNNetCopy(network, visitor);
297     IE_SUPPRESS_DEPRECATED_START
298     auto copied_net = CNNNetwork(copied_net_ptr.get());
299     IE_SUPPRESS_DEPRECATED_END
300
301     //check that pre process Info existed in copied network
302     auto &pp = copied_net.getInputsInfo().begin()->second->getPreProcess();
303     ASSERT_EQ(MEAN_VALUE, pp.getMeanVariant());
304     ASSERT_EQ(3, pp.getNumberOfChannels());
305
306
307     ASSERT_FLOAT_EQ(pp[0]->meanValue, 104);
308     ASSERT_FLOAT_EQ(pp[1]->meanValue, 116);
309     ASSERT_FLOAT_EQ(pp[2]->meanValue, 122);
310 }
311
312 TEST(CNNSpecificGraphCopyTests, copyNetworkWithDeconvolution) {
313     CNNNetReader netReader;
314     //define minimal network with deconvolution layer
315     const std::string SINGLE_LAYER_MODEL = R"V0G0N(
316     <net name="SingleLayer" version="2" batch="1">
317         <layers>
318                 <layer id="0" name="InputLayer" precision="FP16" type="Input">
319                         <output>
320                                 <port id="0">
321                                         <dim>1</dim>
322                                         <dim>384</dim>
323                                         <dim>4</dim>
324                                         <dim>2</dim>
325                                 </port>
326                         </output>
327                 </layer>
328             <layer name="upsample_merged" type="Deconvolution" precision="FP16" id="1">
329             <deconvolution_data stride-x="2" stride-y="2" pad-x="1" pad-y="1" kernel-x="4" kernel-y="4" output="384" group="384"/>
330             <input>
331                 <port id="0">
332                     <dim>1</dim>
333                     <dim>384</dim>
334                     <dim>4</dim>
335                     <dim>2</dim>
336                 </port>
337             </input>
338             <output>
339                 <port id="1">
340                     <dim>1</dim>
341                     <dim>384</dim>
342                     <dim>8</dim>
343                     <dim>4</dim>
344                 </port>
345             </output>
346             <weights offset="5517824" size="12288"/>
347         </layer>
348         </layers>
349         <edges>
350             <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
351         </edges>
352     </net>
353     )V0G0N";
354     ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
355     ASSERT_TRUE(netReader.isParseSuccess());
356     auto network = netReader.getNetwork();
357
358     // copy the network
359     struct EmptyStruct {};
360     auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
361     auto copied_net_ptr = CNNNetCopy(network, visitor);
362     IE_SUPPRESS_DEPRECATED_START
363     auto copied_net = CNNNetwork(copied_net_ptr.get());
364     IE_SUPPRESS_DEPRECATED_END
365
366     // check that Clamp layer was properly copied
367     auto layer = std::dynamic_pointer_cast<DeconvolutionLayer>(copied_net.getLayerByName("upsample_merged"));
368     ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Deconvolution layer pointer. "
369                                  "Net copy could be incorrect.";
370 }