Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / fully_connected_grad_weights_gpu_test.cpp
1 /*
2 // Copyright (c) 2016 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
19 #include <gtest/gtest.h>
20 #include "api/CPP/memory.hpp"
21 #include <api/CPP/input_layout.hpp>
22 #include "api/CPP/fully_connected_grad_weights.hpp"
23 #include "api/CPP/fully_connected.hpp"
24 #include "api/CPP/fully_connected_grad_input.hpp"
25 #include "api/CPP/reorder.hpp"
26 #include <api/CPP/mutable_data.hpp>
27 #include <api/CPP/data.hpp>
28 #include <api/CPP/topology.hpp>
29 #include <api/CPP/network.hpp>
30 #include <api/CPP/engine.hpp>
31 #include "test_utils/test_utils.h"
32
33 using namespace cldnn;
34 using namespace tests;
35
36 TEST(fully_connected_grad_weights_gpu, basic_bfyx) {
37     //  Filter : 2x2
38     //  Input  : 1x1x1x3
39     //  Stride : 2x2
40     //
41     //  Input:
42     //  -0.5     2    0.5
43     //
44     //  Input_grad:
45     //   1.5   0.75  -2.25  3
46
47     const auto& engine = get_test_engine();
48     float lr = 0.00001f;
49     auto input_grad = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 4, 1 } });
50     auto input = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 3, 1 } });
51     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx, { 4, 1, 3, 1 } });
52     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 4, 1 } });
53
54     set_values(input, { -0.5f, 2.0f, 0.5f });
55     set_values(input_grad, { 1.5f, 0.75f, -2.25f, 3.0f });
56
57     topology topology(
58         input_layout("input_grad", input_grad.get_layout()),
59         data("input", input),
60         mutable_data("weights", weights),
61         mutable_data("biases", biases),
62         fully_connected_grad_weights("conv_grad_weights", "input_grad", "input", { "weights" }, { "biases" })
63     );
64
65     network network(engine, topology);
66     network.set_input_data("input_grad", input_grad);
67
68     auto outputs = network.execute();
69     EXPECT_EQ(outputs.size(), size_t(1));
70     EXPECT_EQ(outputs.begin()->first, "conv_grad_weights");
71
72     auto output_prim = outputs.begin()->second.get_memory();
73
74     auto output_ptr = output_prim.pointer<float>();
75     auto weights_ptr = weights.pointer<float>();
76     auto biases_ptr = biases.pointer<float>();
77
78     std::vector<float> expected_weights_vec = {
79         0.75f, -3.f, -0.75,
80         0.375f, -1.5f, -0.375f,
81         -1.125f, 4.5f, 1.125f,
82         1.5f, -6.f, -1.5f
83     };
84
85     std::vector<float> expected_bias_vec = {
86         -1.5f, -0.75f, 2.25f, -3.0f
87     };
88
89     for (unsigned int i = 0; i < expected_weights_vec.size(); i++)
90     {
91         float x = float_round(expected_weights_vec[i]*lr), y = float_round(weights_ptr[i]);
92         EXPECT_FLOAT_EQ(x, y) << "on weights verification" << random_seed << std::endl;
93     }
94
95     for (unsigned int i = 0; i < expected_bias_vec.size(); i++)
96     {
97         float x = float_round(expected_bias_vec[i]*lr), y = float_round(biases_ptr[i]);
98         EXPECT_FLOAT_EQ(x, y) << "on biases verification" << random_seed << std::endl;
99     }
100 }
101
102 TEST(fully_connected_grad_weights_gpu, basic_bfyx_b8) {
103     //  Filter : 2x2
104     //  Input  : 2x2x1x2
105     //  Output : 2x2x1x2
106     //  Stride : 2x2
107     //
108     //  Input:
109     //  -0.5     2    0.5
110     //  -0.5     2    0.5
111     //  -0.5     2    0.5
112     //  -0.5     2    0.5
113     //  -0.5     2    0.5
114     //  -0.5     2    0.5
115     //  -0.5     2    0.5
116     //  1     1    1
117     //
118     //  Input_grad:
119     //   1.5   0.75  -2.25  3
120     //   1.5   0.75  -2.25  3
121     //   1.5   0.75  -2.25  3
122     //   1.5   0.75  -2.25  3
123     //   1.5   0.75  -2.25  3
124     //   1.5   0.75  -2.25  3
125     //   1.5   0.75  -2.25  3
126     //   1   1  1  1
127
128     const auto& engine = get_test_engine();
129     float lr = 0.00001f;
130     auto input_grad = memory::allocate(engine, { data_types::f32, format::bfyx,{ 8, 1, 4, 1 } });
131     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 8, 1, 3, 1 } });
132     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 4, 1, 3, 1 } });
133     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 4, 1 } });
134
135     set_values(input, { -0.5f, 2.0f, 0.5f,
136                         -0.5f, 2.0f, 0.5f, 
137                         -0.5f, 2.0f, 0.5f, 
138                         -0.5f, 2.0f, 0.5f, 
139                         -0.5f, 2.0f, 0.5f, 
140                         -0.5f, 2.0f, 0.5f, 
141                         -0.5f, 2.0f, 0.5f, 
142                         1.f, 1.f, 1.f });
143     set_values(input_grad, { 1.5f, 0.75f, -2.25f, 3.0f,
144                             1.5f, 0.75f, -2.25f, 3.0f, 
145                             1.5f, 0.75f, -2.25f, 3.0f, 
146                             1.5f, 0.75f, -2.25f, 3.0f, 
147                             1.5f, 0.75f, -2.25f, 3.0f, 
148                             1.5f, 0.75f, -2.25f, 3.0f, 
149                             1.5f, 0.75f, -2.25f, 3.0f, 
150                             1.f, 1.f, 1.f, 1.f });
151
152     topology topology(
153         input_layout("input_grad", input_grad.get_layout()),
154         data("input", input),
155         mutable_data("weights", weights),
156         mutable_data("biases", biases),
157         fully_connected_grad_weights("conv_grad_weights", "input_grad", "input", { "weights" }, { "biases" })
158     );
159
160     network network(engine, topology);
161     network.set_input_data("input_grad", input_grad);
162
163     auto outputs = network.execute();
164     EXPECT_EQ(outputs.size(), size_t(1));
165     EXPECT_EQ(outputs.begin()->first, "conv_grad_weights");
166
167     auto output_prim = outputs.begin()->second.get_memory();
168
169     auto output_ptr = output_prim.pointer<float>();
170     auto weights_ptr = weights.pointer<float>();
171     auto biases_ptr = biases.pointer<float>();
172
173     std::vector<float> expected_weights_vec = {
174         4.25e-05f, -0.00022f, -6.25e-05f,
175         1.625e-05f, -0.000115f, -3.625e-05f,
176         -8.875e-05f, 0.000305f, 6.875e-05f,
177         9.5e-05f, -0.00043f, -0.000115f
178     };
179
180     std::vector<float> expected_bias_vec = {
181         -0.000115f, -6.25e-05f, 0.0001475f, -0.00022f
182     };
183
184     for (unsigned int i = 0; i < expected_weights_vec.size(); i++)
185     {
186         float x = float_round(expected_weights_vec[i]), y = float_round(weights_ptr[i]);
187         EXPECT_FLOAT_EQ(x, y) << "on weights verification" << random_seed << std::endl;
188     }
189
190     for (unsigned int i = 0; i < expected_bias_vec.size(); i++)
191     {
192         float x = float_round(expected_bias_vec[i]), y = float_round(biases_ptr[i]);
193         EXPECT_FLOAT_EQ(x, y) << "on biases verification" << random_seed << std::endl;
194     }
195 }
196
197 TEST(fully_connected_grad_weights_gpu, basic_bfyx_no_bias) {
198     //  Filter : 2x2
199     //  Input  : 2x2x1x2
200     //  Output : 2x2x1x2
201     //  Stride : 2x2
202     //
203     //  Input:
204     //  -0.5     2    0.5
205     //
206     //  Input_grad:
207     //   1.5   0.75  -2.25  3
208
209     const auto& engine = get_test_engine();
210     float lr = 0.00001f;
211     auto input_grad = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 4, 1 } });
212     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 3, 1 } });
213     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 4, 1, 3, 1 } });
214
215     set_values(input, { -0.5f, 2.0f, 0.5f });
216     set_values(input_grad, { 1.5f, 0.75f, -2.25f, 3.0f });
217
218     topology topology(
219         input_layout("input_grad", input_grad.get_layout()),
220         data("input", input),
221         mutable_data("weights", weights),
222         fully_connected_grad_weights("conv_grad_weights", "input_grad", "input", { "weights" })
223     );
224
225     network network(engine, topology);
226     network.set_input_data("input_grad", input_grad);
227
228     auto outputs = network.execute();
229     EXPECT_EQ(outputs.size(), size_t(1));
230     EXPECT_EQ(outputs.begin()->first, "conv_grad_weights");
231
232     auto output_prim = outputs.begin()->second.get_memory();
233
234     auto output_ptr = output_prim.pointer<float>();
235     auto weights_ptr = weights.pointer<float>();
236
237     std::vector<float> expected_weights_vec = {
238         0.75f, -3.f, -0.75,
239         0.375f, -1.5f, -0.375f,
240         -1.125f, 4.5f, 1.125f,
241         1.5f, -6.f, -1.5f
242     };
243
244     for (unsigned int i = 0; i < expected_weights_vec.size(); i++)
245     {
246         float x = float_round(expected_weights_vec[i]*lr), y = float_round(weights_ptr[i]);
247         EXPECT_FLOAT_EQ(x, y) << "on weights verification" << random_seed << std::endl;
248     }
249 }