Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / inference_engine_tests / util_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
8 #include <initializer_list>
9 #include <string>
10 #include <utility>
11 #include <unordered_set>
12 #include <unordered_map>
13
14 #include <ie_util_internal.hpp>
15 #include <tests_common.hpp>
16 #include <graph_transformer.h>
17 #include "ie_utils.hpp"
18 #include "util_test.hpp"
19 #include "graph_tools.hpp"
20
21 namespace IE = InferenceEngine;
22
23 namespace {
24 bool checkLayers(const std::vector<IE::CNNLayerPtr>& layers, std::initializer_list<const char*> layersToCheck) {
25     if (layers.size() != layersToCheck.size()) {
26         return false;
27     }
28     for (auto&& layerToCheck: layersToCheck) {
29         bool found = false;
30         for (auto&& layer: layers) {
31             if (layerToCheck == layer->name) {
32                 found = true;
33                 break;
34             }
35         }
36         if (!found) {
37             return false;
38         }
39     }
40     return true;
41 }
42 }
43
44 TEST(UtilTests, contains) {
45     std::unordered_set<int> temp_set;
46     temp_set.insert(42);
47     EXPECT_TRUE(IE::contains(temp_set, 42));
48     EXPECT_FALSE(IE::contains(temp_set, 5));
49 }
50
51 TEST(UtilTests, groupSubraphsEmpty) {
52     auto net = NetBuilder().finalize();
53     auto subgraphs = IE::groupSubgraphs(*net,
54                                         [&](const IE::CNNLayerPtr&,
55                                             const IE::CNNLayerPtr&)
56     {
57         return false;
58     });
59     ASSERT_EQ(0, subgraphs.size());
60 }
61
62 TEST(UtilTests, groupSubraphsNoSplit) {
63     auto net = NetBuilder()
64                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
65                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
66                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
67                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
68                .data("data5",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
69                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
70                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
71                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
72                .layer<IE::CNNLayer>(IE::LayerParams{"layer4","dummy",IE::Precision::UNSPECIFIED})
73                .linkData("data1","data2","layer1")
74                .linkData("data2","data3","layer2")
75                .linkData("data3","data4","layer3")
76                .linkData("data4","data5","layer4")
77                .finalize();
78
79     auto subgraphs = IE::groupSubgraphs(*net,
80                                         [&](const IE::CNNLayerPtr&,
81                                             const IE::CNNLayerPtr&)
82     {
83         return false;
84     });
85     ASSERT_EQ(1, subgraphs.size());
86     ASSERT_TRUE(checkLayers(subgraphs.front(), {"layer1","layer2","layer3","layer4"}));
87 }
88
89 TEST(UtilTests, groupSubraphsAlwaysSplit) {
90     auto net = NetBuilder()
91                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
92                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
93                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
94                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
95                .data("data5",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
96                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
97                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
98                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
99                .layer<IE::CNNLayer>(IE::LayerParams{"layer4","dummy",IE::Precision::UNSPECIFIED})
100                .linkData("data1","data2","layer1")
101                .linkData("data2","data3","layer2")
102                .linkData("data3","data4","layer3")
103                .linkData("data4","data5","layer4")
104                .finalize();
105
106     auto subgraphs = IE::groupSubgraphs(*net,
107                                         [&](const IE::CNNLayerPtr&,
108                                             const IE::CNNLayerPtr&)
109     {
110         return true;
111     });
112     ASSERT_EQ(4, subgraphs.size());
113
114     for (auto&& it: net->allLayers()) {
115         auto& layer = it.second;
116         bool found = false;
117         for (auto&& subgraphLayer: subgraphs) {
118             ASSERT_EQ(1, subgraphLayer.size());
119             if (layer == subgraphLayer.front()) {
120                 found = true;
121                 break;
122             }
123         }
124         ASSERT_TRUE(found);
125     }
126 }
127
128 TEST(UtilTests, groupSubraphsUnconnectedSubgraphs) {
129     auto net = NetBuilder()
130                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
131                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
132                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
133                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
134                .data("data5",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
135                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
136                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
137                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
138                .linkData("data1","data2","layer1")
139                .linkData("data3","data4","layer2")
140                .linkData("data4","data5","layer3")
141                .finalize();
142
143     auto subgraphs = IE::groupSubgraphs(*net,
144                                         [&](const IE::CNNLayerPtr&,
145                                             const IE::CNNLayerPtr&)
146     {
147         return false;
148     });
149     ASSERT_EQ(2, subgraphs.size());
150
151     for (auto&& subgraph: subgraphs) {
152         if (1 == subgraph.size()) {
153             ASSERT_TRUE(checkLayers(subgraph, {"layer1"}));
154         }
155         else if (2 == subgraph.size()) {
156             ASSERT_TRUE(checkLayers(subgraph, {"layer2","layer3"}));
157         }
158         else {
159             FAIL();
160         }
161     }
162 }
163
164 TEST(UtilTests, groupSubraphsLinear) {
165     auto net = NetBuilder()
166                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
167                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
168                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
169                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
170                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
171                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
172                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
173                .linkData("data1","data2","layer1")
174                .linkData("data2","data3","layer2")
175                .linkData("data3","data4","layer3")
176                .finalize();
177
178     auto subgraphs = IE::groupSubgraphs(*net,
179                                         [&](const IE::CNNLayerPtr& layer1,
180                                             const IE::CNNLayerPtr& layer2)
181     {
182         if ("layer1" == layer1->name) {
183             EXPECT_EQ("layer2", layer2->name);
184             return true;
185         }
186         if ("layer2" == layer1->name) {
187             EXPECT_EQ("layer3", layer2->name);
188             return false;
189         }
190         else {
191             ADD_FAILURE();
192             return false;
193         }
194     });
195     ASSERT_EQ(2, subgraphs.size());
196
197     for (auto&& subgraph: subgraphs) {
198         if (1 == subgraph.size()) {
199             ASSERT_TRUE(checkLayers(subgraph, {"layer1"}));
200         }
201         else if (2 == subgraph.size()) {
202             ASSERT_TRUE(checkLayers(subgraph, {"layer2","layer3"}));
203         }
204         else {
205             FAIL();
206         }
207     }
208 }
209
210 TEST(UtilTests, groupSubraphsDeadBranch) {
211     //
212     // L1->L2->L3->L4->L5
213     //      \      /
214     //      L6 -> L7
215     //
216     // Split between L2 - L6 and L7 - L4
217     //
218     // Subgraphs:
219     // L1, L2, L3, L4, L5
220     // L6, L7
221     auto net = NetBuilder()
222                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
223                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
224                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
225                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
226                .data("data5",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
227                .data("data6",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
228                .data("data7",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
229                .data("data8",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
230                .data("data9",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
231                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
232                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
233                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
234                .layer<IE::CNNLayer>(IE::LayerParams{"layer4","dummy",IE::Precision::UNSPECIFIED})
235                .layer<IE::CNNLayer>(IE::LayerParams{"layer5","dummy",IE::Precision::UNSPECIFIED})
236                .layer<IE::CNNLayer>(IE::LayerParams{"layer6","dummy",IE::Precision::UNSPECIFIED})
237                .layer<IE::CNNLayer>(IE::LayerParams{"layer7","dummy",IE::Precision::UNSPECIFIED})
238                .linkData("data1","data2","layer1")
239                .linkData("data2","data3","layer2")
240                .linkData("data3","data4","layer3")
241                .linkData("data4","data5","layer4")
242                .linkData("data5","data6","layer5")
243
244                .linkLayers("layer2", "layer6", "data7")
245                .linkLayers("layer6", "layer7", "data8")
246                .linkLayers("layer7", "layer4", "data9")
247
248                .finalize();
249
250     auto subgraphs = IE::groupSubgraphs(*net,
251                                         [&](const IE::CNNLayerPtr& layer1,
252                                             const IE::CNNLayerPtr& layer2)
253     {
254         if ("layer2" == layer1->name) {
255             if ("layer3" == layer2->name) {
256                 return false;
257             }
258             else if ("layer6" == layer2->name) {
259                 return true;
260             }
261             else {
262                 ADD_FAILURE();
263             }
264         }
265
266         if ("layer7" == layer1->name) {
267             EXPECT_EQ("layer4", layer2->name);
268             return true;
269         }
270         return false;
271     });
272     ASSERT_EQ(2, subgraphs.size());
273
274     for (auto&& subgraph: subgraphs) {
275         if (5 == subgraph.size()) {
276             ASSERT_TRUE(checkLayers(subgraph, {"layer1","layer2","layer3","layer4","layer5"}));
277         }
278         else if (2 == subgraph.size()) {
279             ASSERT_TRUE(checkLayers(subgraph, {"layer6","layer7"}));
280         }
281         else {
282             FAIL();
283         }
284     }
285 }
286
287 TEST(UtilTests, cloneData) {
288     IE::Data srcData("test",IE::SizeVector{1,2,3},IE::Precision::FP32,IE::CHW);
289     IE::CNNLayerPtr layer1 = std::make_shared<IE::CNNLayer>(IE::LayerParams{});
290     IE::CNNLayerPtr layer2 = std::make_shared<IE::CNNLayer>(IE::LayerParams{});
291     srcData.getCreatorLayer() = layer1;
292     srcData.getInputTo().insert({"foo",layer2});
293     auto cloned = IE::cloneData(srcData);
294     ASSERT_NE(nullptr, cloned);
295     EXPECT_EQ(srcData.getName(), cloned->getName());
296     EXPECT_EQ(srcData.getPrecision(), cloned->getPrecision());
297     EXPECT_EQ(srcData.getLayout(), cloned->getLayout());
298     EXPECT_EQ(srcData.getDims(), cloned->getDims());
299     EXPECT_EQ(nullptr, cloned->getCreatorLayer().lock());
300     EXPECT_TRUE(cloned->getInputTo().empty());
301 }
302
303 namespace {
304 template<typename T>
305 bool checkLayerCloning() {
306     T srcLayer(IE::LayerParams{"layer","dummy",IE::Precision::FP32});
307     auto cloned = IE::clonelayer(srcLayer);
308     return nullptr != std::dynamic_pointer_cast<T>(cloned);
309 }
310 }
311
312 TEST(UtilTests, cloneLayers) {
313     {
314         IE::CNNLayer srclayer(IE::LayerParams{"layer","dummy",IE::Precision::FP32});
315         auto data1 = std::make_shared<IE::Data>("data1",IE::Precision::FP32);
316         auto data2 = std::make_shared<IE::Data>("data1",IE::Precision::FP32);
317         srclayer.insData.push_back(data1);
318         srclayer.outData.push_back(data2);
319         int dummy = 123;
320         srclayer.userValue.v_ptr = &dummy;
321         srclayer.params["foo"] = "1";
322         srclayer.params["bar"] = "2";
323         auto blob = std::make_shared<IE::TBlob<float>>(IE::Precision::FP32, IE::NCHW);
324         srclayer.blobs["baz"] = blob;
325         auto cloned = IE::clonelayer(srclayer);
326         ASSERT_NE(nullptr, cloned);
327         EXPECT_EQ(srclayer.name, cloned->name);
328         EXPECT_EQ(srclayer.type, cloned->type);
329         EXPECT_EQ(srclayer.precision, cloned->precision);
330         EXPECT_EQ(srclayer.userValue.v_ptr, cloned->userValue.v_ptr);
331         EXPECT_EQ(srclayer.params, cloned->params);
332         EXPECT_EQ(srclayer.blobs, cloned->blobs);
333         EXPECT_EQ(0, cloned->insData.size());
334         EXPECT_EQ(0, cloned->outData.size());
335     }
336     EXPECT_TRUE(checkLayerCloning<IE::BatchNormalizationLayer>());
337     EXPECT_TRUE(checkLayerCloning<IE::PowerLayer             >());
338     EXPECT_TRUE(checkLayerCloning<IE::ScaleShiftLayer        >());
339     EXPECT_TRUE(checkLayerCloning<IE::TileLayer              >());
340     EXPECT_TRUE(checkLayerCloning<IE::ReshapeLayer           >());
341     EXPECT_TRUE(checkLayerCloning<IE::CropLayer              >());
342     EXPECT_TRUE(checkLayerCloning<IE::EltwiseLayer           >());
343     EXPECT_TRUE(checkLayerCloning<IE::ClampLayer             >());
344     EXPECT_TRUE(checkLayerCloning<IE::ReLULayer              >());
345     EXPECT_TRUE(checkLayerCloning<IE::SoftMaxLayer           >());
346     EXPECT_TRUE(checkLayerCloning<IE::GRNLayer               >());
347     EXPECT_TRUE(checkLayerCloning<IE::NormLayer              >());
348     EXPECT_TRUE(checkLayerCloning<IE::SplitLayer             >());
349     EXPECT_TRUE(checkLayerCloning<IE::ConcatLayer            >());
350     EXPECT_TRUE(checkLayerCloning<IE::FullyConnectedLayer    >());
351     EXPECT_TRUE(checkLayerCloning<IE::PoolingLayer           >());
352     EXPECT_TRUE(checkLayerCloning<IE::DeconvolutionLayer     >());
353     EXPECT_TRUE(checkLayerCloning<IE::ConvolutionLayer       >());
354     EXPECT_TRUE(checkLayerCloning<IE::WeightableLayer        >());
355     EXPECT_TRUE(checkLayerCloning<IE::CNNLayer               >());
356 }
357
358 namespace {
359 IE::CNNLayerPtr getLayer(const IE::details::CNNNetworkImplPtr n,
360                          const char* name) {
361     if (IE::contains(n->allLayers(), name)) {
362         return n->allLayers().find(name)->second;
363     }
364     return nullptr;
365 };
366 } // namespace
367
368 TEST(UtilTests, cloneNet) {
369     //
370     //      I      O
371     //       \    /
372     // I-L1->L2->L3->L4->L5->O
373     //        \      /
374     //        L6 -> L7
375     //
376     auto net = NetBuilder()
377                 // input is 4d to allow setting of batch, otherwise, CHW notation doesnt have batches
378                .data("data1",IE::SizeVector{1,1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::NCHW)
379                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
380                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
381                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
382                .data("data5",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
383                .data("data6",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
384                .data("data7",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
385                .data("data8",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
386                .data("data9",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
387                .data("data10",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
388                .data("data11",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
389                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::Q78})
390                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
391                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
392                .layer<IE::CNNLayer>(IE::LayerParams{"layer4","dummy",IE::Precision::UNSPECIFIED})
393                .layer<IE::CNNLayer>(IE::LayerParams{"layer5","dummy",IE::Precision::UNSPECIFIED})
394                .layer<IE::CNNLayer>(IE::LayerParams{"layer6","dummy",IE::Precision::UNSPECIFIED})
395                .layer<IE::CNNLayer>(IE::LayerParams{"layer7","dummy",IE::Precision::UNSPECIFIED})
396                .linkData("data1","data2","layer1")
397                .linkData("data2","data3","layer2")
398                .linkData("data3","data4","layer3")
399                .linkData("data4","data5","layer4")
400                .linkData("data5","data6","layer5")
401
402                .linkLayers("layer2", "layer6", "data7")
403                .linkLayers("layer6", "layer7", "data8")
404                .linkLayers("layer7", "layer4", "data9")
405
406                .linkDataTo("data10","layer2")
407                .linkToData("layer3","data11")
408
409                .finalize();
410
411     net->setPrecision(IE::Precision::Q78);
412     net->setBatchSize(42);
413     net->setName("net");
414     net->setTargetDevice(IE::TargetDevice::eHETERO);
415
416     {
417         IE::InputsDataMap inputs;
418         net->getInputsInfo(inputs);
419         for (auto &&it : inputs) {
420             it.second->getPreProcess().init(1);
421             it.second->getPreProcess().setMeanImage(IE::make_shared_blob<float>(IE::Precision::FP32, IE::Layout::CHW, {1,1,1}));
422             it.second->getPreProcess().setResizeAlgorithm(IE::ResizeAlgorithm::RESIZE_BILINEAR);
423         }
424     }
425
426     {
427         auto layer = getLayer(net, "layer1");
428         auto cloned = IE::cloneNet({layer}, nullptr);
429         EXPECT_EQ(2, cloned->layerCount());
430         auto clonedLayer = getLayer(cloned, "layer1");
431         ASSERT_NE(nullptr, clonedLayer);
432         EXPECT_EQ(layer->type, clonedLayer->type);
433
434         IE::InputsDataMap inputs;
435         IE::OutputsDataMap outputs;
436         cloned->getInputsInfo(inputs);
437         cloned->getOutputsInfo(outputs);
438         ASSERT_EQ(1, inputs.size());
439         ASSERT_EQ(1, outputs.size());
440         EXPECT_TRUE(IE::contains(inputs,"data1"));
441         EXPECT_TRUE(IE::contains(outputs,"data2"));
442     }
443     {
444         auto layer1 = getLayer(net, "layer1");
445         auto layer2 = getLayer(net, "layer2");
446         auto cloned = IE::cloneNet({layer1,layer2}, nullptr);
447         EXPECT_EQ(4, cloned->layerCount());
448         auto clonedLayer1 = getLayer(cloned, "layer1");
449         auto clonedLayer2 = getLayer(cloned, "layer2");
450         ASSERT_NE(nullptr, clonedLayer1);
451         ASSERT_NE(nullptr, clonedLayer2);
452
453         IE::InputsDataMap inputs;
454         IE::OutputsDataMap outputs;
455         cloned->getInputsInfo(inputs);
456         cloned->getOutputsInfo(outputs);
457         ASSERT_EQ(2, inputs.size());
458         ASSERT_EQ(2, outputs.size());
459         EXPECT_TRUE(IE::contains(inputs,"data1"));
460         EXPECT_TRUE(IE::contains(inputs,"data10"));
461         EXPECT_TRUE(IE::contains(outputs,"data3"));
462         EXPECT_TRUE(IE::contains(outputs,"data7"));
463     }
464     {
465         auto layer4 = getLayer(net, "layer4");
466         auto layer5 = getLayer(net, "layer5");
467         auto cloned = IE::cloneNet({layer4,layer5}, nullptr);
468         EXPECT_EQ(4, cloned->layerCount());
469         auto clonedLayer4 = getLayer(cloned, "layer4");
470         auto clonedLayer5 = getLayer(cloned, "layer5");
471         ASSERT_NE(nullptr, clonedLayer4);
472         ASSERT_NE(nullptr, clonedLayer5);
473
474         ASSERT_EQ(2, clonedLayer4->insData.size());
475         ASSERT_EQ(1, clonedLayer4->outData.size());
476
477         EXPECT_EQ("data4", clonedLayer4->insData[0].lock()->getName());
478         EXPECT_EQ("data9", clonedLayer4->insData[1].lock()->getName());
479         EXPECT_EQ("data5", clonedLayer4->outData[0]->getName());
480
481         ASSERT_EQ(1, clonedLayer5->insData.size());
482         ASSERT_EQ(1, clonedLayer5->outData.size());
483
484         EXPECT_EQ("data5", clonedLayer5->insData[0].lock()->getName());
485         EXPECT_EQ("data6", clonedLayer5->outData[0]->getName());
486
487         IE::InputsDataMap inputs;
488         IE::OutputsDataMap outputs;
489         cloned->getInputsInfo(inputs);
490         cloned->getOutputsInfo(outputs);
491         ASSERT_EQ(2, inputs.size());
492         ASSERT_EQ(1, outputs.size());
493         EXPECT_TRUE(IE::contains(inputs,"data4"));
494         EXPECT_TRUE(IE::contains(inputs,"data9"));
495         EXPECT_TRUE(IE::contains(outputs,"data6"));
496     }
497     {
498         auto layer3 = getLayer(net, "layer3");
499         auto cloned = IE::cloneNet({layer3}, nullptr);
500         EXPECT_EQ(2, cloned->layerCount());
501         auto clonedLayer3 = getLayer(cloned, "layer3");
502         ASSERT_NE(nullptr, clonedLayer3);
503
504         ASSERT_EQ(1, clonedLayer3->insData.size());
505         ASSERT_EQ(2, clonedLayer3->outData.size());
506
507         EXPECT_EQ("data3", clonedLayer3->insData[0].lock()->getName());
508         EXPECT_EQ("data4", clonedLayer3->outData[0]->getName());
509         EXPECT_EQ("data11", clonedLayer3->outData[1]->getName());
510
511         IE::InputsDataMap inputs;
512         IE::OutputsDataMap outputs;
513         cloned->getInputsInfo(inputs);
514         cloned->getOutputsInfo(outputs);
515         ASSERT_EQ(1, inputs.size());
516         ASSERT_EQ(2, outputs.size());
517         EXPECT_TRUE(IE::contains(inputs,"data3"));
518         EXPECT_TRUE(IE::contains(outputs,"data4"));
519         EXPECT_TRUE(IE::contains(outputs,"data11"));
520     }
521     {
522         auto layer1 = getLayer(net, "layer1");
523         auto layer2 = getLayer(net, "layer2");
524         auto layer3 = getLayer(net, "layer3");
525         auto layer4 = getLayer(net, "layer4");
526         auto layer5 = getLayer(net, "layer5");
527         auto layer6 = getLayer(net, "layer6");
528         auto layer7 = getLayer(net, "layer7");
529         auto cloned = IE::cloneNet({layer1,layer2,layer3,layer4,layer5,layer6,layer7}, nullptr);
530         EXPECT_EQ(9, cloned->layerCount());
531         auto clonedLayer1 = getLayer(cloned, "layer1");
532         auto clonedLayer2 = getLayer(cloned, "layer2");
533         auto clonedLayer3 = getLayer(cloned, "layer3");
534         auto clonedLayer4 = getLayer(cloned, "layer4");
535         auto clonedLayer5 = getLayer(cloned, "layer5");
536         auto clonedLayer6 = getLayer(cloned, "layer6");
537         auto clonedLayer7 = getLayer(cloned, "layer7");
538         ASSERT_NE(nullptr, clonedLayer1);
539         ASSERT_NE(nullptr, clonedLayer2);
540         ASSERT_NE(nullptr, clonedLayer3);
541         ASSERT_NE(nullptr, clonedLayer4);
542         ASSERT_NE(nullptr, clonedLayer5);
543         ASSERT_NE(nullptr, clonedLayer6);
544         ASSERT_NE(nullptr, clonedLayer7);
545
546         ASSERT_EQ(1, clonedLayer1->insData.size());
547         ASSERT_EQ(1, clonedLayer1->outData.size());
548         EXPECT_EQ("data1", clonedLayer1->insData[0].lock()->getName());
549         EXPECT_EQ("data2", clonedLayer1->outData[0]->getName());
550
551         ASSERT_EQ(2, clonedLayer2->insData.size());
552         ASSERT_EQ(2, clonedLayer2->outData.size());
553         EXPECT_EQ("data2", clonedLayer2->insData[0].lock()->getName());
554         EXPECT_EQ("data10", clonedLayer2->insData[1].lock()->getName());
555         EXPECT_EQ("data3", clonedLayer2->outData[0]->getName());
556         EXPECT_EQ("data7", clonedLayer2->outData[1]->getName());
557
558         ASSERT_EQ(1, clonedLayer3->insData.size());
559         ASSERT_EQ(2, clonedLayer3->outData.size());
560         EXPECT_EQ("data3", clonedLayer3->insData[0].lock()->getName());
561         EXPECT_EQ("data4", clonedLayer3->outData[0]->getName());
562         EXPECT_EQ("data11", clonedLayer3->outData[1]->getName());
563
564         ASSERT_EQ(2, clonedLayer4->insData.size());
565         ASSERT_EQ(1, clonedLayer4->outData.size());
566         EXPECT_EQ("data4", clonedLayer4->insData[0].lock()->getName());
567         EXPECT_EQ("data9", clonedLayer4->insData[1].lock()->getName());
568         EXPECT_EQ("data5", clonedLayer4->outData[0]->getName());
569
570         ASSERT_EQ(1, clonedLayer5->insData.size());
571         ASSERT_EQ(1, clonedLayer5->outData.size());
572         EXPECT_EQ("data5", clonedLayer5->insData[0].lock()->getName());
573         EXPECT_EQ("data6", clonedLayer5->outData[0]->getName());
574
575         ASSERT_EQ(1, clonedLayer6->insData.size());
576         ASSERT_EQ(1, clonedLayer6->outData.size());
577         EXPECT_EQ("data7", clonedLayer6->insData[0].lock()->getName());
578         EXPECT_EQ("data8", clonedLayer6->outData[0]->getName());
579
580         ASSERT_EQ(1, clonedLayer7->insData.size());
581         ASSERT_EQ(1, clonedLayer7->outData.size());
582         EXPECT_EQ("data8", clonedLayer7->insData[0].lock()->getName());
583         EXPECT_EQ("data9", clonedLayer7->outData[0]->getName());
584
585         IE::InputsDataMap inputs;
586         IE::OutputsDataMap outputs;
587         cloned->getInputsInfo(inputs);
588         cloned->getOutputsInfo(outputs);
589         ASSERT_EQ(2, inputs.size());
590         ASSERT_EQ(2, outputs.size());
591         EXPECT_TRUE(IE::contains(inputs,"data1"));
592         EXPECT_TRUE(IE::contains(inputs,"data10"));
593         EXPECT_TRUE(IE::contains(outputs,"data11"));
594         EXPECT_TRUE(IE::contains(outputs,"data6"));
595     }
596     {
597         auto cloned = IE::cloneNet(*net);
598         auto layer1 = getLayer(cloned, "layer1");
599         auto layer2 = getLayer(cloned, "layer2");
600         EXPECT_TRUE(IE::Precision::Q78          == layer1->precision);
601         EXPECT_TRUE(IE::Precision::UNSPECIFIED  == layer2->precision);
602     }
603     {
604         auto cloned = IE::cloneNet(*net);
605         EXPECT_TRUE(IE::Precision::Q78        == cloned->getPrecision());
606         EXPECT_EQ(42,                            cloned->getBatchSize());
607         EXPECT_EQ("net",                         cloned->getName());
608         EXPECT_TRUE(IE::TargetDevice::eHETERO == cloned->getTargetDevice());
609     }
610     {
611         auto cloned = IE::cloneNet(*net);
612         IE::InputsDataMap clonedInputs;
613         cloned->getInputsInfo(clonedInputs);
614         for (auto &&clonedInput : clonedInputs) {
615            EXPECT_EQ(1,                                        clonedInput.second->getPreProcess().getNumberOfChannels());
616            EXPECT_TRUE(IE::MeanVariant::MEAN_IMAGE          == clonedInput.second->getPreProcess().getMeanVariant());
617            EXPECT_TRUE(IE::ResizeAlgorithm::RESIZE_BILINEAR == clonedInput.second->getPreProcess().getResizeAlgorithm());
618         }
619     }
620 }
621
622 TEST(UtilTests, cloneNet_input) {
623     //
624     // I1-d1-L1
625     //
626     // I2-d2
627     //      \
628     //       L2
629     //      /
630     // I3-d3
631     //      \
632     //       L3
633     //
634     auto net = NetBuilder()
635                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
636                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
637                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
638                .layer<IE::CNNLayer>(IE::LayerParams{"input1","input",IE::Precision::UNSPECIFIED})
639                .layer<IE::CNNLayer>(IE::LayerParams{"input2","Input",IE::Precision::UNSPECIFIED})
640                .layer<IE::CNNLayer>(IE::LayerParams{"input3","input",IE::Precision::UNSPECIFIED})
641                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
642                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
643                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
644
645                .linkToData("input1", "data1")
646                .linkToData("input2", "data2")
647                .linkToData("input3", "data3")
648
649                .linkDataTo("data1", "layer1")
650                .linkDataTo("data2", "layer2")
651                .linkDataTo("data3", "layer2")
652                .linkDataTo("data3", "layer3")
653
654                .finalize();
655
656     getLayer(net, "input1")->params["custom_param1"] = "custom_val1";
657     getLayer(net, "input2")->params["custom_param2"] = "custom_val2";
658     getLayer(net, "input3")->params["custom_param3"] = "custom_val3";
659
660     auto cloned = IE::cloneNet({getLayer(net, "layer1"),
661                                 getLayer(net, "layer2"),
662                                 getLayer(net, "layer3")}, nullptr);
663
664     ASSERT_EQ(6, cloned->layerCount());
665     ASSERT_NE(nullptr, getLayer(cloned, "input1"));
666     ASSERT_NE(nullptr, getLayer(cloned, "input2"));
667     ASSERT_NE(nullptr, getLayer(cloned, "input3"));
668     ASSERT_EQ("input", getLayer(cloned, "input1")->type);
669     ASSERT_EQ("Input", getLayer(cloned, "input2")->type);
670     ASSERT_EQ("input", getLayer(cloned, "input3")->type);
671     ASSERT_EQ("custom_val1", getLayer(cloned, "input1")->params["custom_param1"]);
672     ASSERT_EQ("custom_val2", getLayer(cloned, "input2")->params["custom_param2"]);
673     ASSERT_EQ("custom_val3", getLayer(cloned, "input3")->params["custom_param3"]);
674 }
675
676 TEST(UtilTests, cloneNet_const) {
677     //
678     // C1-d1-L1
679     //
680     // C2-d2
681     //      \
682     //       L2
683     //      /
684     // C3-d3
685     //      \
686     //       L3
687     //
688     auto net = NetBuilder()
689                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
690                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
691                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
692                .layer<IE::CNNLayer>(IE::LayerParams{"input1","const",IE::Precision::UNSPECIFIED})
693                .layer<IE::CNNLayer>(IE::LayerParams{"input2","Const",IE::Precision::UNSPECIFIED})
694                .layer<IE::CNNLayer>(IE::LayerParams{"input3","const",IE::Precision::UNSPECIFIED})
695                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
696                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
697                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
698
699                .linkToData("input1", "data1")
700                .linkToData("input2", "data2")
701                .linkToData("input3", "data3")
702
703                .linkDataTo("data1", "layer1")
704                .linkDataTo("data2", "layer2")
705                .linkDataTo("data3", "layer2")
706                .linkDataTo("data3", "layer3")
707
708                .finalize();
709
710     getLayer(net, "input1")->params["custom_param1"] = "custom_val1";
711     getLayer(net, "input2")->params["custom_param2"] = "custom_val2";
712     getLayer(net, "input3")->params["custom_param3"] = "custom_val3";
713
714     auto cloned = IE::cloneNet({getLayer(net, "layer1"),
715                                 getLayer(net, "layer2"),
716                                 getLayer(net, "layer3")}, nullptr);
717
718     ASSERT_EQ(6, cloned->layerCount());
719     ASSERT_NE(nullptr, getLayer(cloned, "input1"));
720     ASSERT_NE(nullptr, getLayer(cloned, "input2"));
721     ASSERT_NE(nullptr, getLayer(cloned, "input3"));
722     ASSERT_EQ("const", getLayer(cloned, "input1")->type);
723     ASSERT_EQ("Const", getLayer(cloned, "input2")->type);
724     ASSERT_EQ("const", getLayer(cloned, "input3")->type);
725     ASSERT_EQ("custom_val1", getLayer(cloned, "input1")->params["custom_param1"]);
726     ASSERT_EQ("custom_val2", getLayer(cloned, "input2")->params["custom_param2"]);
727     ASSERT_EQ("custom_val3", getLayer(cloned, "input3")->params["custom_param3"]);
728 }
729
730 TEST(UtilTests, getRootDataObjects) {
731     //
732     // I1-d1-L1-d7
733     //            \
734     // I2-d2       L6
735     //      \     /
736     //       L2-d8
737     //      /
738     // I3-d3
739     //      \
740     //       L3
741     //      /
742     // C1-d4
743     //      \
744     //       L4-d9
745     //      /     \
746     // C2-d5       L7
747     //            /
748     // C3-d6-L5-d10
749     auto net = NetBuilder()
750                .data("data1",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
751                .data("data2",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
752                .data("data3",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
753                .data("data4",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
754                .data("data5",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
755                .data("data6",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
756                .data("data7",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
757                .data("data8",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
758                .data("data9",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
759                .data("data10",IE::SizeVector{1,1,1},IE::Precision::UNSPECIFIED, IE::Layout::CHW)
760                .layer<IE::CNNLayer>(IE::LayerParams{"input1","input",IE::Precision::UNSPECIFIED})
761                .layer<IE::CNNLayer>(IE::LayerParams{"input2","Input",IE::Precision::UNSPECIFIED})
762                .layer<IE::CNNLayer>(IE::LayerParams{"input3","input",IE::Precision::UNSPECIFIED})
763                .layer<IE::CNNLayer>(IE::LayerParams{"const1","const",IE::Precision::UNSPECIFIED})
764                .layer<IE::CNNLayer>(IE::LayerParams{"const2","Const",IE::Precision::UNSPECIFIED})
765                .layer<IE::CNNLayer>(IE::LayerParams{"const3","const",IE::Precision::UNSPECIFIED})
766                .layer<IE::CNNLayer>(IE::LayerParams{"layer1","dummy",IE::Precision::UNSPECIFIED})
767                .layer<IE::CNNLayer>(IE::LayerParams{"layer2","dummy",IE::Precision::UNSPECIFIED})
768                .layer<IE::CNNLayer>(IE::LayerParams{"layer3","dummy",IE::Precision::UNSPECIFIED})
769                .layer<IE::CNNLayer>(IE::LayerParams{"layer4","dummy",IE::Precision::UNSPECIFIED})
770                .layer<IE::CNNLayer>(IE::LayerParams{"layer5","dummy",IE::Precision::UNSPECIFIED})
771                .layer<IE::CNNLayer>(IE::LayerParams{"layer6","dummy",IE::Precision::UNSPECIFIED})
772                .layer<IE::CNNLayer>(IE::LayerParams{"layer7","dummy",IE::Precision::UNSPECIFIED})
773
774                .linkToData("input1", "data1")
775                .linkToData("input2", "data2")
776                .linkToData("input3", "data3")
777
778                .linkToData("const1", "data4")
779                .linkToData("const2", "data5")
780                .linkToData("const3", "data6")
781
782                .linkDataTo("data1", "layer1")
783                .linkDataTo("data2", "layer2")
784                .linkDataTo("data3", "layer2")
785                .linkDataTo("data3", "layer3")
786
787                .linkDataTo("data4", "layer3")
788                .linkDataTo("data4", "layer4")
789                .linkDataTo("data5", "layer4")
790                .linkDataTo("data6", "layer5")
791
792                .linkToData("layer1", "data7")
793                .linkToData("layer2", "data8")
794                .linkToData("layer4", "data9")
795                .linkToData("layer5", "data10")
796
797                .linkDataTo("data7", "layer6")
798                .linkDataTo("data8", "layer6")
799
800                .linkDataTo("data9", "layer7")
801                .linkDataTo("data10", "layer7")
802
803                .addInput("data1")
804                .addInput("data2")
805                .addInput("data3")
806
807                .finalize();
808
809     auto cloned = IE::cloneNet(*net);
810
811     ASSERT_EQ(13, cloned->layerCount());
812     auto root_data = IE::getRootDataObjects(*cloned);
813     ASSERT_EQ(6, root_data.size());
814     std::unordered_set<std::string> data_names;
815     for (auto& data : root_data) {
816         data_names.insert(data->name);
817     }
818     ASSERT_TRUE(IE::contains(data_names, "data1"));
819     ASSERT_TRUE(IE::contains(data_names, "data2"));
820     ASSERT_TRUE(IE::contains(data_names, "data3"));
821     ASSERT_TRUE(IE::contains(data_names, "data4"));
822     ASSERT_TRUE(IE::contains(data_names, "data5"));
823     ASSERT_TRUE(IE::contains(data_names, "data6"));
824 }
825
826 TEST(UtilTests, networkComplexity) {
827     std::string model =
828             "<net name=\"Top\" version=\"2\" batch=\"1\">"
829             "    <layers>"
830             "        <layer name=\"data\" type=\"Input\" precision=\"FP32\" id=\"0\">"
831             "            <output>"
832             "                <port id=\"0\">"
833             "                    <dim>1</dim>"
834             "                    <dim>3</dim>"
835             "                    <dim>227</dim>"
836             "                    <dim>227</dim>"
837             "                </port>"
838             "            </output>"
839             "        </layer>"
840             "        <layer name=\"conv1\" type=\"Convolution\" precision=\"FP32\" id=\"1\">"
841             "            <convolution_data stride-x=\"4\" stride-y=\"4\" pad-x=\"0\" pad-y=\"0\" kernel-x=\"11\" kernel-y=\"11\" output=\"96\" group=\"1\"/>"
842             "            <input>"
843             "                <port id=\"1\">"
844             "                    <dim>1</dim>"
845             "                    <dim>3</dim>"
846             "                    <dim>227</dim>"
847             "                    <dim>227</dim>"
848             "                </port>"
849             "            </input>"
850             "            <output>"
851             "                <port id=\"2\">"
852             "                    <dim>1</dim>"
853             "                    <dim>96</dim>"
854             "                    <dim>55</dim>"
855             "                    <dim>55</dim>"
856             "                </port>"
857             "            </output>"
858             "            <weights offset=\"0\" size=\"139392\"/>"
859             "            <biases offset=\"139392\" size=\"384\"/>"
860             "        </layer>"
861             "        <layer name=\"relu1\" type=\"ReLU\" precision=\"FP32\" id=\"2\">"
862             "            <input>"
863             "                <port id=\"3\">"
864             "                    <dim>1</dim>"
865             "                    <dim>96</dim>"
866             "                    <dim>55</dim>"
867             "                    <dim>55</dim>"
868             "                </port>"
869             "            </input>"
870             "            <output>"
871             "                <port id=\"4\">"
872             "                    <dim>1</dim>"
873             "                    <dim>96</dim>"
874             "                    <dim>55</dim>"
875             "                    <dim>55</dim>"
876             "                </port>"
877             "            </output>"
878             "        </layer>"
879             "        <layer name=\"norm1\" type=\"Norm\" precision=\"FP32\" id=\"3\">"
880             "            <norm_data alpha=\"9.9999997e-05\" beta=\"0.75\" local-size=\"5\" region=\"across\"/>"
881             "            <input>"
882             "                <port id=\"5\">"
883             "                    <dim>1</dim>"
884             "                    <dim>96</dim>"
885             "                    <dim>55</dim>"
886             "                    <dim>55</dim>"
887             "                </port>"
888             "            </input>"
889             "            <output>"
890             "                <port id=\"6\">"
891             "                    <dim>1</dim>"
892             "                    <dim>96</dim>"
893             "                    <dim>55</dim>"
894             "                    <dim>55</dim>"
895             "                </port>"
896             "            </output>"
897             "        </layer>"
898             "        <layer name=\"pool1\" type=\"Pooling\" precision=\"FP32\" id=\"4\">"
899             "            <pooling_data kernel-x=\"3\" kernel-y=\"3\" pad-x=\"0\" pad-y=\"0\" stride-x=\"2\" stride-y=\"2\" rounding-type=\"ceil\" pool-method=\"max\"/>"
900             "            <input>"
901             "                <port id=\"7\">"
902             "                    <dim>1</dim>"
903             "                    <dim>96</dim>"
904             "                    <dim>55</dim>"
905             "                    <dim>55</dim>"
906             "                </port>"
907             "            </input>"
908             "            <output>"
909             "                <port id=\"8\">"
910             "                    <dim>1</dim>"
911             "                    <dim>96</dim>"
912             "                    <dim>27</dim>"
913             "                    <dim>27</dim>"
914             "                </port>"
915             "            </output>"
916             "        </layer>"
917             "        <layer name=\"conv2_split\" type=\"Split\" precision=\"FP32\" id=\"24\">"
918             "            <input>"
919             "                <port id=\"47\">"
920             "                    <dim>1</dim>"
921             "                    <dim>96</dim>"
922             "                    <dim>27</dim>"
923             "                    <dim>27</dim>"
924             "                </port>"
925             "            </input>"
926             "            <output>"
927             "                <port id=\"49\">"
928             "                    <dim>1</dim>"
929             "                    <dim>48</dim>"
930             "                    <dim>27</dim>"
931             "                    <dim>27</dim>"
932             "                </port>"
933             "                <port id=\"53\">"
934             "                    <dim>1</dim>"
935             "                    <dim>48</dim>"
936             "                    <dim>27</dim>"
937             "                    <dim>27</dim>"
938             "                </port>"
939             "            </output>"
940             "        </layer>"
941             "        <layer name=\"conv2_1\" type=\"Convolution\" precision=\"FP32\" id=\"27\">"
942             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"2\" pad-y=\"2\" kernel-x=\"5\" kernel-y=\"5\" output=\"128\" group=\"1\"/>"
943             "            <input>"
944             "                <port id=\"54\">"
945             "                    <dim>1</dim>"
946             "                    <dim>48</dim>"
947             "                    <dim>27</dim>"
948             "                    <dim>27</dim>"
949             "                </port>"
950             "            </input>"
951             "            <output>"
952             "                <port id=\"55\">"
953             "                    <dim>1</dim>"
954             "                    <dim>128</dim>"
955             "                    <dim>27</dim>"
956             "                    <dim>27</dim>"
957             "                </port>"
958             "            </output>"
959             "            <weights offset=\"139776\" size=\"614400\"/>"
960             "            <biases offset=\"754176\" size=\"512\"/>"
961             "        </layer>"
962             "        <layer name=\"conv2_0\" type=\"Convolution\" precision=\"FP32\" id=\"26\">"
963             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"2\" pad-y=\"2\" kernel-x=\"5\" kernel-y=\"5\" output=\"128\" group=\"1\"/>"
964             "            <input>"
965             "                <port id=\"50\">"
966             "                    <dim>1</dim>"
967             "                    <dim>48</dim>"
968             "                    <dim>27</dim>"
969             "                    <dim>27</dim>"
970             "                </port>"
971             "            </input>"
972             "            <output>"
973             "                <port id=\"51\">"
974             "                    <dim>1</dim>"
975             "                    <dim>128</dim>"
976             "                    <dim>27</dim>"
977             "                    <dim>27</dim>"
978             "                </port>"
979             "            </output>"
980             "            <weights offset=\"754688\" size=\"614400\"/>"
981             "            <biases offset=\"1369088\" size=\"512\"/>"
982             "        </layer>"
983             "        <layer name=\"conv2_merge\" type=\"Concat\" precision=\"FP32\" id=\"25\">"
984             "            <concat_data axis=\"1\"/>"
985             "            <input>"
986             "                <port id=\"52\">"
987             "                    <dim>1</dim>"
988             "                    <dim>128</dim>"
989             "                    <dim>27</dim>"
990             "                    <dim>27</dim>"
991             "                </port>"
992             "                <port id=\"56\">"
993             "                    <dim>1</dim>"
994             "                    <dim>128</dim>"
995             "                    <dim>27</dim>"
996             "                    <dim>27</dim>"
997             "                </port>"
998             "            </input>"
999             "            <output>"
1000             "                <port id=\"48\">"
1001             "                    <dim>1</dim>"
1002             "                    <dim>256</dim>"
1003             "                    <dim>27</dim>"
1004             "                    <dim>27</dim>"
1005             "                </port>"
1006             "            </output>"
1007             "        </layer>"
1008             "        <layer name=\"relu2\" type=\"ReLU\" precision=\"FP32\" id=\"6\">"
1009             "            <input>"
1010             "                <port id=\"11\">"
1011             "                    <dim>1</dim>"
1012             "                    <dim>256</dim>"
1013             "                    <dim>27</dim>"
1014             "                    <dim>27</dim>"
1015             "                </port>"
1016             "            </input>"
1017             "            <output>"
1018             "                <port id=\"12\">"
1019             "                    <dim>1</dim>"
1020             "                    <dim>256</dim>"
1021             "                    <dim>27</dim>"
1022             "                    <dim>27</dim>"
1023             "                </port>"
1024             "            </output>"
1025             "        </layer>"
1026             "        <layer name=\"norm2\" type=\"Norm\" precision=\"FP32\" id=\"7\">"
1027             "            <norm_data alpha=\"9.9999997e-05\" beta=\"0.75\" local-size=\"5\" region=\"across\"/>"
1028             "            <input>"
1029             "                <port id=\"13\">"
1030             "                    <dim>1</dim>"
1031             "                    <dim>256</dim>"
1032             "                    <dim>27</dim>"
1033             "                    <dim>27</dim>"
1034             "                </port>"
1035             "            </input>"
1036             "            <output>"
1037             "                <port id=\"14\">"
1038             "                    <dim>1</dim>"
1039             "                    <dim>256</dim>"
1040             "                    <dim>27</dim>"
1041             "                    <dim>27</dim>"
1042             "                </port>"
1043             "            </output>"
1044             "        </layer>"
1045             "        <layer name=\"pool2\" type=\"Pooling\" precision=\"FP32\" id=\"8\">"
1046             "            <pooling_data kernel-x=\"3\" kernel-y=\"3\" pad-x=\"0\" pad-y=\"0\" stride-x=\"2\" stride-y=\"2\" rounding-type=\"ceil\" pool-method=\"max\"/>"
1047             "            <input>"
1048             "                <port id=\"15\">"
1049             "                    <dim>1</dim>"
1050             "                    <dim>256</dim>"
1051             "                    <dim>27</dim>"
1052             "                    <dim>27</dim>"
1053             "                </port>"
1054             "            </input>"
1055             "            <output>"
1056             "                <port id=\"16\">"
1057             "                    <dim>1</dim>"
1058             "                    <dim>256</dim>"
1059             "                    <dim>13</dim>"
1060             "                    <dim>13</dim>"
1061             "                </port>"
1062             "            </output>"
1063             "        </layer>"
1064             "        <layer name=\"conv3\" type=\"Convolution\" precision=\"FP32\" id=\"9\">"
1065             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"1\" pad-y=\"1\" kernel-x=\"3\" kernel-y=\"3\" output=\"384\" group=\"1\"/>"
1066             "            <input>"
1067             "                <port id=\"17\">"
1068             "                    <dim>1</dim>"
1069             "                    <dim>256</dim>"
1070             "                    <dim>13</dim>"
1071             "                    <dim>13</dim>"
1072             "                </port>"
1073             "            </input>"
1074             "            <output>"
1075             "                <port id=\"18\">"
1076             "                    <dim>1</dim>"
1077             "                    <dim>384</dim>"
1078             "                    <dim>13</dim>"
1079             "                    <dim>13</dim>"
1080             "                </port>"
1081             "            </output>"
1082             "            <weights offset=\"1369600\" size=\"3538944\"/>"
1083             "            <biases offset=\"4908544\" size=\"1536\"/>"
1084             "        </layer>"
1085             "        <layer name=\"relu3\" type=\"ReLU\" precision=\"FP32\" id=\"10\">"
1086             "            <input>"
1087             "                <port id=\"19\">"
1088             "                    <dim>1</dim>"
1089             "                    <dim>384</dim>"
1090             "                    <dim>13</dim>"
1091             "                    <dim>13</dim>"
1092             "                </port>"
1093             "            </input>"
1094             "            <output>"
1095             "                <port id=\"20\">"
1096             "                    <dim>1</dim>"
1097             "                    <dim>384</dim>"
1098             "                    <dim>13</dim>"
1099             "                    <dim>13</dim>"
1100             "                </port>"
1101             "            </output>"
1102             "        </layer>"
1103             "        <layer name=\"conv4_split\" type=\"Split\" precision=\"FP32\" id=\"28\">"
1104             "            <input>"
1105             "                <port id=\"57\">"
1106             "                    <dim>1</dim>"
1107             "                    <dim>384</dim>"
1108             "                    <dim>13</dim>"
1109             "                    <dim>13</dim>"
1110             "                </port>"
1111             "            </input>"
1112             "            <output>"
1113             "                <port id=\"59\">"
1114             "                    <dim>1</dim>"
1115             "                    <dim>192</dim>"
1116             "                    <dim>13</dim>"
1117             "                    <dim>13</dim>"
1118             "                </port>"
1119             "                <port id=\"63\">"
1120             "                    <dim>1</dim>"
1121             "                    <dim>192</dim>"
1122             "                    <dim>13</dim>"
1123             "                    <dim>13</dim>"
1124             "                </port>"
1125             "            </output>"
1126             "        </layer>"
1127             "        <layer name=\"conv4_1\" type=\"Convolution\" precision=\"FP32\" id=\"31\">"
1128             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"1\" pad-y=\"1\" kernel-x=\"3\" kernel-y=\"3\" output=\"192\" group=\"1\"/>"
1129             "            <input>"
1130             "                <port id=\"64\">"
1131             "                    <dim>1</dim>"
1132             "                    <dim>192</dim>"
1133             "                    <dim>13</dim>"
1134             "                    <dim>13</dim>"
1135             "                </port>"
1136             "            </input>"
1137             "            <output>"
1138             "                <port id=\"65\">"
1139             "                    <dim>1</dim>"
1140             "                    <dim>192</dim>"
1141             "                    <dim>13</dim>"
1142             "                    <dim>13</dim>"
1143             "                </port>"
1144             "            </output>"
1145             "            <weights offset=\"4910080\" size=\"1327104\"/>"
1146             "            <biases offset=\"6237184\" size=\"768\"/>"
1147             "        </layer>"
1148             "        <layer name=\"conv4_0\" type=\"Convolution\" precision=\"FP32\" id=\"30\">"
1149             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"1\" pad-y=\"1\" kernel-x=\"3\" kernel-y=\"3\" output=\"192\" group=\"1\"/>"
1150             "            <input>"
1151             "                <port id=\"60\">"
1152             "                    <dim>1</dim>"
1153             "                    <dim>192</dim>"
1154             "                    <dim>13</dim>"
1155             "                    <dim>13</dim>"
1156             "                </port>"
1157             "            </input>"
1158             "            <output>"
1159             "                <port id=\"61\">"
1160             "                    <dim>1</dim>"
1161             "                    <dim>192</dim>"
1162             "                    <dim>13</dim>"
1163             "                    <dim>13</dim>"
1164             "                </port>"
1165             "            </output>"
1166             "            <weights offset=\"6237952\" size=\"1327104\"/>"
1167             "            <biases offset=\"7565056\" size=\"768\"/>"
1168             "        </layer>"
1169             "        <layer name=\"conv4_merge\" type=\"Concat\" precision=\"FP32\" id=\"29\">"
1170             "            <concat_data axis=\"1\"/>"
1171             "            <input>"
1172             "                <port id=\"62\">"
1173             "                    <dim>1</dim>"
1174             "                    <dim>192</dim>"
1175             "                    <dim>13</dim>"
1176             "                    <dim>13</dim>"
1177             "                </port>"
1178             "                <port id=\"66\">"
1179             "                    <dim>1</dim>"
1180             "                    <dim>192</dim>"
1181             "                    <dim>13</dim>"
1182             "                    <dim>13</dim>"
1183             "                </port>"
1184             "            </input>"
1185             "            <output>"
1186             "                <port id=\"58\">"
1187             "                    <dim>1</dim>"
1188             "                    <dim>384</dim>"
1189             "                    <dim>13</dim>"
1190             "                    <dim>13</dim>"
1191             "                </port>"
1192             "            </output>"
1193             "        </layer>"
1194             "        <layer name=\"relu4\" type=\"ReLU\" precision=\"FP32\" id=\"12\">"
1195             "            <input>"
1196             "                <port id=\"23\">"
1197             "                    <dim>1</dim>"
1198             "                    <dim>384</dim>"
1199             "                    <dim>13</dim>"
1200             "                    <dim>13</dim>"
1201             "                </port>"
1202             "            </input>"
1203             "            <output>"
1204             "                <port id=\"24\">"
1205             "                    <dim>1</dim>"
1206             "                    <dim>384</dim>"
1207             "                    <dim>13</dim>"
1208             "                    <dim>13</dim>"
1209             "                </port>"
1210             "            </output>"
1211             "        </layer>"
1212             "        <layer name=\"conv5_split\" type=\"Split\" precision=\"FP32\" id=\"32\">"
1213             "            <input>"
1214             "                <port id=\"67\">"
1215             "                    <dim>1</dim>"
1216             "                    <dim>384</dim>"
1217             "                    <dim>13</dim>"
1218             "                    <dim>13</dim>"
1219             "                </port>"
1220             "            </input>"
1221             "            <output>"
1222             "                <port id=\"69\">"
1223             "                    <dim>1</dim>"
1224             "                    <dim>192</dim>"
1225             "                    <dim>13</dim>"
1226             "                    <dim>13</dim>"
1227             "                </port>"
1228             "                <port id=\"73\">"
1229             "                    <dim>1</dim>"
1230             "                    <dim>192</dim>"
1231             "                    <dim>13</dim>"
1232             "                    <dim>13</dim>"
1233             "                </port>"
1234             "            </output>"
1235             "        </layer>"
1236             "        <layer name=\"conv5_1\" type=\"Convolution\" precision=\"FP32\" id=\"35\">"
1237             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"1\" pad-y=\"1\" kernel-x=\"3\" kernel-y=\"3\" output=\"128\" group=\"1\"/>"
1238             "            <input>"
1239             "                <port id=\"74\">"
1240             "                    <dim>1</dim>"
1241             "                    <dim>192</dim>"
1242             "                    <dim>13</dim>"
1243             "                    <dim>13</dim>"
1244             "                </port>"
1245             "            </input>"
1246             "            <output>"
1247             "                <port id=\"75\">"
1248             "                    <dim>1</dim>"
1249             "                    <dim>128</dim>"
1250             "                    <dim>13</dim>"
1251             "                    <dim>13</dim>"
1252             "                </port>"
1253             "            </output>"
1254             "            <weights offset=\"7565824\" size=\"884736\"/>"
1255             "            <biases offset=\"8450560\" size=\"512\"/>"
1256             "        </layer>"
1257             "        <layer name=\"conv5_0\" type=\"Convolution\" precision=\"FP32\" id=\"34\">"
1258             "            <convolution_data stride-x=\"1\" stride-y=\"1\" pad-x=\"1\" pad-y=\"1\" kernel-x=\"3\" kernel-y=\"3\" output=\"128\" group=\"1\"/>"
1259             "            <input>"
1260             "                <port id=\"70\">"
1261             "                    <dim>1</dim>"
1262             "                    <dim>192</dim>"
1263             "                    <dim>13</dim>"
1264             "                    <dim>13</dim>"
1265             "                </port>"
1266             "            </input>"
1267             "            <output>"
1268             "                <port id=\"71\">"
1269             "                    <dim>1</dim>"
1270             "                    <dim>128</dim>"
1271             "                    <dim>13</dim>"
1272             "                    <dim>13</dim>"
1273             "                </port>"
1274             "            </output>"
1275             "            <weights offset=\"8451072\" size=\"884736\"/>"
1276             "            <biases offset=\"9335808\" size=\"512\"/>"
1277             "        </layer>"
1278             "        <layer name=\"conv5_merge\" type=\"Concat\" precision=\"FP32\" id=\"33\">"
1279             "            <concat_data axis=\"1\"/>"
1280             "            <input>"
1281             "                <port id=\"72\">"
1282             "                    <dim>1</dim>"
1283             "                    <dim>128</dim>"
1284             "                    <dim>13</dim>"
1285             "                    <dim>13</dim>"
1286             "                </port>"
1287             "                <port id=\"76\">"
1288             "                    <dim>1</dim>"
1289             "                    <dim>128</dim>"
1290             "                    <dim>13</dim>"
1291             "                    <dim>13</dim>"
1292             "                </port>"
1293             "            </input>"
1294             "            <output>"
1295             "                <port id=\"68\">"
1296             "                    <dim>1</dim>"
1297             "                    <dim>256</dim>"
1298             "                    <dim>13</dim>"
1299             "                    <dim>13</dim>"
1300             "                </port>"
1301             "            </output>"
1302             "        </layer>"
1303             "        <layer name=\"relu5\" type=\"ReLU\" precision=\"FP32\" id=\"14\">"
1304             "            <input>"
1305             "                <port id=\"27\">"
1306             "                    <dim>1</dim>"
1307             "                    <dim>256</dim>"
1308             "                    <dim>13</dim>"
1309             "                    <dim>13</dim>"
1310             "                </port>"
1311             "            </input>"
1312             "            <output>"
1313             "                <port id=\"28\">"
1314             "                    <dim>1</dim>"
1315             "                    <dim>256</dim>"
1316             "                    <dim>13</dim>"
1317             "                    <dim>13</dim>"
1318             "                </port>"
1319             "            </output>"
1320             "        </layer>"
1321             "        <layer name=\"pool5\" type=\"Pooling\" precision=\"FP32\" id=\"15\">"
1322             "            <pooling_data kernel-x=\"3\" kernel-y=\"3\" pad-x=\"0\" pad-y=\"0\" stride-x=\"2\" stride-y=\"2\" rounding-type=\"ceil\" pool-method=\"max\"/>"
1323             "            <input>"
1324             "                <port id=\"29\">"
1325             "                    <dim>1</dim>"
1326             "                    <dim>256</dim>"
1327             "                    <dim>13</dim>"
1328             "                    <dim>13</dim>"
1329             "                </port>"
1330             "            </input>"
1331             "            <output>"
1332             "                <port id=\"30\">"
1333             "                    <dim>1</dim>"
1334             "                    <dim>256</dim>"
1335             "                    <dim>6</dim>"
1336             "                    <dim>6</dim>"
1337             "                </port>"
1338             "            </output>"
1339             "        </layer>"
1340             "        <layer name=\"fc6\" type=\"FullyConnected\" precision=\"FP32\" id=\"16\">"
1341             "            <fc_data out-size=\"4096\"/>"
1342             "            <input>"
1343             "                <port id=\"31\">"
1344             "                    <dim>1</dim>"
1345             "                    <dim>256</dim>"
1346             "                    <dim>6</dim>"
1347             "                    <dim>6</dim>"
1348             "                </port>"
1349             "            </input>"
1350             "            <output>"
1351             "                <port id=\"32\">"
1352             "                    <dim>1</dim>"
1353             "                    <dim>4096</dim>"
1354             "                </port>"
1355             "            </output>"
1356             "            <weights offset=\"9336320\" size=\"150994944\"/>"
1357             "            <biases offset=\"160331264\" size=\"16384\"/>"
1358             "        </layer>"
1359             "        <layer name=\"relu6\" type=\"ReLU\" precision=\"FP32\" id=\"17\">"
1360             "            <input>"
1361             "                <port id=\"33\">"
1362             "                    <dim>1</dim>"
1363             "                    <dim>4096</dim>"
1364             "                </port>"
1365             "            </input>"
1366             "            <output>"
1367             "                <port id=\"34\">"
1368             "                    <dim>1</dim>"
1369             "                    <dim>4096</dim>"
1370             "                </port>"
1371             "            </output>"
1372             "        </layer>"
1373             "        <layer name=\"fc7\" type=\"FullyConnected\" precision=\"FP32\" id=\"19\">"
1374             "            <fc_data out-size=\"4096\"/>"
1375             "            <input>"
1376             "                <port id=\"37\">"
1377             "                    <dim>1</dim>"
1378             "                    <dim>4096</dim>"
1379             "                </port>"
1380             "            </input>"
1381             "            <output>"
1382             "                <port id=\"38\">"
1383             "                    <dim>1</dim>"
1384             "                    <dim>4096</dim>"
1385             "                </port>"
1386             "            </output>"
1387             "            <weights offset=\"160347648\" size=\"67108864\"/>"
1388             "            <biases offset=\"227456512\" size=\"16384\"/>"
1389             "        </layer>"
1390             "        <layer name=\"relu7\" type=\"ReLU\" precision=\"FP32\" id=\"20\">"
1391             "            <input>"
1392             "                <port id=\"39\">"
1393             "                    <dim>1</dim>"
1394             "                    <dim>4096</dim>"
1395             "                </port>"
1396             "            </input>"
1397             "            <output>"
1398             "                <port id=\"40\">"
1399             "                    <dim>1</dim>"
1400             "                    <dim>4096</dim>"
1401             "                </port>"
1402             "            </output>"
1403             "        </layer>"
1404             "        <layer name=\"fc8\" type=\"FullyConnected\" precision=\"FP32\" id=\"22\">"
1405             "            <fc_data out-size=\"1000\"/>"
1406             "            <input>"
1407             "                <port id=\"43\">"
1408             "                    <dim>1</dim>"
1409             "                    <dim>4096</dim>"
1410             "                </port>"
1411             "            </input>"
1412             "            <output>"
1413             "                <port id=\"44\">"
1414             "                    <dim>1</dim>"
1415             "                    <dim>1000</dim>"
1416             "                </port>"
1417             "            </output>"
1418             "            <weights offset=\"227472896\" size=\"16384000\"/>"
1419             "            <biases offset=\"243856896\" size=\"4000\"/>"
1420             "        </layer>"
1421             "        <layer name=\"prob\" type=\"SoftMax\" precision=\"FP32\" id=\"23\">"
1422             "            <input>"
1423             "                <port id=\"45\">"
1424             "                    <dim>1</dim>"
1425             "                    <dim>1000</dim>"
1426             "                </port>"
1427             "            </input>"
1428             "            <output>"
1429             "                <port id=\"46\">"
1430             "                    <dim>1</dim>"
1431             "                    <dim>1000</dim>"
1432             "                </port>"
1433             "            </output>"
1434             "        </layer>"
1435             "    </layers>"
1436             "    <edges>"
1437             "        <edge from-layer=\"0\" from-port=\"0\" to-layer=\"1\" to-port=\"1\"/>"
1438             "        <edge from-layer=\"1\" from-port=\"2\" to-layer=\"2\" to-port=\"3\"/>"
1439             "        <edge from-layer=\"2\" from-port=\"4\" to-layer=\"3\" to-port=\"5\"/>"
1440             "        <edge from-layer=\"3\" from-port=\"6\" to-layer=\"4\" to-port=\"7\"/>"
1441             "        <edge from-layer=\"4\" from-port=\"8\" to-layer=\"24\" to-port=\"47\"/>"
1442             "        <edge from-layer=\"25\" from-port=\"48\" to-layer=\"6\" to-port=\"11\"/>"
1443             "        <edge from-layer=\"6\" from-port=\"12\" to-layer=\"7\" to-port=\"13\"/>"
1444             "        <edge from-layer=\"7\" from-port=\"14\" to-layer=\"8\" to-port=\"15\"/>"
1445             "        <edge from-layer=\"8\" from-port=\"16\" to-layer=\"9\" to-port=\"17\"/>"
1446             "        <edge from-layer=\"9\" from-port=\"18\" to-layer=\"10\" to-port=\"19\"/>"
1447             "        <edge from-layer=\"10\" from-port=\"20\" to-layer=\"28\" to-port=\"57\"/>"
1448             "        <edge from-layer=\"29\" from-port=\"58\" to-layer=\"12\" to-port=\"23\"/>"
1449             "        <edge from-layer=\"12\" from-port=\"24\" to-layer=\"32\" to-port=\"67\"/>"
1450             "        <edge from-layer=\"33\" from-port=\"68\" to-layer=\"14\" to-port=\"27\"/>"
1451             "        <edge from-layer=\"14\" from-port=\"28\" to-layer=\"15\" to-port=\"29\"/>"
1452             "        <edge from-layer=\"15\" from-port=\"30\" to-layer=\"16\" to-port=\"31\"/>"
1453             "        <edge from-layer=\"16\" from-port=\"32\" to-layer=\"17\" to-port=\"33\"/>"
1454             "        <edge from-layer=\"19\" from-port=\"38\" to-layer=\"20\" to-port=\"39\"/>"
1455             "        <edge from-layer=\"22\" from-port=\"44\" to-layer=\"23\" to-port=\"45\"/>"
1456             "        <edge from-layer=\"24\" from-port=\"49\" to-layer=\"26\" to-port=\"50\"/>"
1457             "        <edge from-layer=\"26\" from-port=\"51\" to-layer=\"25\" to-port=\"52\"/>"
1458             "        <edge from-layer=\"24\" from-port=\"53\" to-layer=\"27\" to-port=\"54\"/>"
1459             "        <edge from-layer=\"27\" from-port=\"55\" to-layer=\"25\" to-port=\"56\"/>"
1460             "        <edge from-layer=\"28\" from-port=\"59\" to-layer=\"30\" to-port=\"60\"/>"
1461             "        <edge from-layer=\"30\" from-port=\"61\" to-layer=\"29\" to-port=\"62\"/>"
1462             "        <edge from-layer=\"28\" from-port=\"63\" to-layer=\"31\" to-port=\"64\"/>"
1463             "        <edge from-layer=\"31\" from-port=\"65\" to-layer=\"29\" to-port=\"66\"/>"
1464             "        <edge from-layer=\"32\" from-port=\"69\" to-layer=\"34\" to-port=\"70\"/>"
1465             "        <edge from-layer=\"34\" from-port=\"71\" to-layer=\"33\" to-port=\"72\"/>"
1466             "        <edge from-layer=\"32\" from-port=\"73\" to-layer=\"35\" to-port=\"74\"/>"
1467             "        <edge from-layer=\"35\" from-port=\"75\" to-layer=\"33\" to-port=\"76\"/>"
1468             "        <edge from-layer=\"17\" from-port=\"34\" to-layer=\"19\" to-port=\"37\"/>"
1469             "        <edge from-layer=\"20\" from-port=\"40\" to-layer=\"22\" to-port=\"43\"/>"
1470             "    </edges>"
1471             "    <pre-process reference-layer-name=\"data\">"
1472             "        <channel id=\"0\">"
1473             "            <mean value=\"104.00698793\"/>"
1474             "        </channel>"
1475             "        <channel id=\"1\">"
1476             "            <mean value=\"116.66876762\"/>"
1477             "        </channel>"
1478             "        <channel id=\"2\">"
1479             "            <mean value=\"122.67891434\"/>"
1480             "        </channel>"
1481             "    </pre-process>"
1482             "</net>";
1483     InferenceEngine::CNNNetReader reader;
1484     ASSERT_NO_THROW(reader.ReadNetwork(model.data(), model.length()));
1485
1486     auto topology = reader.getNetwork();
1487     auto topology_complexity = getNetworkComplexity(topology);
1488
1489     std::map<std::string, InferenceEngine::LayerComplexity>
1490         reference
1491         {
1492             {"conv1", {210830400, 34944}},
1493             {"relu1", {290400, 0}},
1494             {"norm1", {14520000, 0}},
1495             {"pool1", {629856, 0}},
1496
1497             {"conv2_0", {223948800, 153728}},
1498             {"conv2_1", {223948800, 153728}},
1499             {"relu2", {186624, 0}},
1500             {"norm2", {9331200, 0}},
1501             {"pool2", {389376, 0}},
1502
1503             {"conv3", {299040768, 885120}},
1504             {"relu3", {64896, 0}},
1505
1506             {"conv4_0", {112140288, 331968}},
1507             {"conv4_1", {112140288, 331968}},
1508             {"relu4", {64896, 0}},
1509             {"conv5_0", {74760192, 221312}},
1510             {"conv5_1", {74760192, 221312}},
1511
1512             {"relu5", {43264, 0}},
1513             {"pool5", {82944, 0}},
1514
1515             {"fc6", {75497472, 37752832}},
1516             {"relu6", {4096, 0}},
1517
1518             {"fc7", {33554432, 16781312}},
1519             {"relu7", {4096, 0}},
1520
1521             {"fc8", {8192000, 4097000}},
1522             {"prob", {4000, 0}}
1523         };
1524
1525     for (auto &item: reference) {
1526         ASSERT_TRUE(topology_complexity.count(item.first) > 0);
1527         auto flops = topology_complexity[item.first].flops;
1528         auto params = topology_complexity[item.first].params;
1529
1530         ASSERT_EQ(flops, item.second.flops);
1531         ASSERT_EQ(params, item.second.params);
1532     }
1533 }
1534
1535 TEST(UtilTests, replaceLayerWithNewLayer) {
1536     //
1537     // I->L1->L3->O
1538     //     \  /
1539     //      L2
1540     //
1541
1542     NetBuilder netBuilder;
1543     auto net = netBuilder
1544                .data("data1", IE::SizeVector{1, 1, 1}, IE::Precision::UNSPECIFIED, IE::Layout::CHW)
1545                .data("data2", IE::SizeVector{1, 1, 1}, IE::Precision::UNSPECIFIED, IE::Layout::CHW)
1546                .data("data3", IE::SizeVector{1, 1, 1}, IE::Precision::UNSPECIFIED, IE::Layout::CHW)
1547                .data("data4", IE::SizeVector{1, 1, 1}, IE::Precision::UNSPECIFIED, IE::Layout::CHW)
1548                .layer<IE::CNNLayer>(IE::LayerParams{"layer1", "dummy", IE::Precision::UNSPECIFIED})
1549                .layer<IE::CNNLayer>(IE::LayerParams{"layer2", "dummy", IE::Precision::UNSPECIFIED})
1550                .layer<IE::CNNLayer>(IE::LayerParams{"layer3", "dummy", IE::Precision::UNSPECIFIED})
1551                .linkData("data1", "data2", "layer1")
1552                .linkData("data2", "data3", "layer2")
1553                .linkData("data2", "data4", "layer3")
1554                .linkDataTo("data3", "layer3")
1555                .finalize();
1556
1557     const auto& layers = netBuilder.getLayersMap();
1558     const auto& data   = netBuilder.getDataMap();
1559
1560     {   // Replace L1
1561         auto newLayer1 = std::make_shared<IE::CNNLayer>(IE::LayerParams{"layer1", "dummy", IE::Precision::UNSPECIFIED});
1562         auto layer1    = layers.find("layer1");
1563         EXPECT_TRUE(layer1 != layers.end());
1564         CNNNetSubstituteLayer(*net, layer1->second, newLayer1);
1565         IE::CNNLayerPtr layer1Check = nullptr;
1566         net->getLayerByName("layer1", layer1Check, nullptr);
1567         ASSERT_EQ(layer1Check, newLayer1);
1568         ASSERT_EQ(layer1Check->outData.size(), 1);
1569         ASSERT_EQ(layer1Check->outData[0], data.find("data2")->second);
1570         ASSERT_EQ(layer1Check->outData[0]->creatorLayer.lock(), newLayer1);
1571     }
1572     {   // Replace L2
1573         auto newLayer2 = std::make_shared<IE::CNNLayer>(IE::LayerParams{"layer2", "dummy", IE::Precision::UNSPECIFIED});
1574         auto layer2    = layers.find("layer2");
1575         EXPECT_TRUE(layer2 != layers.end());
1576         CNNNetSubstituteLayer(*net, layer2->second, newLayer2);
1577         IE::CNNLayerPtr layer2Check = nullptr;
1578         net->getLayerByName("layer2", layer2Check, nullptr);
1579         ASSERT_EQ(layer2Check, newLayer2);
1580         ASSERT_EQ(layer2Check->outData.size(), 1);
1581         ASSERT_EQ(layer2Check->outData[0], data.find("data3")->second);
1582         ASSERT_EQ(layer2Check->outData[0]->creatorLayer.lock(), newLayer2);
1583     }
1584     {   // Replace L3
1585         auto newLayer3 = std::make_shared<IE::CNNLayer>(IE::LayerParams{"layer3", "dummy", IE::Precision::UNSPECIFIED});
1586         auto layer3    = layers.find("layer3");
1587         EXPECT_TRUE(layer3 != layers.end());
1588         CNNNetSubstituteLayer(*net, layer3->second, newLayer3);
1589         IE::CNNLayerPtr layer3Check = nullptr;
1590         net->getLayerByName("layer3", layer3Check, nullptr);
1591         ASSERT_EQ(layer3Check, newLayer3);
1592         ASSERT_EQ(layer3Check->outData.size(), 1);
1593         ASSERT_EQ(layer3Check->outData[0], data.find("data4")->second);
1594         ASSERT_EQ(layer3Check->outData[0]->creatorLayer.lock(), newLayer3);
1595         ASSERT_TRUE(layer3Check->insData[0].lock() == data.find("data2")->second ||
1596                     layer3Check->insData[0].lock() == data.find("data3")->second);
1597         ASSERT_TRUE(layer3Check->insData[1].lock() == data.find("data2")->second ||
1598                     layer3Check->insData[1].lock() == data.find("data3")->second);
1599     }
1600 }