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 IE_SUPPRESS_DEPRECATED_START
110 CNNNetwork cloned (clone.get());
111 IE_SUPPRESS_DEPRECATED_END
112 auto idMemOutput = cloned.getLayerByName("1")->GetParamAsString("id");
113 auto idMemInput = cloned.getLayerByName("2")->GetParamAsString("id");
115 ASSERT_STREQ(idMemInput.c_str(), idMemOutput.c_str());
116 ASSERT_STREQ(idMemInput.c_str(), "r-1-2-3");
119 TEST_F(GraphCopyTests, canPreserveGetData) {
120 auto clone = CNNNetCopy<MockCopier>(mockNet, mc);
122 ASSERT_NE(clone->getData("1"), nullptr);
123 ASSERT_NE(clone->getData("2"), nullptr);
124 ASSERT_NE(clone->getData("3"), nullptr);
125 ASSERT_NE(clone->getData("4"), nullptr);
126 ASSERT_NE(clone->getData("5"), nullptr);
129 TEST_F(GraphCopyTests, canPreserveTopology) {
130 auto iclone = CNNNetCopy<MockCopier>(mockNet, mc);
131 auto clone = CNNNetwork(iclone);
133 ASSERT_EQ(clone.layerCount(), 5);
135 EXPECT_CALL(*this, visited(1, 0)).Times(1);
136 EXPECT_CALL(*this, visited(2, 1)).Times(1);
138 EXPECT_CALL(*this, visited2(3, 0)).Times(1);
139 EXPECT_CALL(*this, visited2(4, AnyOf(1, 2))).Times(1);
140 EXPECT_CALL(*this, visited2(5, AnyOf(1, 2))).Times(1);
141 EXPECT_CALL(*this, visited2(2, 3)).Times(1);
144 CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
145 visited(ID(layer), idx++);
149 CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
150 visited2(ID(layer), idx++);
155 using namespace GNAPluginNS;
156 struct _FP32_2_FP32 : public GNAPluginNS::details::QuantDescTmpl<float, float, float, float, float> {
158 using FP32_2_FP32 = GNAPluginNS::details::QuantPair<_FP32_2_FP32 , _FP32_2_FP32 >;
160 TEST_F(GraphCopyTests, canQuantizeTopology) {
162 auto iclone = ModelQuantizer<FP32_2_FP32>().quantize(mockNet, std::vector<float >({1.0f, 1.0f}));
163 auto clone = CNNNetwork(iclone);
165 CNNNetBFS(clone.getLayerByName("1"), [&](CNNLayerPtr layer) {
166 auto params = getInjectedData<QuantizedLayerParams>(layer);
167 ASSERT_NE(params, nullptr);
170 CNNNetBFS(clone.getLayerByName("3"), [&](CNNLayerPtr layer) {
171 auto params = getInjectedData<QuantizedLayerParams>(layer);
172 ASSERT_NE(params, nullptr);
178 TEST(CNNSpecificGraphCopyTests, copyNetworkWithClampLayer) {
179 CNNNetReader netReader;
180 //define minimal network with Clamp layer
181 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
182 <net name="SingleLayer" version="2" batch="1">
184 <layer id="0" name="InputLayer" precision="FP16" type="Input">
194 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
195 <data max="6" min="0"/>
215 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
219 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
220 ASSERT_TRUE(netReader.isParseSuccess());
221 auto network = netReader.getNetwork();
224 struct EmptyStruct {};
225 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
226 auto copied_net_ptr = CNNNetCopy(network, visitor);
227 IE_SUPPRESS_DEPRECATED_START
228 auto copied_net = CNNNetwork(copied_net_ptr.get());
229 IE_SUPPRESS_DEPRECATED_END
231 //check that Clamp layer was properly copied
232 auto layer = std::dynamic_pointer_cast<ClampLayer>(copied_net.getLayerByName("ClampLayer"));
233 ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Clamp layer pointer. "
234 "Net copy could be incorrect.";
237 TEST(CNNSpecificGraphCopyTests, copyPreprocess) {
238 CNNNetReader netReader;
239 //define minimal network with Clamp layer
240 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
241 <net name="SingleLayer" version="2" batch="1">
243 <layer id="0" name="InputLayer" precision="FP16" type="Input">
253 <layer id="1" name="ClampLayer" precision="FP16" type="Clamp">
254 <data max="6" min="0"/>
274 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
276 <pre-process reference-layer-name="InputLayer">
289 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
290 ASSERT_TRUE(netReader.isParseSuccess());
291 auto network = netReader.getNetwork();
294 struct EmptyStruct {};
295 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
296 auto copied_net_ptr = CNNNetCopy(network, visitor);
297 IE_SUPPRESS_DEPRECATED_START
298 auto copied_net = CNNNetwork(copied_net_ptr.get());
299 IE_SUPPRESS_DEPRECATED_END
301 //check that pre process Info existed in copied network
302 auto &pp = copied_net.getInputsInfo().begin()->second->getPreProcess();
303 ASSERT_EQ(MEAN_VALUE, pp.getMeanVariant());
304 ASSERT_EQ(3, pp.getNumberOfChannels());
307 ASSERT_FLOAT_EQ(pp[0]->meanValue, 104);
308 ASSERT_FLOAT_EQ(pp[1]->meanValue, 116);
309 ASSERT_FLOAT_EQ(pp[2]->meanValue, 122);
312 TEST(CNNSpecificGraphCopyTests, copyNetworkWithDeconvolution) {
313 CNNNetReader netReader;
314 //define minimal network with deconvolution layer
315 const std::string SINGLE_LAYER_MODEL = R"V0G0N(
316 <net name="SingleLayer" version="2" batch="1">
318 <layer id="0" name="InputLayer" precision="FP16" type="Input">
328 <layer name="upsample_merged" type="Deconvolution" precision="FP16" id="1">
329 <deconvolution_data stride-x="2" stride-y="2" pad-x="1" pad-y="1" kernel-x="4" kernel-y="4" output="384" group="384"/>
346 <weights offset="5517824" size="12288"/>
350 <edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
354 ASSERT_NO_THROW(netReader.ReadNetwork(SINGLE_LAYER_MODEL.data(), SINGLE_LAYER_MODEL.length()));
355 ASSERT_TRUE(netReader.isParseSuccess());
356 auto network = netReader.getNetwork();
359 struct EmptyStruct {};
360 auto visitor = [&](CNNLayerPtr lp) { return injectData<EmptyStruct>(lp); };
361 auto copied_net_ptr = CNNNetCopy(network, visitor);
362 IE_SUPPRESS_DEPRECATED_START
363 auto copied_net = CNNNetwork(copied_net_ptr.get());
364 IE_SUPPRESS_DEPRECATED_END
366 // check that Clamp layer was properly copied
367 auto layer = std::dynamic_pointer_cast<DeconvolutionLayer>(copied_net.getLayerByName("upsample_merged"));
368 ASSERT_NE(layer, nullptr) << "Could not perform dynamic cast from base pointer to Deconvolution layer pointer. "
369 "Net copy could be incorrect.";