Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / lookup_table_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 #include <gtest/gtest.h>
18 #include "api/CPP/memory.hpp"
19 #include <api/CPP/input_layout.hpp>
20 #include "api/CPP/lookup_table.hpp"
21 #include "api/CPP/arg_max_min.hpp"
22 #include <api/CPP/topology.hpp>
23 #include <api/CPP/network.hpp>
24 #include <api/CPP/engine.hpp>
25 #include "test_utils/test_utils.h"
26
27 using namespace cldnn;
28 using namespace std;
29 using namespace tests;
30
31
32 TEST(lookup_table_base, base) {
33     //  Input  : 2x3x2x2
34     static const int32_t x_size = 2, y_size = 2, feature_num = 3, batch_num = 2;
35     const auto& engine = get_test_engine();
36
37     auto input = memory::allocate(engine, { data_types::f32, format::bfyx, { batch_num, feature_num, x_size , y_size } });
38     auto input2 = memory::allocate(engine, { data_types::f32, format::bfyx, {2, 1, 1, 1} });
39     topology topology;
40     topology.add(input_layout("input", input.get_layout()));
41     topology.add(input_layout("input2", input2.get_layout()));
42     topology.add(lookup_table("table", "input", "input2"));
43     vector<float> input_vec = {
44         //y0x0 y0x1 y1x0 y1x1
45         /*b0f0*/0.1f, -0.1f, 0.9f,  1.5f,
46         /*b0f1*/0.2f, 0.2f,  -10.f, 5.2f,
47         /*b0f2*/0.2f, 0.2f,  -10.f, 5.2f,
48
49         /*b1f0*/3.f,  0.5f,  7.f,   10.f,
50         /*b1f1*/4.f,  0.5f,  8.f,   8.2f,
51         /*b1f2*/0.2f, 0.2f,  -10.f, 5.2f
52     };
53     vector<float> input2_vec = { 11, 3 };
54     set_values(input, input_vec);
55     set_values(input2, input2_vec);
56
57     network network(engine, topology);
58
59     network.set_input_data("input", input);
60     network.set_input_data("input2", input2);
61     auto outputs = network.execute();
62
63     EXPECT_EQ(outputs.size(), size_t(1));
64
65     auto output = outputs.at("table").get_memory();
66     auto output_ptr = output.pointer<float>();;
67     float out_buffer[batch_num];
68     for (uint32_t i = 0; i < batch_num; i++)
69     {
70         out_buffer[i] = get_value<float>(output_ptr, i);
71     }
72     int size = x_size * y_size * feature_num;
73     float value;
74     for (int i = 0; i < batch_num; i++) {
75         value = out_buffer[i];
76         for (int j = 0; j < size; j++)
77         {
78             EXPECT_LE(input_vec[i*size + j], value);
79         }
80     }
81 }
82
83 TEST(lookup_table_num, base) {
84     //  Input  : 2x3x2x2
85     static const int32_t x_size = 2, y_size = 2, feature_num = 3, batch_num = 2, number_of_values = 3;
86     const auto& engine = get_test_engine();
87
88     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ batch_num, feature_num, x_size , y_size } });
89     auto input2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 1, 3, 1 } });
90     topology topology;
91     topology.add(input_layout("input", input.get_layout()));
92     topology.add(input_layout("input2", input2.get_layout()));
93     topology.add(lookup_table("table", "input", "input2"));
94     vector<float> input_vec = {
95         //y0x0 y0x1 y1x0 y1x1
96         /*b0f0*/0.1f, -0.1f, 0.9f,  1.5f,
97         /*b0f1*/0.2f, 0.2f,  -10.f, 5.2f,
98         /*b0f2*/0.2f, 0.2f,  -10.f, 5.2f,
99
100         /*b1f0*/3.f,  0.5f,  7.f,   10.f,
101         /*b1f1*/4.f,  0.5f,  8.f,   8.2f,
102         /*b1f2*/0.2f, 0.2f,  -10.f, 5.2f
103     };
104     vector<float> input2_vec = { 11, 7, 3, 3, 7, 6};
105     set_values(input, input_vec);
106     set_values(input2, input2_vec);
107
108     network network(engine, topology);
109
110     network.set_input_data("input", input);
111     network.set_input_data("input2", input2);
112     auto outputs = network.execute();
113
114     EXPECT_EQ(outputs.size(), size_t(1));
115
116     auto output = outputs.at("table").get_memory();
117     auto output_ptr = output.pointer<float>();;
118     float out_buffer[batch_num*number_of_values];
119     for (uint32_t i = 0; i < batch_num * number_of_values; i++)
120     {
121         out_buffer[i] = get_value<float>(output_ptr, i);
122     }
123     int size = x_size * y_size * feature_num;
124     float value;
125     for (int i = 0; i < batch_num; i++) {
126         int count = 0;
127         int amount = 0;
128         int same_values = 1;
129         int j;
130         for (j = 0; j < number_of_values; j++) {
131             if (number_of_values - 1 == j) {
132                 if (input_vec[i*size + (int)input2_vec[i*number_of_values + j]] != input_vec[i*size + (int)input2_vec[i*number_of_values + j - 1]]) {
133                     amount += j;
134                 }
135                 else
136                     amount += same_values * (j - same_values + 1);
137             }
138             else if (input_vec[i*size + (int)input2_vec[i*number_of_values + j]] != input_vec[i*size + (int)input2_vec[i*number_of_values + j + 1]]) {
139                 if (same_values != j + 1) {
140                     amount += same_values * (j - same_values + 1);
141                     same_values = 1;
142                 }
143             }
144             else
145                 same_values++;
146         }
147         for (int j = 0; j < number_of_values; j++)
148         {
149             value = out_buffer[i*number_of_values + j];
150             for (int k = 0; k < size; k++)
151             {
152                 if (input_vec[i*size + k] > value)
153                     count++;
154             }
155         }
156         EXPECT_EQ(count, amount);
157     }
158 }
159
160 TEST(lookup_table_with_arg_max, base) {
161     //  Input  : 2x3x2x2
162     static const int32_t x_size = 2, y_size = 2, feature_num = 3, batch_num = 2;
163     const auto& engine = get_test_engine();
164
165     auto input = memory::allocate(engine, { data_types::f32, format::yxfb,{ batch_num, feature_num, x_size , y_size } });
166     topology topology;
167     topology.add(input_layout("input", input.get_layout()));
168     topology.add(arg_max_min("arg_max", "input", arg_max_min::max));
169     topology.add(lookup_table("table", "input", "arg_max"));
170     vector<float> input_vec = {
171         //y0x0 y0x1 y1x0 y1x1
172         /*b0f0*/0.1f, -0.1f, 0.9f,  1.5f,
173         /*b0f1*/0.2f, 0.2f,  -10.f, 5.2f,
174         /*b0f2*/0.2f, 0.2f,  -10.f, 5.2f,
175
176         /*b1f0*/3.f,  0.5f,  7.f,   10.f,
177         /*b1f1*/4.f,  0.5f,  8.f,   8.2f,
178         /*b1f2*/0.2f, 0.2f,  -10.f, 5.2f
179     };
180     set_values(input, input_vec);
181
182     network network(engine, topology);
183
184     network.set_input_data("input", input);
185     auto outputs = network.execute();
186
187     EXPECT_EQ(outputs.size(), size_t(1));
188
189     auto output = outputs.at("table").get_memory();
190     auto output_ptr = output.pointer<float>();;
191     float out_buffer[batch_num];
192     for (uint32_t i = 0; i < batch_num; i++)
193     {
194         out_buffer[i] = get_value<float>(output_ptr, i);
195     }
196     int size = x_size * y_size * feature_num;
197     float value;
198     for (int i = 0; i < batch_num; i++) {
199         value = out_buffer[i];
200         for (int j = 0; j < size; j++)
201         {
202             EXPECT_LE(input_vec[i*size + j], value);
203         }
204     }
205 }
206
207 TEST(lookup_table_axis, base) {
208     //  Input  : 2x3x2x2
209     static const int32_t x_size = 2, y_size = 2, feature_num = 3, batch_num = 2, number_of_values = 2;
210     const auto& engine = get_test_engine();
211
212     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ batch_num, feature_num, x_size , y_size } });
213     auto input2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 3, 2, 2 } });
214     topology topology;
215     topology.add(input_layout("input", input.get_layout()));
216     topology.add(input_layout("input2", input2.get_layout()));
217     topology.add(lookup_table("table", "input", "input2", lookup_table::batch));
218     vector<float> input_vec = {
219         //y0x0 y0x1 y1x0 y1x1
220         /*b0f0*/0.1f, -0.1f, 0.9f,  1.5f,
221         /*b0f1*/0.2f, 0.2f,  -10.f, 5.2f,
222         /*b0f2*/0.2f, 0.2f,  -10.f, 5.2f,
223
224         /*b1f0*/3.f,  0.5f,  7.f,   10.f,
225         /*b1f1*/4.f,  0.5f,  8.f,   8.2f,
226         /*b1f2*/0.2f, 0.2f,  -10.f, 5.2f
227     };
228     vector<float> input2_vec = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
229     set_values(input, input_vec);
230     set_values(input2, input2_vec);
231
232     network network(engine, topology);
233
234     network.set_input_data("input", input);
235     network.set_input_data("input2", input2);
236     auto outputs = network.execute();
237
238     EXPECT_EQ(outputs.size(), size_t(1));
239
240     auto output = outputs.at("table").get_memory();
241     auto output_ptr = output.pointer<float>();;
242     const int out_size = y_size * feature_num * x_size * number_of_values;
243     float out_buffer[out_size];
244     for (uint32_t i = 0; i < out_size; i++)
245     {
246         out_buffer[i] = get_value<float>(output_ptr, i);
247     }
248     for (int i = 0; i < out_size; i++)
249     {
250         EXPECT_EQ(out_buffer[i], (i%2==0 ? input_vec[i/2] : input_vec[(i/2+12)]));
251     }
252 }