1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include <gtest/gtest.h>
6 #include <inference_engine/graph_tools.hpp>
7 #include "test_assertions.hpp"
8 #include <unordered_set>
9 #include <gmock/gmock-generated-function-mockers.h>
10 #include <gmock/gmock-generated-matchers.h>
11 #include <gmock/gmock-more-actions.h>
12 #include "xml_father.hpp"
13 #include "ie_common.h"
14 #include "graph_test_base.hpp"
18 # include <gna_plugin/quantization/model_quantizer.hpp>
21 using namespace testing;
22 using namespace InferenceEngine;
24 using namespace GraphTest;
27 class GraphCopyTests : public GraphTestsBase {
32 void SetUp() override {
33 GraphTestsBase::_batchSize = 12;
34 GraphTestsBase::SetUp();
41 EXPECT_CALL(mockNet, getInputsInfo(_)).WillRepeatedly(WithArg<0>(Invoke([&](InputsDataMap &maps) {
42 prepareInputs(maps, 12);
45 EXPECT_CALL(mockNet, getOutputsInfo(_)).WillRepeatedly(WithArg<0>(Invoke([&](OutputsDataMap &maps) {
49 EXPECT_CALL(mockNet, getTargetDevice()).WillRepeatedly(Return(TargetDevice::eCPU));
50 EXPECT_CALL(mockNet, getPrecision()).WillRepeatedly(Return(Precision::FP16));
51 EXPECT_CALL(mockNet, getBatchSize()).WillRepeatedly(Return(12));
52 EXPECT_CALL(mockNet, getName(_, _)).WillRepeatedly(Invoke([](char *pName, size_t len) {
53 memcpy(pName, "nm", 3);
56 EXPECT_CALL(mc, copyLayer(_)).WillRepeatedly(Invoke([](CNNLayerPtr ptr) {
62 TEST_F(GraphCopyTests, copyNetworkPreserveBasicParams) {
64 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
66 //network was copied not just assigned
67 ASSERT_NE(clone.get(), &mockNet);
68 ASSERT_EQ(clone->getTargetDevice(), TargetDevice::eCPU);
69 ASSERT_EQ(clone->getPrecision(), Precision::FP16);
72 clone->getName(name, sizeof(name));
73 ASSERT_STREQ(name, "nm");
76 TEST_F(GraphCopyTests, canPreserveBatchWhenCopyNetwork) {
77 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
78 ASSERT_EQ(clone->getBatchSize(), 12);
82 TEST_F(GraphCopyTests, canPreserveInputs) {
83 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
85 InputsDataMap inputs, inputsTarget;
86 InputsDataMap heads, headsTarget;
88 clone->getInputsInfo(inputs);
89 mockNet.getInputsInfo(inputsTarget);
90 ASSERT_INPUTS_INFO_EQ(inputs, inputsTarget);
93 TEST_F(GraphCopyTests, canPreserveOutputs) {
95 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
97 OutputsDataMap outTarget, outSource;
98 clone->getOutputsInfo(outTarget);
99 mockNet.getOutputsInfo(outSource);
101 ASSERT_OUTPUTS_INFO_EQ(outSource, outTarget);
104 TEST_F(GraphCopyTests, canPreserveAttributes) {
105 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
106 ADD_ATTR(1, "id", "r-1-2-3");
107 ADD_ATTR(2, "id", "r-1-2-3");
109 CNNNetwork cloned (clone.get());
110 auto idMemOutput = cloned.getLayerByName("1")->GetParamAsString("id");
111 auto idMemInput = cloned.getLayerByName("2")->GetParamAsString("id");
113 ASSERT_STREQ(idMemInput.c_str(), idMemOutput.c_str());
114 ASSERT_STREQ(idMemInput.c_str(), "r-1-2-3");
117 TEST_F(GraphCopyTests, canPreserveGetData) {
118 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
120 ASSERT_NE(clone->getData("1"), nullptr);
121 ASSERT_NE(clone->getData("2"), nullptr);
122 ASSERT_NE(clone->getData("3"), nullptr);
123 ASSERT_NE(clone->getData("4"), nullptr);
124 ASSERT_NE(clone->getData("5"), nullptr);
127 TEST_F(GraphCopyTests, canPreserveTopology) {
128 auto iclone = CNNNetCopy<MockCopier>(mockNet, mc);
129 auto clone = CNNNetwork(iclone);
131 ASSERT_EQ(clone.layerCount(), 5);
133 EXPECT_CALL(*this, visited(1, 0)).Times(1);
134 EXPECT_CALL(*this, visited(2, 1)).Times(1);
136 EXPECT_CALL(*this, visited2(3, 0)).Times(1);
137 EXPECT_CALL(*this, visited2(4, AnyOf(1, 2))).Times(1);
138 EXPECT_CALL(*this, visited2(5, AnyOf(1, 2))).Times(1);
139 EXPECT_CALL(*this, visited2(2, 3)).Times(1);
142 CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
143 visited(ID(layer), idx++);
147 CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
148 visited2(ID(layer), idx++);
153 using namespace GNAPluginNS;
154 struct _FP32_2_FP32 : public GNAPluginNS::details::QuantDescTmpl<float, float, float, float, float> {
156 using FP32_2_FP32 = GNAPluginNS::details::QuantPair<_FP32_2_FP32 , _FP32_2_FP32 >;
158 TEST_F(GraphCopyTests, canQuantizeTopology) {
160 auto iclone = ModelQuantizer<FP32_2_FP32>().quantize(mockNet, 1.0f);
161 auto clone = CNNNetwork(iclone);
163 CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
164 auto params = getInjectedData<QuantizedLayerParams>(layer);
165 ASSERT_NE(params, nullptr);
168 CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
169 auto params = getInjectedData<QuantizedLayerParams>(layer);
170 ASSERT_NE(params, nullptr);
176 TEST(CNNSpecificGraphCopyTests, copyNetworkWithClampLayer) {
177 CNNNetReader netReader;
178 //define minimal network with Clamp layer
179 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
180 <net name="SingleLayer" version="2" batch="1">
182 <layer id="0" name="InputLayer" precision="FP16" type="Input">
192 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
193 <data max="6" min="0"/>
213 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
217 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
218 ASSERT_TRUE(netReader.isParseSuccess());
219 auto network = netReader.getNetwork();
222 struct EmptyStruct {};
223 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
224 auto copied_net_ptr = CNNNetCopy(network, visitor);
225 auto copied_net = CNNNetwork(copied_net_ptr.get());
227 //check that Clamp layer was properly copied
228 auto layer = std::dynamic_pointer_cast<ClampLayer>(copied_net.getLayerByName("ClampLayer"));
229 ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Clamp layer pointer. "
230 "Net copy could be incorrect.";
233 TEST(CNNSpecificGraphCopyTests, copyPreprocess) {
234 CNNNetReader netReader;
235 //define minimal network with Clamp layer
236 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
237 <net name="SingleLayer" version="2" batch="1">
239 <layer id="0" name="InputLayer" precision="FP16" type="Input">
249 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
250 <data max="6" min="0"/>
270 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
272 <pre-process reference-layer-name="InputLayer">
285 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
286 ASSERT_TRUE(netReader.isParseSuccess());
287 auto network = netReader.getNetwork();
290 struct EmptyStruct {};
291 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
292 auto copied_net_ptr = CNNNetCopy(network, visitor);
293 auto copied_net = CNNNetwork(copied_net_ptr.get());
295 //check that pre process Info existed in copied network
296 auto &pp = copied_net.getInputsInfo().begin()->second->getPreProcess();
297 ASSERT_EQ(MEAN_VALUE, pp.getMeanVariant());
298 ASSERT_EQ(3, pp.getNumberOfChannels());
301 ASSERT_FLOAT_EQ(pp[0]->meanValue, 104);
302 ASSERT_FLOAT_EQ(pp[1]->meanValue, 116);
303 ASSERT_FLOAT_EQ(pp[2]->meanValue, 122);
306 TEST(CNNSpecificGraphCopyTests, copyNetworkWithDeconvolution) {
307 CNNNetReader netReader;
308 //define minimal network with deconvolution layer
309 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
310 <net name="SingleLayer" version="2" batch="1">
312 <layer id="0" name="InputLayer" precision="FP16" type="Input">
322 <layer name="upsample_merged" type="Deconvolution" precision="FP16" id="1">
323 <deconvolution_data stride-x="2" stride-y="2" pad-x="1" pad-y="1" kernel-x="4" kernel-y="4" output="384" group="384"/>
340 <weights offset="5517824" size="12288"/>
344 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
348 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
349 ASSERT_TRUE(netReader.isParseSuccess());
350 auto network = netReader.getNetwork();
353 struct EmptyStruct {};
354 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
355 auto copied_net_ptr = CNNNetCopy(network, visitor);
356 auto copied_net = CNNNetwork(copied_net_ptr.get());
358 // check that Clamp layer was properly copied
359 auto layer = std::dynamic_pointer_cast<DeconvolutionLayer>(copied_net.getLayerByName("upsample_merged"));
360 ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Deconvolution layer pointer. "
361 "Net copy could be incorrect.";