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, getPrecision()).WillRepeatedly(Return(Precision::FP16));
50 EXPECT_CALL(*mockNet, getBatchSize()).WillRepeatedly(Return(12));
51 EXPECT_CALL(*mockNet, getName(_, _)).WillRepeatedly(Invoke([](char *pName, size_t len) {
52 memcpy(pName, "nm", 3);
55 EXPECT_CALL(mc, copyLayer(_)).WillRepeatedly(Invoke([](CNNLayerPtr ptr) {
61 TEST_F(GraphCopyTests, copyNetworkPreserveBasicParams) {
62 auto clone = CNNNetCopy<MockCopier>(*mockNet, mc);
64 //network was copied not just assigned
65 ASSERT_NE(clone.get(), mockNet.get());
66 ASSERT_EQ(clone->getPrecision(), Precision::FP16);
69 clone->getName(name, sizeof(name));
70 ASSERT_STREQ(name, "nm");
73 TEST_F(GraphCopyTests, canPreserveBatchWhenCopyNetwork) {
74 auto clone = CNNNetCopy<MockCopier>(*mockNet, mc);
75 ASSERT_EQ(clone->getBatchSize(), 12);
79 TEST_F(GraphCopyTests, canPreserveInputs) {
80 auto clone = CNNNetCopy<MockCopier>(*mockNet, mc);
82 InputsDataMap inputs, inputsTarget;
83 InputsDataMap heads, headsTarget;
85 clone->getInputsInfo(inputs);
86 mockNet->getInputsInfo(inputsTarget);
87 ASSERT_INPUTS_INFO_EQ(inputs, inputsTarget);
90 TEST_F(GraphCopyTests, canPreserveOutputs) {
92 auto clone = CNNNetCopy<MockCopier>(*mockNet, mc);
94 OutputsDataMap outTarget, outSource;
95 clone->getOutputsInfo(outTarget);
96 mockNet->getOutputsInfo(outSource);
98 ASSERT_OUTPUTS_INFO_EQ(outSource, outTarget);
101 TEST_F(GraphCopyTests, canPreserveAttributes) {
102 auto clone = CNNNetCopy<MockCopier>(*mockNet, mc);
103 ADD_ATTR(1, "id", "r-1-2-3");
104 ADD_ATTR(2, "id", "r-1-2-3");
105 CNNNetwork cloned (clone);
106 auto idMemOutput = cloned.getLayerByName("1")->GetParamAsString("id");
107 auto idMemInput = cloned.getLayerByName("2")->GetParamAsString("id");
109 ASSERT_STREQ(idMemInput.c_str(), idMemOutput.c_str());
110 ASSERT_STREQ(idMemInput.c_str(), "r-1-2-3");
113 TEST_F(GraphCopyTests, canPreserveGetData) {
114 auto clone = CNNNetCopy<MockCopier>(*mockNet, mc);
116 ASSERT_NE(clone->getData("1"), nullptr);
117 ASSERT_NE(clone->getData("2"), nullptr);
118 ASSERT_NE(clone->getData("3"), nullptr);
119 ASSERT_NE(clone->getData("4"), nullptr);
120 ASSERT_NE(clone->getData("5"), nullptr);
123 TEST_F(GraphCopyTests, canPreserveTopology) {
124 auto iclone = CNNNetCopy<MockCopier>(*mockNet, mc);
125 auto clone = CNNNetwork(iclone);
127 ASSERT_EQ(clone.layerCount(), 5);
129 EXPECT_CALL(*this, visited(1, 0)).Times(1);
130 EXPECT_CALL(*this, visited(2, 1)).Times(1);
132 EXPECT_CALL(*this, visited2(3, 0)).Times(1);
133 EXPECT_CALL(*this, visited2(4, AnyOf(1, 2))).Times(1);
134 EXPECT_CALL(*this, visited2(5, AnyOf(1, 2))).Times(1);
135 EXPECT_CALL(*this, visited2(2, 3)).Times(1);
138 CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
139 visited(ID(layer), idx++);
143 CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
144 visited2(ID(layer), idx++);
149 using namespace GNAPluginNS;
150 struct _FP32_2_FP32 : public GNAPluginNS::details::QuantDescTmpl<float, float, float, float, float> {
152 using FP32_2_FP32 = GNAPluginNS::details::QuantPair<_FP32_2_FP32 , _FP32_2_FP32 >;
154 TEST_F(GraphCopyTests, canQuantizeTopology) {
156 auto iclone = ModelQuantizer<FP32_2_FP32>().quantize(*mockNet, std::vector<float >({1.0f, 1.0f}));
157 auto clone = CNNNetwork(iclone);
159 CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
160 auto params = getInjectedData<QuantizedLayerParams>(layer);
161 ASSERT_NE(params, nullptr);
164 CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
165 auto params = getInjectedData<QuantizedLayerParams>(layer);
166 ASSERT_NE(params, nullptr);
172 TEST(CNNSpecificGraphCopyTests, copyNetworkWithClampLayer) {
173 CNNNetReader netReader;
174 //define minimal network with Clamp layer
175 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
176 <net name="SingleLayer" version="2" batch="1">
178 <layer id="0" name="InputLayer" precision="FP16" type="Input">
188 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
189 <data max="6" min="0"/>
209 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
213 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
214 ASSERT_TRUE(netReader.isParseSuccess());
215 auto network = netReader.getNetwork();
218 struct EmptyStruct {};
219 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
220 auto copied_net_ptr = CNNNetCopy(network, visitor);
221 auto copied_net = CNNNetwork(copied_net_ptr);
223 //check that Clamp layer was properly copied
224 auto layer = std::dynamic_pointer_cast<ClampLayer>(copied_net.getLayerByName("ClampLayer"));
225 ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Clamp layer pointer. "
226 "Net copy could be incorrect.";
229 TEST(CNNSpecificGraphCopyTests, copyPreprocess) {
230 CNNNetReader netReader;
231 //define minimal network with Clamp layer
232 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
233 <net name="SingleLayer" version="2" batch="1">
235 <layer id="0" name="InputLayer" precision="FP16" type="Input">
245 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
246 <data max="6" min="0"/>
266 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
268 <pre-process reference-layer-name="InputLayer">
281 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
282 ASSERT_TRUE(netReader.isParseSuccess());
283 auto network = netReader.getNetwork();
286 struct EmptyStruct {};
287 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
288 auto copied_net_ptr = CNNNetCopy(network, visitor);
289 auto copied_net = CNNNetwork(copied_net_ptr);
291 //check that pre process Info existed in copied network
292 auto &pp = copied_net.getInputsInfo().begin()->second->getPreProcess();
293 ASSERT_EQ(MEAN_VALUE, pp.getMeanVariant());
294 ASSERT_EQ(3, pp.getNumberOfChannels());
297 ASSERT_FLOAT_EQ(pp[0]->meanValue, 104);
298 ASSERT_FLOAT_EQ(pp[1]->meanValue, 116);
299 ASSERT_FLOAT_EQ(pp[2]->meanValue, 122);
302 TEST(CNNSpecificGraphCopyTests, copyNetworkWithDeconvolution) {
303 CNNNetReader netReader;
304 //define minimal network with deconvolution layer
305 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
306 <net name="SingleLayer" version="2" batch="1">
308 <layer id="0" name="InputLayer" precision="FP16" type="Input">
318 <layer name="upsample_merged" type="Deconvolution" precision="FP16" id="1">
319 <deconvolution_data stride-x="2" stride-y="2" pad-x="1" pad-y="1" kernel-x="4" kernel-y="4" output="384" group="384"/>
336 <weights offset="5517824" size="12288"/>
340 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
344 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
345 ASSERT_TRUE(netReader.isParseSuccess());
346 auto network = netReader.getNetwork();
349 struct EmptyStruct {};
350 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
351 auto copied_net_ptr = CNNNetCopy(network, visitor);
352 auto copied_net = CNNNetwork(copied_net_ptr);
354 // check that Clamp layer was properly copied
355 auto layer = std::dynamic_pointer_cast<DeconvolutionLayer>(copied_net.getLayerByName("upsample_merged"));
356 ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Deconvolution layer pointer. "
357 "Net copy could be incorrect.";