1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include <gtest/gtest.h>
7 #include <initializer_list>
10 #include <unordered_set>
11 #include <unordered_map>
13 #include <ie_util_internal.hpp>
14 #include <tests_common.hpp>
15 #include <graph_transformer.h>
16 #include "ie_utils.hpp"
17 #include "blob_factory.hpp"
19 #include "util_test.hpp"
20 #include "util_const_infer_test.hpp"
21 #include <details/ie_cnn_network_tools.h>
23 namespace IE = InferenceEngine;
25 void RemoveLayerTests::SetUp() {
27 originalLayersNum = net->allLayers().size();
28 testTransformator.reset(new ConstTransformatorTest(net.get()));
36 // I2-d2-L2-d5-L4-d6-L5-d9-L10
42 IE::details::CNNNetworkImplPtr RemoveLayerTests::getNetwork() {
44 .data("data1", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
45 .data("data2", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
46 .data("data3", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
47 .data("data4", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
48 .data("data5", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
49 .data("data6", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
50 .data("data7", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
51 .data("data8", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
52 .data("data9", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
53 .data("data10", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
54 .data("data11", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
55 .layer<IE::CNNLayer>(IE::LayerParams{"input1", "input", IE::Precision::FP32})
56 .layer<IE::CNNLayer>(IE::LayerParams{"input2", "Input", IE::Precision::FP32})
57 .layer<IE::CNNLayer>(IE::LayerParams{"input3", "input", IE::Precision::FP32})
58 .layer<IE::CNNLayer>(IE::LayerParams{"input4", "input", IE::Precision::FP32})
59 .layer<IE::CNNLayer>(IE::LayerParams{"layer1", "dummy", IE::Precision::FP32})
60 .layer<IE::CNNLayer>(IE::LayerParams{"layer2", "dummy", IE::Precision::FP32})
61 .layer<IE::CNNLayer>(IE::LayerParams{"layer3", "dummy", IE::Precision::FP32})
62 .layer<IE::CNNLayer>(IE::LayerParams{"layer4", "dummy", IE::Precision::FP32})
63 .layer<IE::CNNLayer>(IE::LayerParams{"layer5", "dummy", IE::Precision::FP32})
64 .layer<IE::CNNLayer>(IE::LayerParams{"layer6", "dummy", IE::Precision::FP32})
65 .linkToData("input1", "data1")
66 .linkToData("input2", "data2")
67 .linkToData("input3", "data3")
68 .linkToData("input4", "data10")
70 .linkDataTo("data1", "layer1")
71 .linkDataTo("data2", "layer2")
72 .linkDataTo("data2", "layer1")
73 .linkDataTo("data3", "layer3")
74 .linkDataTo("data3", "layer2")
75 .linkDataTo("data10", "layer6")
77 .linkToData("layer1", "data4")
78 .linkToData("layer1", "data7")
79 .linkToData("layer2", "data5")
80 .linkToData("layer3", "data8")
82 .linkDataTo("data4", "layer4")
83 .linkDataTo("data5", "layer4")
84 .linkDataTo("data8", "layer5")
85 .linkDataTo("data7", "layer2")
87 .linkToData("layer4", "data6")
89 .linkDataTo("data6", "layer5")
91 .linkToData("layer5", "data9")
93 .linkDataTo("data9", "layer6")
95 .linkToData("layer6", "data11")
103 IE::CNNLayerPtr RemoveLayerTests::getLayer(const std::string& name) {
104 const auto& layers = netBuilder.getLayersMap();
105 auto it = layers.find(name);
106 if (it == layers.end()) throw std::logic_error("Failed to find layer: " + name);
110 IE::DataPtr RemoveLayerTests::getData(const std::string& name) {
111 const auto& datas = netBuilder.getDataMap();
112 auto it = datas.find(name);
113 if (it == datas.end()) throw std::logic_error("Failed to find data: " + name);
117 IE::BlobMap RemoveLayerTests::fillConstData(const std::vector<std::string>& constLayers) {
118 IE::BlobMap constData;
119 for (const auto& name:constLayers) {
120 auto layer = getLayer(name);
121 for (const auto& outData:layer->outData) {
122 IE::TensorDesc desc = outData->getTensorDesc();
123 IE::Blob::Ptr blob = make_blob_with_precision(desc);
125 auto* buffer = blob->buffer().as<float*>();
126 for (int i = 0; i < blob->size(); i++) {
129 constData[outData->name] = blob;
135 IE::BlobMap RemoveLayerTests::initConstLayers(const std::vector<std::string>& constLayers) {
136 for (const auto& name : constLayers) {
137 getLayer(name)->type = "Const";
139 IE::BlobMap customBlobs = fillConstData(constLayers);
140 for (const auto& layerName: constLayers) {
141 auto layer = getLayer(layerName);
142 layer->type = "Const";
143 layer->blobs["custom"] = customBlobs[layer->outData[0]->name];
148 TEST_F(RemoveLayerTests, canTrimL2) {
149 auto layer1 = getLayer("layer1");
150 auto layer4 = getLayer("layer4");
151 auto data2 = getData("data2");
152 auto data3 = getData("data3");
153 auto data7 = getData("data7");
154 auto data5 = getData("data5");
155 std::vector<std::string> constLayers = {"layer2"};
156 std::vector<std::string> refNewLayers = {constLayers[0] + "__data5__Const"};
157 auto constData = fillConstData(constLayers);
158 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
160 auto newLayers = testTransformator->foldConstSubgraphsInternal({{constLayers[0], false}}, constData, sortedLayers);
162 ASSERT_EQ(newLayers, refNewLayers);
163 IE::CNNNetwork cnnNetwork(net);
164 ASSERT_THROW(cnnNetwork.getLayerByName("layer2"), IE::NotFound);
165 auto newLayer = cnnNetwork.getLayerByName(refNewLayers[0].c_str());
166 ASSERT_EQ(newLayer->type, "Const");
167 ASSERT_EQ(constData["data5"], newLayer->blobs.at("custom"));
168 ASSERT_EQ(nullptr, net->getData("data7"));
169 net->removeData("data7");
170 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
171 ASSERT_EQ(data2->inputTo.size(), 1);
172 ASSERT_EQ(data2->inputTo.find("layer1")->second, layer1);
173 ASSERT_EQ(data5->creatorLayer.lock(), newLayer);
174 ASSERT_EQ(layer4->insData.size(), 2);
175 ASSERT_EQ(layer4->insData[1].lock(), data5);
176 ASSERT_EQ(layer1->insData.size(), 2);
177 ASSERT_EQ(layer1->insData[0].lock(), getData("data1"));
178 ASSERT_EQ(layer1->insData[1].lock(), data2);
179 ASSERT_EQ(layer1->outData.size(), 1);
180 ASSERT_EQ(layer1->outData[0], getData("data4"));
181 ASSERT_EQ(newLayer->outData.size(), 1);
182 ASSERT_EQ(newLayer->outData[0], data5);
183 ASSERT_EQ(data3->inputTo.size(), 1);
184 ASSERT_EQ(data3->inputTo.find("layer3")->second, getLayer("layer3"));
187 TEST_F(RemoveLayerTests, canTrimI1andL1) {
188 auto layer4 = getLayer("layer4");
189 auto layer2 = getLayer("layer2");
190 auto data2 = getData("data2");
191 std::vector<std::string> constLayers = {"input1", "layer1"};
192 std::map<std::string, bool> mapConstLayers;
193 for (const auto& it : constLayers) {
194 mapConstLayers[it] = false;
196 std::vector<std::string> refNewLayers = {(constLayers[1] + "__data4__Const"), (constLayers[1] + "__data7__Const")};
198 auto constData = fillConstData(constLayers);
199 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
200 auto newLayers = testTransformator->foldConstSubgraphsInternal(mapConstLayers, constData, sortedLayers);
202 ASSERT_EQ(newLayers, refNewLayers);
203 IE::CNNNetwork cnnNetwork(net);
204 ASSERT_THROW(cnnNetwork.getLayerByName("input1"), IE::NotFound);
205 ASSERT_THROW(cnnNetwork.getLayerByName("layer1"), IE::NotFound);
206 auto newLayerD4 = cnnNetwork.getLayerByName(refNewLayers[0].c_str());
207 auto newLayerD7 = cnnNetwork.getLayerByName(refNewLayers[1].c_str());
208 auto newData4 = net->getData("data4__layer4");
209 auto newData7 = net->getData("data7__layer2");
210 ASSERT_EQ(newLayerD4->type, "Const");
211 ASSERT_EQ(newLayerD7->type, "Const");
212 ASSERT_EQ(constData["data4"], newLayerD4->blobs.at("custom"));
213 ASSERT_EQ(constData["data7"], newLayerD7->blobs.at("custom"));
214 ASSERT_EQ(nullptr, net->getData("data1"));
215 net->removeData("data1");
216 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
217 ASSERT_EQ(data2->inputTo.size(), 1);
218 ASSERT_EQ(data2->inputTo.find("layer2")->second, layer2);
219 ASSERT_EQ(newData4->creatorLayer.lock(), newLayerD4);
220 ASSERT_EQ(newData7->creatorLayer.lock(), newLayerD7);
221 ASSERT_EQ(newLayerD4->outData.size(), 1);
222 ASSERT_EQ(newLayerD7->outData.size(), 1);
223 ASSERT_EQ(newLayerD4->outData[0], newData4);
224 ASSERT_EQ(newLayerD7->outData[0], newData7);
225 ASSERT_EQ(layer4->insData.size(), 2);
226 ASSERT_EQ(layer4->insData[0].lock(), newData4);
227 ASSERT_EQ(layer4->insData[1].lock(), getData("data5"));
228 ASSERT_EQ(layer2->insData.size(), 3);
229 ASSERT_EQ(layer2->insData[0].lock(), data2);
230 ASSERT_EQ(layer2->insData[1].lock(), getData("data3"));
231 ASSERT_EQ(layer2->insData[2].lock(), newData7);
234 TEST_F(RemoveLayerTests, canFindConstLayers) {
235 getLayer("input1")->type = "Const";
236 getLayer("layer2")->type = "Shape";
238 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
239 auto constLayers = testTransformator->getConstLayers(sortedLayers);
241 ASSERT_EQ(constLayers.size(), 2);
242 auto begin = constLayers.begin();
243 auto end = constLayers.end();
244 ASSERT_FALSE(constLayers.at("input1"));
245 ASSERT_FALSE(constLayers.at("layer2"));
248 TEST_F(RemoveLayerTests, canFindConstLayers2) {
249 getLayer("input3")->type = "Const";
250 getLayer("input2")->type = "Const";
251 getLayer("layer2")->type = "Shape";
253 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
254 auto constLayers = testTransformator->getConstLayers(sortedLayers);
256 ASSERT_EQ(constLayers.size(), 4);
257 ASSERT_FALSE(constLayers.at("input3"));
258 ASSERT_FALSE(constLayers.at("layer2"));
259 ASSERT_FALSE(constLayers.at("layer3"));
260 ASSERT_FALSE(constLayers.at("input2"));
263 TEST_F(RemoveLayerTests, canFindConstLayers3) {
264 getLayer("input3")->type = "Const";
265 getLayer("layer2")->type = "Shape";
266 getLayer("layer1")->type = "Shape";
267 getLayer("layer4")->type = "Reshape";
269 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
270 auto constLayers = testTransformator->getConstLayers(sortedLayers);
272 ASSERT_EQ(constLayers.size(), 6);
273 ASSERT_FALSE(constLayers.at("input3"));
274 ASSERT_FALSE(constLayers.at("layer1"));
275 ASSERT_TRUE(constLayers.at("layer2"));
276 ASSERT_FALSE(constLayers.at("layer3"));
277 ASSERT_FALSE(constLayers.at("layer4"));
278 ASSERT_FALSE(constLayers.at("layer5"));
281 TEST_F(RemoveLayerTests, canFindShapeConstLayers) {
282 getLayer("input3")->type = "Const";
283 getLayer("layer2")->type = "Shape";
284 getLayer("layer1")->type = "Shape";
285 getLayer("layer6")->type = "Interp";
287 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
288 auto constLayers = testTransformator->getConstLayers(sortedLayers);
290 ASSERT_EQ(constLayers.size(), 6);
291 ASSERT_TRUE(constLayers.at("input3"));
292 ASSERT_TRUE(constLayers.at("layer1"));
293 ASSERT_TRUE(constLayers.at("layer2"));
294 ASSERT_TRUE(constLayers.at("layer3"));
295 ASSERT_TRUE(constLayers.at("layer4"));
296 ASSERT_TRUE(constLayers.at("layer5"));
299 TEST_F(RemoveLayerTests, canFindShapeConstLayers2) {
300 getLayer("input3")->type = "Const";
301 getLayer("input2")->type = "Const";
302 getLayer("layer2")->type = "Shape";
303 getLayer("layer1")->type = "Resample";
305 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
306 auto constLayers = testTransformator->getConstLayers(sortedLayers);
308 ASSERT_EQ(constLayers.size(), 4);
309 ASSERT_FALSE(constLayers.at("input3"));
310 ASSERT_FALSE(constLayers.at("layer2"));
311 ASSERT_FALSE(constLayers.at("layer3"));
312 ASSERT_FALSE(constLayers.at("input2"));
315 TEST_F(RemoveLayerTests, canTrimShapeInput) {
316 std::vector<std::string> constLayers = {"input3", "layer3", "input2"};
317 for (const auto& name : constLayers) {
318 getLayer(name)->type = "Const";
320 getLayer("layer2")->type = "Shape";
321 getLayer("layer1")->type = "Interp";
322 getLayer("layer4")->type = "Reshape";
323 getLayer("layer5")->type = "Reshape";
324 auto layer1 = getLayer("layer1");
325 auto layer4 = getLayer("layer4");
326 auto layer5 = getLayer("layer5");
328 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
329 auto mapConstLayers = testTransformator->getConstLayers(sortedLayers);
330 auto newLayers = testTransformator->foldConstSubgraphsInternal(mapConstLayers, {}, sortedLayers);
331 testTransformator->trimShapeInputs(newLayers);
333 ASSERT_EQ(nullptr, net->getData("data5"));
334 ASSERT_EQ(nullptr, net->getData("data2"));
335 net->removeData("data5");
336 net->removeData("data2");
337 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 3);
338 ASSERT_EQ(layer1->insData.size(), 1);
339 ASSERT_EQ(layer1->insData[0].lock(), getData("data1"));
340 ASSERT_EQ(layer4->insData.size(), 1);
341 ASSERT_EQ(layer4->insData[0].lock(), getData("data4"));
342 ASSERT_EQ(layer5->insData.size(), 2);
343 ASSERT_EQ(layer5->insData[0].lock(), getData("data8"));
344 ASSERT_EQ(layer5->insData[1].lock(), getData("data6"));
347 TEST_F(RemoveLayerTests, canTrimShapeInput2) {
348 std::vector<std::string> constLayers = {"input3", "input2"};
349 for (const auto& name : constLayers) {
350 getLayer(name)->type = "Const";
352 auto layer1 = getLayer("layer1");
353 auto layer2 = getLayer("layer2");
354 layer1->type = "Resample";
355 layer2->type = "StridedSlice";
357 testTransformator->trimShapeInputs(constLayers);
359 auto data6 = net->getData("data6");
360 auto data2 = net->getData("data2");
361 ASSERT_EQ(data2->inputTo.size(), 1);
362 ASSERT_EQ(data2->inputTo.at(layer2->name), layer2);
363 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
364 ASSERT_EQ(layer1->insData.size(), 1);
365 ASSERT_EQ(layer1->insData[0].lock(), getData("data1"));
366 ASSERT_EQ(layer2->insData.size(), 3);
367 ASSERT_EQ(layer2->insData[0].lock(), getData("data2"));
368 ASSERT_EQ(layer2->insData[1].lock(), getData("data3"));
369 ASSERT_EQ(layer2->insData[2].lock(), getData("data7"));
372 TEST_F(RemoveLayerTests, notTrimFirstConstInput) {
373 std::vector<std::string> testLayers = {"Interp", "Reshape", "Pad", "Gather", "Resample"};
374 std::string constLayer = "input4";
375 getLayer(constLayer)->type = "Const";
376 auto layer6 = getLayer("layer6");
377 auto data10 = getData("data10");
378 for (const auto& name: testLayers) {
381 testTransformator->trimShapeInputs({constLayer});
383 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
384 IE::CNNNetwork cnnNetwork(net);
385 auto input4 = cnnNetwork.getLayerByName(constLayer.c_str());
386 ASSERT_EQ(data10->inputTo.size(), 1);
387 ASSERT_EQ(data10->creatorLayer.lock(), input4);
388 ASSERT_EQ(layer6->insData.size(), 2);
389 ASSERT_EQ(layer6->insData[0].lock(), data10);
390 ASSERT_EQ(layer6->insData[1].lock(), getData("data9"));
394 TEST_F(RemoveLayerTests, canSaveConstForEltWise) {
395 auto input2 = getLayer("input2");
396 auto layer1 = getLayer("layer1");
397 auto data2 = getData("data2");
398 input2->type = "Const";
399 layer1->type = "Eltwise";
401 testTransformator->trimShapeInputs({input2->name});
403 IE::CNNNetwork cnnNetwork(net);
404 ASSERT_NO_THROW(input2 = cnnNetwork.getLayerByName(input2->name.c_str()));
405 ASSERT_EQ(net->allLayers().size(), 10);
406 ASSERT_EQ(layer1->insData.size(), 2);
407 ASSERT_EQ(layer1->insData[1].lock(), data2);
408 ASSERT_EQ(data2->inputTo.size(), 2);
409 ASSERT_EQ(data2->inputTo.at(layer1->name), layer1);
410 ASSERT_EQ(data2->creatorLayer.lock(), input2);
413 TEST_F(RemoveLayerTests, canSaveDataWithMultipleInputTo) {
414 auto input3 = getLayer("input3");
415 auto layer2 = getLayer("layer2");
416 auto layer3 = getLayer("layer3");
417 auto data3 = getData("data3");
418 input3->type = "Const";
419 layer2->type = "Reshape";
421 testTransformator->trimShapeInputs({input3->name});
423 IE::CNNNetwork cnnNetwork(net);
424 ASSERT_NO_THROW(input3 = cnnNetwork.getLayerByName(input3->name.c_str()));
425 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
426 ASSERT_EQ(layer2->insData.size(), 2);
427 ASSERT_EQ(layer2->insData[0].lock(), getData("data2"));
428 ASSERT_EQ(layer2->insData[1].lock(), getData("data7"));
429 ASSERT_EQ(data3->inputTo.size(), 1);
430 ASSERT_EQ(data3->inputTo.at(layer3->name), layer3);
431 ASSERT_EQ(data3->creatorLayer.lock(), input3);
432 ASSERT_EQ(layer3->insData.size(), 1);
433 ASSERT_EQ(layer3->insData[0].lock(), data3);
436 TEST_F(RemoveLayerTests, canFoldConstSubgraphToConst) {
437 std::vector<std::string> constLayers = {"input1", "input2", "input3"};
438 std::vector<std::string> refNewLayers = {"layer5__data9__Const"};
439 for (const auto& name : constLayers) {
440 getLayer(name)->type = "Const";
442 getLayer("layer2")->type = "Shape";
444 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
445 auto mapConstLayers = testTransformator->getConstLayers(sortedLayers);
446 auto newLayers = testTransformator->foldConstSubgraphsInternal(mapConstLayers, {}, sortedLayers);
448 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 7);
449 ASSERT_EQ(newLayers, refNewLayers);
450 IE::CNNNetwork cnnNetwork(net);
451 auto newLayer = cnnNetwork.getLayerByName(refNewLayers[0].c_str());
452 ASSERT_EQ(newLayer->type, "Const");
453 ASSERT_EQ(newLayer->outData[0], getData("data9"));
456 TEST_F(RemoveLayerTests, canGetConstData) {
457 std::vector<std::string> constLayers = {"input2", "input3", "layer3"};
458 IE::BlobMap refBlobs = initConstLayers(constLayers);
459 std::map<std::string, bool> mapConstLayers;
460 for (const auto& it : constLayers) {
461 mapConstLayers[it] = false;
463 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
465 auto actBlobs = testTransformator->getConstData(mapConstLayers, sortedLayers);
467 ASSERT_EQ(actBlobs.size(), refBlobs.size());
468 for (const auto& it: refBlobs) {
469 ASSERT_EQ(it.second, actBlobs[it.first]);
473 TEST_F(RemoveLayerTests, canGetConstDataForUnknownImpl) {
474 initConstLayers({"input1", "input2", "input3"});
476 getLayer("layer1")->type = "UNKNOWN";
477 getLayer("layer2")->type = "UNKNOWN";
478 getLayer("layer3")->type = "Shape";
479 getLayer("layer4")->type = "UNKNOWN";
480 getLayer("layer5")->type = "Mul";
481 getLayer("layer6")->type = "Reshape";
483 auto sortedLayers = IE::details::CNNNetSortTopologically(*net);
484 IE::SizeVector refShape = {1, 1, 3};
486 auto mapConstLayers = testTransformator->getConstLayers(sortedLayers);
487 auto actBlobs = testTransformator->getConstData(mapConstLayers, sortedLayers);
489 ASSERT_EQ(getData("data9")->getTensorDesc().getDims(), refShape);
492 TEST_F(RemoveLayerTests, canFoldConstSubgraphs) {
493 IE::BlobMap refBlobs = initConstLayers({"input1", "input2", "input3"});
494 std::vector<std::string> refNewLayers = {"layer5__data9__Const"};
495 { // TODO: method for marking layers
496 getLayer("layer1")->type = "Mul";
497 getLayer("layer2")->type = "Shape";
498 getLayer("layer3")->type = "Power";
499 getLayer("layer3")->params = {{"power", "1"},
502 getLayer("layer4")->type = "Mul";
503 getLayer("layer5")->type = "Mul";
505 float arr[] = {-2.f, 0.f, 54.f};
506 auto ref5 = make_blob_with_precision(getData("data9")->getTensorDesc(), arr);
508 IE::ConstTransformer transformator(net.get());
509 transformator.foldConstSubgraphs();
511 IE::CNNNetwork cnnNetwork(net);
512 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 7);
513 auto newLayer = cnnNetwork.getLayerByName(refNewLayers[0].c_str());
514 auto actualBlob = newLayer->blobs["custom"];
515 ASSERT_NE(actualBlob, nullptr);
516 ASSERT_FALSE(actualBlob->buffer() == nullptr);
517 TestsCommon::compare(*actualBlob, *ref5);
518 ASSERT_EQ(newLayer->type, "Const");
521 TEST_F(RemoveLayerTests, canSkipConstCalculation) {
522 IE::BlobMap refBlobs = initConstLayers({"input1", "input2", "input3"});
523 getLayer("layer6")->type = "Reshape";
525 IE::ConstTransformer transformator(net.get());
526 transformator.foldConstSubgraphs();
528 IE::CNNNetwork cnnNetwork(net);
529 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 8);
532 TEST_F(RemoveLayerTests, canFoldConstWithUnknownImplForShapeDefiningLayers) {
533 IE::BlobMap refBlobs = initConstLayers({"input1", "input2", "input3"});
535 getLayer("layer1")->type = "UNKNOWN";
536 getLayer("layer2")->type = "UNKNOWN";
537 getLayer("layer3")->type = "Shape";
538 getLayer("layer4")->type = "Reshape";
539 getLayer("layer5")->type = "Mul";
540 getLayer("layer6")->type = "Reshape";
543 IE::ConstTransformer transformator(net.get());
544 transformator.foldConstSubgraphs();
546 IE::CNNNetwork cnnNetwork(net);
547 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 8);
548 ASSERT_EQ(getLayer("layer6")->insData.size(), 1);
551 TEST_F(RemoveLayerTests, throwErrorOnFoldWithUnknownImplForNotShapeDefiningLayers) {
552 IE::BlobMap refBlobs = initConstLayers({"input1", "input2", "input3"});
554 getLayer("layer1")->type = "UNKNOWN";
555 getLayer("layer2")->type = "Shape";
556 getLayer("layer3")->type = "Shape";
557 getLayer("layer4")->type = "Mul";
558 getLayer("layer5")->type = "Mul";
559 getLayer("layer6")->type = "Gather";
562 IE::ConstTransformer transformator(net.get());
563 ASSERT_THROW(transformator.foldConstSubgraphs(), IE::details::InferenceEngineException);
566 TEST_F(RemoveLayerTests, canFullTrim) {
567 IE::BlobMap refBlobs = initConstLayers({"input1", "input2", "input3"});
568 auto layer6 = getLayer("layer6");
569 { // TODO: method for marking layers
570 getLayer("layer1")->type = "Mul";
571 getLayer("layer2")->type = "Shape";
572 getLayer("layer3")->type = "Power";
573 getLayer("layer3")->params = {{"power", "1"},
576 getLayer("layer4")->type = "Mul";
577 getLayer("layer5")->type = "Mul";
578 layer6->type = "Reshape";
581 IE::ConstTransformer transformator(net.get());
582 transformator.fullTrim();
584 IE::CNNNetwork cnnNetwork(net);
585 std::string newName = "layer5__data9__Const";
586 ASSERT_THROW(cnnNetwork.getLayerByName(newName.c_str()), IE::NotFound);
587 ASSERT_EQ(net->allLayers().size(), 2);
588 ASSERT_EQ(layer6->insData.size(), 1);
589 ASSERT_EQ(layer6->insData[0].lock(), getData("data10"));
592 TEST_F(RemoveLayerTests, canFullTrimConstToReshape) {
593 IE::BlobMap refBlobs = initConstLayers({"input2"});
594 auto layer1 = getLayer("layer1");
595 layer1->type = "Reshape";
597 IE::ConstTransformer transformator(net.get());
598 transformator.fullTrim();
600 IE::CNNNetwork cnnNetwork(net);
601 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
602 ASSERT_EQ(layer1->insData.size(), 1);
603 ASSERT_EQ(layer1->insData[0].lock(), getData("data1"));
606 TEST_F(AdvancedShapeInferTests, canReshape) {
615 .data("data1", IE::SizeVector{1, 1, 3}, IE::Precision::FP32, IE::Layout::CHW)
616 .data("data2", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
617 .data("data3", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
618 .data("data4", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
619 .layer<IE::CNNLayer>(IE::LayerParams{"input1", "input", IE::Precision::FP32})
620 .layer<IE::CNNLayer>(IE::LayerParams{"input2", "Input", IE::Precision::FP32})
621 .layer<IE::CNNLayer>(IE::LayerParams{"layer1", "Reshape", IE::Precision::FP32})
622 .layer<IE::CNNLayer>(IE::LayerParams{"layer2", "Shape", IE::Precision::FP32})
623 .linkToData("input1", "data1")
624 .linkToData("input2", "data2")
625 .linkDataTo("data1", "layer1")
626 .linkDataTo("data2", "layer2")
627 .linkToData("layer2", "data3")
628 .linkDataTo("data3", "layer1")
629 .linkToData("layer1", "data4")
633 originalLayersNum = net->allLayers().size();
634 IE::CNNNetwork cnnNetwork(net);
635 IE::SizeVector newShape = {1, 3, 1};
636 std::map<std::string, IE::SizeVector> inputShapes = {{"data2", newShape}};
637 cnnNetwork.reshape(inputShapes);
639 ASSERT_NO_THROW(cnnNetwork.getLayerByName("layer2"));
640 ASSERT_EQ(getData("data3")->getTensorDesc().getDims(), IE::SizeVector{3});
641 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
643 IE::ConstTransformer transformator(net.get());
644 transformator.fullTrim();
646 ASSERT_THROW(cnnNetwork.getLayerByName("layer2"), IE::NotFound);
647 ASSERT_EQ(getData("data4")->getTensorDesc().getDims(), newShape);
648 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 1);
651 TEST_F(AdvancedShapeInferTests, canReshape2) {
653 // I3-d3-Shape(L3)-d5
655 // I2-d2-Shape(L2)-d4-Power(L4)-d6-Mul(L5)-d7
657 // I1-d1-Reshape(L1)-d8
660 .data("data1", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
661 .data("data2", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
662 .data("data3", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
663 .data("data4", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
664 .data("data5", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
665 .data("data6", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
666 .data("data7", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
667 .data("data8", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
668 .layer<IE::CNNLayer>(IE::LayerParams{"input1", "input", IE::Precision::FP32})
669 .layer<IE::CNNLayer>(IE::LayerParams{"input2", "Input", IE::Precision::FP32})
670 .layer<IE::CNNLayer>(IE::LayerParams{"input3", "Input", IE::Precision::FP32})
671 .layer<IE::CNNLayer>(IE::LayerParams{"layer1", "Reshape", IE::Precision::FP32})
672 .layer<IE::CNNLayer>(IE::LayerParams{"layer2", "Shape", IE::Precision::FP32})
673 .layer<IE::CNNLayer>(IE::LayerParams{"layer3", "Shape", IE::Precision::FP32})
674 .layer<IE::CNNLayer>(IE::LayerParams{"layer4", "Power", IE::Precision::FP32})
675 .layer<IE::CNNLayer>(IE::LayerParams{"layer5", "Mul", IE::Precision::FP32})
676 .linkToData("input1", "data1")
677 .linkToData("input2", "data2")
678 .linkToData("input3", "data3")
680 .linkDataTo("data1", "layer1")
681 .linkDataTo("data2", "layer2")
682 .linkDataTo("data3", "layer3")
684 .linkToData("layer2", "data4")
685 .linkToData("layer3", "data5")
687 .linkDataTo("data4", "layer4")
689 .linkToData("layer4", "data6")
691 .linkDataTo("data5", "layer5")
692 .linkDataTo("data6", "layer5")
694 .linkToData("layer5", "data7")
696 .linkDataTo("data7", "layer1")
698 .linkToData("layer1", "data8")
704 originalLayersNum = net->allLayers().size();
705 IE::CNNNetwork cnnNetwork(net);
706 IE::SizeVector newShape = {5, 9, 3};
707 std::map<std::string, IE::SizeVector> inputShapes = {{"data1", {135}},
708 {"data2", {2, 1, 1}},
709 {"data3", {1, 3, 1}}};
710 getLayer("layer4")->params = {{"power", "1"},
714 cnnNetwork.reshape(inputShapes);
716 ASSERT_EQ(getData("data7")->getTensorDesc().getDims(), IE::SizeVector{3});
717 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
719 IE::ConstTransformer transformator(net.get());
720 transformator.fullTrim();
722 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 4);
723 ASSERT_EQ(getData("data8")->getTensorDesc().getDims(), newShape);
726 TEST_F(AdvancedShapeInferTests, canReshapeConst) {
730 // I1-d1-Reshape(L1)-d3
733 .data("data1", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
734 .data("data2", IE::SizeVector{3}, IE::Precision::FP32, IE::Layout::C)
735 .data("data3", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
736 .layer<IE::CNNLayer>(IE::LayerParams{"input1", "input", IE::Precision::FP32})
737 .layer<IE::CNNLayer>(IE::LayerParams{"const1", "dummy", IE::Precision::FP32})
738 .layer<IE::CNNLayer>(IE::LayerParams{"layer1", "Reshape", IE::Precision::FP32})
739 .linkToData("input1", "data1")
740 .linkToData("const1", "data2")
741 .linkDataTo("data1", "layer1")
742 .linkDataTo("data2", "layer1")
743 .linkToData("layer1", "data3")
746 originalLayersNum = net->allLayers().size();
747 IE::CNNNetwork cnnNetwork(net);
748 initConstLayers({"const1"});
749 IE::SizeVector newOutShape = {1, 2, 3};
750 IE::SizeVector newInShape = {IE::details::product(newOutShape)};
752 std::map<std::string, IE::SizeVector> inputShapes = {{"data1", newInShape}};
754 cnnNetwork.reshape(inputShapes);
756 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
758 IE::ConstTransformer transformator(net.get());
759 transformator.fullTrim();
761 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 1);
762 ASSERT_EQ(getData("data1")->getTensorDesc().getDims(), newInShape);
763 ASSERT_EQ(getData("data3")->getTensorDesc().getDims(), newOutShape);
766 TEST_F(AdvancedShapeInferTests, canReshapeCHWConst) {
771 .data("data1", IE::SizeVector{3, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
772 .data("data2", IE::SizeVector{1, 1, 1}, IE::Precision::FP32, IE::Layout::CHW)
773 .layer<IE::CNNLayer>(IE::LayerParams{"const", "dummy", IE::Precision::FP32})
774 .layer<IE::CNNLayer>(IE::LayerParams{"tile", "Tile", IE::Precision::FP32})
775 .linkToData("const", "data1")
776 .linkDataTo("data1", "tile")
777 .linkToData("tile", "data2")
780 getLayer("tile")->params = {{"axis", "0"},
782 originalLayersNum = net->allLayers().size();
783 IE::CNNNetwork cnnNetwork(net);
784 initConstLayers({"const"});
786 cnnNetwork.reshape({});
788 IE::SizeVector expectedDims = {2, 1, 3};
789 ASSERT_EQ(getData("data2")->getTensorDesc().getDims(), expectedDims);
792 TEST_F(AdvancedShapeInferTests, canReshapeWithScalar) {
796 // I1-d1-Reshape(L1)-d3
799 .data("data1", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
800 .data("data2", IE::SizeVector{}, IE::Precision::FP32, IE::Layout::SCALAR)
801 .data("data3", IE::SizeVector{1}, IE::Precision::FP32, IE::Layout::C)
802 .layer<IE::CNNLayer>(IE::LayerParams{"input1", "input", IE::Precision::FP32})
803 .layer<IE::CNNLayer>(IE::LayerParams{"scalar", "dummy", IE::Precision::FP32})
804 .layer<IE::CNNLayer>(IE::LayerParams{"layer1", "Reshape", IE::Precision::FP32})
805 .linkToData("input1", "data1")
806 .linkToData("scalar", "data2")
807 .linkDataTo("data1", "layer1")
808 .linkDataTo("data2", "layer1")
809 .linkToData("layer1", "data3")
812 originalLayersNum = net->allLayers().size();
813 IE::CNNNetwork cnnNetwork(net);
814 initConstLayers({"scalar"});
815 IE::SizeVector newOutShape = {1};
816 IE::SizeVector newInShape = {IE::details::product(newOutShape)};
818 std::map<std::string, IE::SizeVector> inputShapes = {{"data1", newInShape}};
820 cnnNetwork.reshape(inputShapes);
822 ASSERT_EQ(net->allLayers().size(), originalLayersNum);
824 IE::ConstTransformer transformator(net.get());
825 transformator.fullTrim();
827 ASSERT_EQ(net->allLayers().size(), originalLayersNum - 1);
828 ASSERT_EQ(getData("data1")->getTensorDesc().getDims(), newInShape);
829 ASSERT_EQ(getData("data3")->getTensorDesc().getDims(), newOutShape);