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