Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / scale_grad_weights_test.cpp
1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 #include <gtest/gtest.h>
19 #include "api/CPP/memory.hpp"
20 #include <api/CPP/data.hpp>
21 #include <api/CPP/input_layout.hpp>
22 #include <api/CPP/mutable_data.hpp>
23 #include "api/CPP/scale_grad_weights.hpp"
24 #include <api/CPP/topology.hpp>
25 #include <api/CPP/network.hpp>
26 #include <api/CPP/engine.hpp>
27 #include "test_utils/test_utils.h"
28
29 #include <iostream>
30
31 using namespace cldnn;
32 using namespace tests;
33
34 TEST(scale_grad_weights_gpu, basic_in2x3x2x2) {
35     //  Scale  : 2x3x2x2
36     //  Input  : 2x3x2x2
37     //  Output : 2x3x2x2
38
39     //  Input:
40     //  f0: b0:  1    2  -10   b1:   0    0    -11
41     //  f0: b0:  3    4  -14   b1:   0.5 -0.5  -15  
42     //  f1: b0:  5    6  -12   b1:   1.5  5.2  -13     
43     //  f1: b0:  7    8  -16   b1:   12   8    -17
44     //
45     //  Input grad:
46     //  f0: b0:  1    2   3   b1:   0    0    -11
47     //  f0: b0:  4    5  -6   b1:   0.5 -0.5  -15  
48     //  f1: b0: -7    8  -9   b1:   1.5  5.2  -13     
49     //  f1: b0:  12  11  10   b1:   12   8    -17
50     //
51     //  Scale:
52     //  f0: 0.1
53     //  f1: 0.6  
54
55     const auto& engine = get_test_engine();
56
57     auto input = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 2, 3, 2 } });
58     auto grad_input = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 2, 3, 2 } });
59     auto scale_input = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 2, 1, 1 } });
60
61     topology topology;
62     topology.add(input_layout("input", input.get_layout()));
63     topology.add(mutable_data("scale_input", scale_input));
64     topology.add(data("grad_input", grad_input));
65     topology.add(scale_grad_weights("scale_grad", "input", "grad_input", "scale_input"));
66
67     std::vector<float> input_vec = { 
68         1.f, 2.f, -10.f,
69         3.f, 4.f, -14.f,
70         5.f, 6.f, -12.f,
71         7.f, 8.f, -16.f,
72         0.f, 0.f, -11.f,
73         0.5f, -0.5f, -15.f,
74         1.5f, 5.2f, -13.f,
75         12.f, 8.f, -17.f
76     };
77     set_values(input, input_vec);
78
79     std::vector<float> grad_vec = {
80         1.f, 2.f, 3.f,
81         4.f, 5.f, -6.f,
82         -7.f, 8.f, -9.f,
83         12.f, 11.f, 10.f,
84         0.f, 0.f, -11.f,
85         0.5f, -0.5f, -15.f,
86         1.5f, 5.2f, -13.f,
87         12.f, 8.f, -17.f
88     };
89     set_values(grad_input, grad_vec);
90
91     std::vector<float> scale_input_vec = {
92         0.1f, 0.6f
93     };
94     set_values(scale_input, scale_input_vec);
95
96     build_options options;
97     network network(engine, topology);
98     
99     network.set_learning_rate(0.0001f);
100     network.set_input_data("input", input);
101
102     std::vector<float> expected_out = {
103         0.05625f, 0.517171f
104     };
105
106     auto outputs = network.execute();
107
108     auto output_ptr = scale_input.pointer<float>();
109
110     for (unsigned int i = 0; i < expected_out.size(); ++i) {
111         EXPECT_NEAR(output_ptr[i], expected_out[i], 1e-04F);
112     }
113 }
114
115 TEST(scale_grad_weights_gpu, basic_in2x3x2x2_bias) {
116     //  Scale  : 2x3x2x2
117     //  Input  : 2x3x2x2
118     //  Output : 2x3x2x2
119
120     //  Input:
121     //  f0: b0:  1    2  -10   b1:   0    0    -11
122     //  f0: b0:  3    4  -14   b1:   0.5 -0.5  -15  
123     //  f1: b0:  5    6  -12   b1:   1.5  5.2  -13     
124     //  f1: b0:  7    8  -16   b1:   12   8    -17
125     //
126     //  Input grad:
127     //  f0: b0:  1    2   3   b1:   0    0    -11
128     //  f0: b0:  4    5  -6   b1:   0.5 -0.5  -15  
129     //  f1: b0: -7    8  -9   b1:   1.5  5.2  -13     
130     //  f1: b0:  12  11  10   b1:   12   8    -17
131     //
132     //  Scale:
133     //  f0: 0.1
134     //  f1: 0.6  
135     //
136     //  Bias:
137     //  f0: 1
138     //  f1: 0.5
139
140     const auto& engine = get_test_engine();
141
142     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 2, 3, 2 } });
143     auto grad_input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 2, 3, 2 } });
144     auto scale_input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 1, 1 } });
145     auto bias = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 1, 1 } });
146
147     topology topology;
148     topology.add(input_layout("input", input.get_layout()));
149     topology.add(mutable_data("scale_input", scale_input));
150     topology.add(data("grad_input", grad_input));
151     topology.add(mutable_data("bias", bias));
152     topology.add(scale_grad_weights("scale_grad", "input", "grad_input", "scale_input", "bias", ""));
153
154     std::vector<float> input_vec = {
155         1.f, 2.f, -10.f,
156         3.f, 4.f, -14.f,
157         5.f, 6.f, -12.f,
158         7.f, 8.f, -16.f,
159         0.f, 0.f, -11.f,
160         0.5f, -0.5f, -15.f,
161         1.5f, 5.2f, -13.f,
162         12.f, 8.f, -17.f
163     };
164     set_values(input, input_vec);
165
166     std::vector<float> grad_vec = {
167         1.f, 2.f, 3.f,
168         4.f, 5.f, -6.f,
169         -7.f, 8.f, -9.f,
170         12.f, 11.f, 10.f,
171         0.f, 0.f, -11.f,
172         0.5f, -0.5f, -15.f,
173         1.5f, 5.2f, -13.f,
174         12.f, 8.f, -17.f
175     };
176     set_values(grad_input, grad_vec);
177
178     std::vector<float> scale_input_vec = {
179         0.1f, 0.6f
180     };
181     set_values(scale_input, scale_input_vec);
182
183     std::vector<float> bias_vec = {
184         1.f, 0.5f  
185     };
186     set_values(bias, bias_vec);
187
188     build_options options;
189     network network(engine, topology);
190
191     network.set_learning_rate(0.0001f);
192     network.set_input_data("input", input);
193
194     std::vector<float> expected_scale = {
195         0.05625f, 0.517171f
196     };
197
198     std::vector<float> expected_bias = {
199         1.0017f, 0.4978f
200     };
201
202     auto outputs = network.execute();
203
204     auto scale_ptr = scale_input.pointer<float>();
205     auto bias_ptr = bias.pointer<float>();
206
207     for (unsigned int i = 0; i < expected_scale.size(); ++i) {
208         EXPECT_NEAR(scale_ptr[i], expected_scale[i], 1e-04F);
209     }
210     for (unsigned int i = 0; i < expected_bias.size(); ++i) {
211         EXPECT_NEAR(bias_ptr[i], expected_bias[i], 1e-04F);
212     }
213 }
214
215 TEST(scale_grad_weights_gpu, basic_in2x3x2x2_bias_momentum) {
216     //  Scale  : 2x3x2x2
217     //  Input  : 2x3x2x2
218     //  Output : 2x3x2x2
219
220     //  Input:
221     //  f0: b0:  1    2  -10   b1:   0    0    -11
222     //  f0: b0:  3    4  -14   b1:   0.5 -0.5  -15  
223     //  f1: b0:  5    6  -12   b1:   1.5  5.2  -13     
224     //  f1: b0:  7    8  -16   b1:   12   8    -17
225     //
226     //  Input grad:
227     //  f0: b0:  1    2   3   b1:   0    0    -11
228     //  f0: b0:  4    5  -6   b1:   0.5 -0.5  -15  
229     //  f1: b0: -7    8  -9   b1:   1.5  5.2  -13     
230     //  f1: b0:  12  11  10   b1:   12   8    -17
231     //
232     //  Scale:
233     //  f0: 0.1
234     //  f1: 0.6  
235     //
236     //  Bias:
237     //  f0: 1
238     //  f1: 0.5
239
240     const auto& engine = get_test_engine();
241
242     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 2, 3, 2 } });
243     auto grad_input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 2, 3, 2 } });
244     auto scale_input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 1, 1 } });
245     auto bias = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 1, 1 } });
246     auto prev_scale = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 1, 1 } });
247     auto prev_bias = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 1, 1 } });
248
249     topology topology;
250     topology.add(input_layout("input", input.get_layout()));
251     topology.add(mutable_data("scale_input", scale_input));
252     topology.add(data("grad_input", grad_input));
253     topology.add(mutable_data("bias", bias));
254     topology.add(mutable_data("prev_scale", prev_scale));
255     topology.add(mutable_data("prev_bias", prev_bias));
256     topology.add(scale_grad_weights("scale_grad", "input", "grad_input", "scale_input", "bias", "prev_scale", "prev_bias"));
257
258     std::vector<float> input_vec = {
259         1.f, 2.f, -10.f,
260         3.f, 4.f, -14.f,
261         5.f, 6.f, -12.f,
262         7.f, 8.f, -16.f,
263         0.f, 0.f, -11.f,
264         0.5f, -0.5f, -15.f,
265         1.5f, 5.2f, -13.f,
266         12.f, 8.f, -17.f
267     };
268     set_values(input, input_vec);
269
270     std::vector<float> grad_vec = {
271         1.f, 2.f, 3.f,
272         4.f, 5.f, -6.f,
273         -7.f, 8.f, -9.f,
274         12.f, 11.f, 10.f,
275         0.f, 0.f, -11.f,
276         0.5f, -0.5f, -15.f,
277         1.5f, 5.2f, -13.f,
278         12.f, 8.f, -17.f
279     };
280     set_values(grad_input, grad_vec);
281
282     std::vector<float> scale_input_vec = {
283         0.1f, 0.6f
284     };
285     set_values(scale_input, scale_input_vec);
286
287     std::vector<float> bias_vec = {
288         1.f, 0.5f
289     };
290     set_values(bias, bias_vec);
291
292     build_options options;
293     network network(engine, topology);
294
295     network.set_learning_rate(0.0001f);
296     network.set_input_data("input", input);
297
298     std::vector<float> expected_scale = {
299         0.05625f, 0.517171f
300     };
301
302     std::vector<float> expected_bias = {
303         1.0017f, 0.4978f
304     };
305
306     auto outputs = network.execute();
307
308     auto scale_ptr = scale_input.pointer<float>();
309     auto bias_ptr = bias.pointer<float>();
310     auto mom_scale_ptr = prev_scale.pointer<float>();
311     auto mom_bias_ptr = prev_bias.pointer<float>();
312
313     for (unsigned int i = 0; i < expected_scale.size(); ++i) {
314         EXPECT_NEAR(scale_ptr[i], expected_scale[i], 1e-04F);
315     }
316     for (unsigned int i = 0; i < expected_bias.size(); ++i) {
317         EXPECT_NEAR(bias_ptr[i], expected_bias[i], 1e-04F);
318     }
319     for (unsigned int i = 0; i < mom_scale_ptr.size(); ++i) {
320         EXPECT_NEAR(mom_scale_ptr[i], scale_input_vec[i] - expected_scale[i], 1e-04F);
321     }
322     for (unsigned int i = 0; i < mom_bias_ptr.size(); ++i) {
323         EXPECT_NEAR(mom_bias_ptr[i], bias_vec[i] - expected_bias[i], 1e-04F);
324     }
325 }