Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / inference_engine_tests / layer_transform_test.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <vector>
6
7 #include <gtest/gtest.h>
8 #include <mock_icnn_network.hpp>
9 #include "inference_engine/layer_transform.hpp"
10
11 using namespace std;
12 using namespace InferenceEngine;
13 using namespace ::testing;
14
15 class LayerTransformTest : public ::testing::Test {
16  protected:
17     struct TransformMocker {
18         MOCK_CONST_METHOD0(mockTransform, bool());
19         template <class T>
20         bool operator () (T ) const {
21             return mockTransform();
22         }
23     };
24     TransformMocker tmock;
25     void SetUp() override  {
26     }
27 };
28
29 TEST_F(LayerTransformTest, canInjectIntoConvolutionLayer) {
30
31     ConvolutionLayer lc(LayerParams{"name", "type", Precision::FP32});
32
33     lc._kernel.clear();
34     lc._kernel.insert(X_AXIS, 23);
35     lc._kernel.insert(Y_AXIS, 24);
36
37     auto layerWithData = injectData<int>(lc);
38     dynamic_cast<details::LayerInjector<ConvolutionLayer, int>*>(layerWithData.get())->injected = 5;
39
40     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[X_AXIS],  23);
41     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[Y_AXIS],  24);
42 }
43
44 TEST_F(LayerTransformTest, canInjectValue) {
45
46     ConvolutionLayer lc(LayerParams{"name", "type", Precision::FP32});
47
48     lc._kernel.clear();
49     lc._kernel.insert(X_AXIS, 23);
50     lc._kernel.insert(Y_AXIS, 24);
51
52     auto layerWithData = injectData<int>(lc, 6);
53     ASSERT_EQ((dynamic_cast<details::LayerInjector<ConvolutionLayer, int>*>(layerWithData.get())->injected), 6);
54
55     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[X_AXIS],  23);
56     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[Y_AXIS],  24);
57 }
58
59 TEST_F(LayerTransformTest, canAccessInjectedValue) {
60
61     ConvolutionLayer lc(LayerParams{"name", "type", Precision::FP32});
62
63     lc._kernel.clear();
64     lc._kernel.insert(X_AXIS, 23);
65     lc._kernel.insert(Y_AXIS, 24);
66
67     auto layerWithData = injectData<int>(lc, 7);
68     auto injectedData = getInjectedData<int>(layerWithData);
69
70     ASSERT_NE(injectedData, nullptr);
71     ASSERT_EQ(*injectedData, 7);
72
73     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[X_AXIS],  23);
74     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[Y_AXIS],  24);
75 }
76
77 TEST_F(LayerTransformTest, returnNullIfNotInjected) {
78
79     ConvolutionLayer lc(LayerParams{"name", "type", Precision::FP32});
80
81     lc._kernel.clear();
82     lc._kernel.insert(X_AXIS, 23);
83     lc._kernel.insert(Y_AXIS, 24);
84
85     auto layerWithData = injectData<int>(lc, 7);
86
87     ASSERT_EQ(getInjectedData<float>(layerWithData), nullptr);
88
89     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[X_AXIS],  23);
90     ASSERT_EQ(dynamic_cast<ConvolutionLayer*>(layerWithData.get())->_kernel[Y_AXIS],  24);
91 }
92
93 struct SomeData {
94     int ivalue;
95     std::string name;
96     float value;
97 };
98
99 TEST_F(LayerTransformTest, canInjectStruct) {
100
101     FullyConnectedLayer fc(LayerParams{"name", "type", Precision::FP32});
102     fc._out_num = 9;
103
104     auto layerWithData = injectData<SomeData>(fc, SomeData({11, "myname", 12.f}));
105
106     auto some = getInjectedData<SomeData>(layerWithData);
107
108     ASSERT_NE(some, nullptr);
109     ASSERT_STREQ(some->name.c_str(), "myname");
110     ASSERT_EQ(some->ivalue, 11);
111     ASSERT_FLOAT_EQ(some->value, 12.f);
112     ASSERT_EQ(dynamic_cast<FullyConnectedLayer*>(layerWithData.get())->_out_num,  9);
113
114 }
115 //  out data array items is fully copied, not just references to them
116 TEST_F(LayerTransformTest, injectioWillCopyOutData) {
117
118     auto fc = std::make_shared<FullyConnectedLayer>(LayerParams{"name", "type", Precision::FP32});
119     ASSERT_NE(fc, nullptr);
120     fc->_out_num = 9;
121
122     auto data  = std::make_shared<Data>("N1", Precision::FP32);
123     data->getCreatorLayer() = fc;
124     fc->outData.push_back(data);
125
126     auto layerWithData = injectData<SomeData>(fc, SomeData({11, "myname", 12.f}));
127
128     ASSERT_EQ(data->getCreatorLayer().lock(), layerWithData->outData[0]->getCreatorLayer().lock());
129     ASSERT_NE(data.get(), layerWithData->outData[0].get());
130 }
131
132 TEST_F(LayerTransformTest, injectioWillCopyInputData) {
133
134     auto fc = std::make_shared<FullyConnectedLayer>(LayerParams{"name", "type", Precision::FP32});
135     ASSERT_NE(fc, nullptr);
136     fc->_out_num = 9;
137
138     auto data  = std::make_shared<Data>("N1", Precision::FP32);
139     data->getCreatorLayer() = fc;
140     fc->insData.push_back(data);
141
142     auto layerWithData = injectData<SomeData>(fc, SomeData({11, "myname", 12.f}));
143
144     ASSERT_EQ(data.get(), layerWithData->insData[0].lock().get());
145 }
146
147 TEST_F(LayerTransformTest, transformWillOnlyTransformOnce) {
148
149     auto fc = std::make_shared<FullyConnectedLayer>(LayerParams{"name", "type", Precision::FP32});
150     ASSERT_NE(fc, nullptr);
151     fc->_out_num = 9;
152
153     EXPECT_CALL(tmock, mockTransform()).WillOnce(Return(true));
154
155     // CNNLayer might be selected in case of overloads
156     transformLayer(fc, tmock);
157 }
158
159 TEST_F(LayerTransformTest, transformCanGoToParentIfChildTransformNotImplemented) {
160
161     auto fc = std::make_shared<FullyConnectedLayer>(LayerParams{"name", "type", Precision::FP32});
162     ASSERT_NE(fc, nullptr);
163     fc->_out_num = 9;
164
165     Sequence s1;
166     EXPECT_CALL(tmock, mockTransform()).InSequence(s1).WillOnce(Return(false));
167     EXPECT_CALL(tmock, mockTransform()).InSequence(s1).WillOnce(Return(false));
168     EXPECT_CALL(tmock, mockTransform()).InSequence(s1).WillOnce(Return(true));
169
170     // CNNLayer might be selected in case of overloads
171     transformLayer(fc, tmock);
172 }