Publishing 2019 R3 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / one_hot_gpu_test.cpp
1 // Copyright (c) 2019 Intel Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 ///////////////////////////////////////////////////////////////////////////////////////////////////
16 #include <gtest/gtest.h>
17
18 #include <api/engine.hpp>
19 #include <api/input_layout.hpp>
20 #include <api/memory.hpp>
21 #include <api/one_hot.hpp>
22 #include <api/topology.hpp>
23 #include <api/network.hpp>
24
25 #include "test_utils/test_utils.h"
26 #include "test_utils/uniform_quantized_real_distribution.hpp"
27
28 #include <cstddef>
29
30 using namespace cldnn;
31 using namespace ::tests;
32
33 template <typename T>
34 VVVVF<T> one_hot_cpu(VVVVF<T> &input, uint16_t axis,
35     int32_t one_hot_limit, int input_padding_y = 0,
36     int input_padding_x = 0, int output_padding_y = 0,
37     int output_padding_x = 0) {
38
39     size_t padding_y = input_padding_y + output_padding_y;
40     size_t padding_x = input_padding_x + output_padding_x;
41     size_t out_sizes[4];
42     out_sizes[0] = input.size();
43     out_sizes[1] = input[0].size();
44     out_sizes[2] = input[0][0].size() + 2 * padding_y;
45     out_sizes[3] = input[0][0][0].size() + 2 * padding_x;
46     for (uint16_t i = 3; i > axis; --i)
47         out_sizes[i] = out_sizes[i - 1];
48     out_sizes[axis] = one_hot_limit;
49     VVVVF<T> output(out_sizes[0], VVVF<T>(out_sizes[1], VVF<T>(out_sizes[2], VF<T>(out_sizes[3]))));
50
51     switch (axis) {
52     case 0:
53         for (size_t b = 0; b < out_sizes[0]; ++b)
54             for (size_t f = 0; f < out_sizes[1]; ++f)
55                 for (size_t y = 0; y < out_sizes[2]; ++y)
56                     for (size_t x = 0; x < out_sizes[3]; ++x)
57                         output[b][f][y][x] = input[f][y][x][0] == (T)b ? 1 : 0;
58         break;
59     case 1:
60         for (size_t b = 0; b < out_sizes[0]; ++b)
61             for (size_t f = 0; f < out_sizes[1]; ++f)
62                 for (size_t y = 0; y < out_sizes[2]; ++y)
63                     for (size_t x = 0; x < out_sizes[3]; ++x)
64                         output[b][f][y][x] = input[b][y][x][0] == (T)f ? 1 : 0;
65         break;
66     case 2:
67         for (size_t b = 0; b < out_sizes[0]; ++b)
68             for (size_t f = 0; f < out_sizes[1]; ++f)
69                 for (size_t y = 0; y < out_sizes[2]; ++y)
70                     for (size_t x = 0; x < out_sizes[3]; ++x)
71                         output[b][f][y][x] = input[b][f][x][0] == (T)y ? 1 : 0;
72         break;
73     case 3:
74         for (size_t b = 0; b < out_sizes[0]; ++b)
75             for (size_t f = 0; f < out_sizes[1]; ++f)
76                 for (size_t y = 0; y < out_sizes[2]; ++y)
77                     for (size_t x = 0; x < out_sizes[3]; ++x)
78                         output[b][f][y][x] = input[b][f][y][0] == (T)x ? 1 : 0;
79         break;
80     default: break;
81     }
82     return output;
83 }
84
85 template <typename T>
86 void generic_one_hot_test_int(cldnn::format test_input_fmt, int input_b, int input_f, int input_y, int input_x, tensor shape,
87     uint16_t one_hot_axis, int input_padding_y = 0, int input_padding_x = 0, int output_padding_y = 0, int output_padding_x = 0) {
88     std::vector<tensor::value_type> output_dims = { shape.batch[0], shape.feature[0],
89         shape.spatial[1], shape.spatial[0] };
90     int32_t one_hot_limit = output_dims[one_hot_axis];
91
92     int min_random = 0, max_random = one_hot_limit + 2;
93     VVVVF<T> input_rnd = generate_random_4d<T>(input_b, input_f, input_y, input_x, min_random, max_random);
94     VF<T> input_rnd_vec = flatten_4d<T>(test_input_fmt, input_rnd);
95
96     const auto& engine = get_test_engine();
97     tensor input_tensor(input_b, input_f, input_x, input_y);
98     auto input = memory::allocate(engine, { type_to_data_type<T>::value, test_input_fmt, input_tensor });
99     set_values(input, input_rnd_vec);
100
101     topology topology;
102     topology.add(input_layout("input", input.get_layout()));
103     topology.add(one_hot("output", "input", shape, one_hot_axis));
104
105     network network(engine, topology);
106     network.set_input_data("input", input);
107     auto outputs = network.execute();
108     EXPECT_EQ(outputs.size(), size_t(1));
109     EXPECT_EQ(outputs.begin()->first, "output");
110
111     auto output_memory = outputs.at("output").get_memory();
112     auto output_layout = output_memory.get_layout();
113     auto output_ptr = output_memory.pointer<T>();
114
115     VVVVF<T> output_cpu = one_hot_cpu<T>(input_rnd, one_hot_axis, one_hot_limit, input_padding_y, input_padding_x, output_padding_y, output_padding_x);
116     EXPECT_EQ(output_layout.format.value, test_input_fmt.value);
117     tensor output_tensor = output_layout.get_buffer_size();
118     int y_size = output_tensor.spatial[1];
119     int x_size = output_tensor.spatial[0];
120     int f_size = output_tensor.feature[0];
121     int b_size = output_tensor.batch[0];
122     EXPECT_EQ(y_size, (int)output_cpu[0][0].size());
123     EXPECT_EQ(x_size, (int)output_cpu[0][0][0].size());
124     EXPECT_EQ(f_size, (int)output_cpu[0].size());
125     EXPECT_EQ(b_size, (int)output_cpu.size());
126
127     bool test_is_correct = true;
128     VF<T> output_cpu_vec = flatten_4d<T>(test_input_fmt, output_cpu);
129
130     for (size_t i = 0; i < output_cpu_vec.size(); ++i) {
131         if (output_cpu_vec[i] != output_ptr[i]) {
132             test_is_correct = false;
133             break;
134         }
135     }
136     EXPECT_EQ(test_is_correct, true) << std::endl
137         << "failing test parameters:" << std::endl
138         << "input_b = " << input_b << std::endl
139         << "input_f = " << input_f << std::endl
140         << "input_y = " << input_y << std::endl
141         << "input_x = " << input_x << std::endl
142         << "one_hot_limit = " << one_hot_limit << std::endl
143         << "one_hot_axis = " << one_hot_axis << std::endl
144         << "input_padding_y = " << input_padding_y << std::endl
145         << "input_padding_x = " << input_padding_x << std::endl
146         << "output_padding_y = " << output_padding_y << std::endl
147         << "output_padding_x = " << output_padding_x << std::endl;
148 }
149
150 TEST(one_hot_gpu_i32, generic) {
151     generic_one_hot_test_int<int32_t>(format::bfyx, 2, 2, 1, 1, tensor(5, 2, 1, 2), 0);
152     generic_one_hot_test_int<int32_t>(format::bfyx, 1, 2, 3, 1, tensor(1, 5, 3, 2), 1);
153     generic_one_hot_test_int<int32_t>(format::bfyx, 2, 2, 1, 1, tensor(2, 2, 1, 4), 2);
154     generic_one_hot_test_int<int32_t>(format::bfyx, 2, 2, 1, 1, tensor(2, 2, 4, 1), 3);
155 }
156
157 TEST(one_hot_gpu_i32, bfzyx_ax4) {
158     // input: 1x1x2x1
159     // axis: 4
160     // output: 1x1x2x1x5
161     int in_b = 1;
162     int in_f = 1;
163     int in_y = 2;
164     int in_x = 1;
165     tensor shape(in_b, in_f, 5, in_x, in_y);
166     uint16_t one_hot_axis = 4;
167     std::vector<tensor::value_type> output_dims = { shape.batch[0], shape.feature[0],
168                                                     shape.spatial[2], shape.spatial[1], shape.spatial[0] };
169     int32_t one_hot_limit = output_dims[one_hot_axis];
170
171     VF<int32_t> input_rnd_vec = {0, 1};
172
173     const auto& engine = get_test_engine();
174     tensor input_tensor(in_b, in_f, in_x, in_y);
175     auto input = memory::allocate(engine, { data_types::i32, format::bfyx, input_tensor });
176     topology topology;
177     topology.add(input_layout("input", input.get_layout()));
178     topology.add(one_hot("output","input", shape, one_hot_axis));
179
180     set_values(input, input_rnd_vec);
181
182     network network(engine, topology);
183     network.set_input_data("input", input);
184     auto outputs = network.execute();
185     EXPECT_EQ(outputs.size(), size_t(1));
186     EXPECT_EQ(outputs.begin()->first, "output");
187
188     auto output_memory = outputs.at("output").get_memory();
189     auto output_layout = output_memory.get_layout();
190     auto output_ptr = output_memory.pointer<int32_t>();
191
192     tensor output_tensor = output_layout.get_buffer_size();
193     int z_size = output_tensor.spatial[2];
194     int y_size = output_tensor.spatial[1];
195     int x_size = output_tensor.spatial[0];
196     int f_size = output_tensor.feature[0];
197     int b_size = output_tensor.batch[0];
198     EXPECT_EQ(z_size, 2);
199     EXPECT_EQ(y_size, 1);
200     EXPECT_EQ(x_size, 5);
201     EXPECT_EQ(f_size, 1);
202     EXPECT_EQ(b_size, 1);
203
204     bool test_is_correct = true;
205
206     std::vector<int32_t> output_cpu_vec = {1, 0, 0, 0, 0,
207                                            0, 1, 0, 0, 0};
208
209     for (size_t i = 0; i < output_cpu_vec.size(); ++i) {
210         if (output_cpu_vec[i] != output_ptr[i]) {
211             test_is_correct = false;
212         }
213     }
214     EXPECT_EQ(test_is_correct, true);
215 }
216
217 TEST(one_hot_gpu_i32, bfzyx_ax0) {
218     int in_b = 1;
219     int in_f = 1;
220     int in_y = 1;
221     int in_x = 2;
222     tensor shape(3, in_b, in_x, in_y, in_f);
223     uint16_t one_hot_axis = 0;
224     std::vector<tensor::value_type> output_dims = { shape.batch[0], shape.feature[0],
225                                                     shape.spatial[2], shape.spatial[1], shape.spatial[0] };
226     int32_t one_hot_limit = output_dims[one_hot_axis];
227
228     VF<int32_t> input_rnd_vec = {0, 1};
229
230     const auto& engine = get_test_engine();
231     tensor input_tensor(in_b, in_f, in_x, in_y);
232     auto input = memory::allocate(engine, { data_types::i32, format::bfyx, input_tensor });
233     topology topology;
234     topology.add(input_layout("input", input.get_layout()));
235     topology.add(one_hot("output","input", shape, one_hot_axis));
236
237     set_values(input, input_rnd_vec);
238
239     network network(engine, topology);
240     network.set_input_data("input", input);
241     auto outputs = network.execute();
242     EXPECT_EQ(outputs.size(), size_t(1));
243     EXPECT_EQ(outputs.begin()->first, "output");
244
245     auto output_memory = outputs.at("output").get_memory();
246     auto output_layout = output_memory.get_layout();
247     auto output_ptr = output_memory.pointer<int32_t>();
248
249     tensor output_tensor = output_layout.get_buffer_size();
250     int z_size = output_tensor.spatial[2];
251     int y_size = output_tensor.spatial[1];
252     int x_size = output_tensor.spatial[0];
253     int f_size = output_tensor.feature[0];
254     int b_size = output_tensor.batch[0];
255     EXPECT_EQ(z_size, 1);
256     EXPECT_EQ(y_size, 1);
257     EXPECT_EQ(x_size, 2);
258     EXPECT_EQ(f_size, 1);
259     EXPECT_EQ(b_size, 3);
260
261     bool test_is_correct = true;
262
263     std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
264
265     for (size_t i = 0; i < output_cpu_vec.size(); ++i) {
266         if (output_cpu_vec[i] != output_ptr[i]) {
267             test_is_correct = false;
268         }
269     }
270     EXPECT_EQ(test_is_correct, true);
271 }
272
273 TEST(one_hot_gpu_i32, bfzyx_ax1) {
274     int in_b = 1;
275     int in_f = 1;
276     int in_y = 1;
277     int in_x = 2;
278     tensor shape(in_b, 3, in_x, in_y, in_f);
279     uint16_t one_hot_axis = 1;
280     std::vector<tensor::value_type> output_dims = { shape.batch[0], shape.feature[0],
281                                                     shape.spatial[2], shape.spatial[1], shape.spatial[0] };
282     int32_t one_hot_limit = output_dims[one_hot_axis];
283
284     VF<int32_t> input_rnd_vec = {0, 1};
285
286     const auto& engine = get_test_engine();
287     tensor input_tensor(in_b, in_f, in_x, in_y);
288     auto input = memory::allocate(engine, { data_types::i32, format::bfyx, input_tensor });
289     topology topology;
290     topology.add(input_layout("input", input.get_layout()));
291     topology.add(one_hot("output","input", shape, one_hot_axis));
292
293     set_values(input, input_rnd_vec);
294
295     network network(engine, topology);
296     network.set_input_data("input", input);
297     auto outputs = network.execute();
298     EXPECT_EQ(outputs.size(), size_t(1));
299     EXPECT_EQ(outputs.begin()->first, "output");
300
301     auto output_memory = outputs.at("output").get_memory();
302     auto output_layout = output_memory.get_layout();
303     auto output_ptr = output_memory.pointer<int32_t>();
304
305     tensor output_tensor = output_layout.get_buffer_size();
306     int z_size = output_tensor.spatial[2];
307     int y_size = output_tensor.spatial[1];
308     int x_size = output_tensor.spatial[0];
309     int f_size = output_tensor.feature[0];
310     int b_size = output_tensor.batch[0];
311     EXPECT_EQ(z_size, 1);
312     EXPECT_EQ(y_size, 1);
313     EXPECT_EQ(x_size, 2);
314     EXPECT_EQ(f_size, 3);
315     EXPECT_EQ(b_size, 1);
316
317     bool test_is_correct = true;
318
319     std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
320
321     for (size_t i = 0; i < output_cpu_vec.size(); ++i) {
322         if (output_cpu_vec[i] != output_ptr[i]) {
323             test_is_correct = false;
324         }
325     }
326     EXPECT_EQ(test_is_correct, true);
327 }
328
329 TEST(one_hot_gpu_i32, bfzyx_ax2) {
330     int in_b = 1;
331     int in_f = 1;
332     int in_y = 1;
333     int in_x = 2;
334     tensor shape(in_b, in_f, in_x, in_y, 3);
335     uint16_t one_hot_axis = 2;
336     std::vector<tensor::value_type> output_dims = { shape.batch[0], shape.feature[0],
337                                                     shape.spatial[2], shape.spatial[1], shape.spatial[0] };
338     int32_t one_hot_limit = output_dims[one_hot_axis];
339
340     VF<int32_t> input_rnd_vec = {0, 1};
341
342     const auto& engine = get_test_engine();
343     tensor input_tensor(in_b, in_f, in_x, in_y);
344     auto input = memory::allocate(engine, { data_types::i32, format::bfyx, input_tensor });
345     topology topology;
346     topology.add(input_layout("input", input.get_layout()));
347     topology.add(one_hot("output","input", shape, one_hot_axis));
348
349     set_values(input, input_rnd_vec);
350
351     network network(engine, topology);
352     network.set_input_data("input", input);
353     auto outputs = network.execute();
354     EXPECT_EQ(outputs.size(), size_t(1));
355     EXPECT_EQ(outputs.begin()->first, "output");
356
357     auto output_memory = outputs.at("output").get_memory();
358     auto output_layout = output_memory.get_layout();
359     auto output_ptr = output_memory.pointer<int32_t>();
360
361     tensor output_tensor = output_layout.get_buffer_size();
362     int z_size = output_tensor.spatial[2];
363     int y_size = output_tensor.spatial[1];
364     int x_size = output_tensor.spatial[0];
365     int f_size = output_tensor.feature[0];
366     int b_size = output_tensor.batch[0];
367     EXPECT_EQ(z_size, 3);
368     EXPECT_EQ(y_size, 1);
369     EXPECT_EQ(x_size, 2);
370     EXPECT_EQ(f_size, 1);
371     EXPECT_EQ(b_size, 1);
372
373     bool test_is_correct = true;
374
375     std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
376
377     for (size_t i = 0; i < output_cpu_vec.size(); ++i) {
378         if (output_cpu_vec[i] != output_ptr[i]) {
379             test_is_correct = false;
380         }
381     }
382     EXPECT_EQ(test_is_correct, true);
383 }
384
385 TEST(one_hot_gpu_i32, bfzyx_ax3) {
386     int in_b = 1;
387     int in_f = 1;
388     int in_y = 1;
389     int in_x = 2;
390     tensor shape(in_b, in_f, in_x, 3, in_y);
391     uint16_t one_hot_axis = 3;
392     std::vector<tensor::value_type> output_dims = { shape.batch[0], shape.feature[0],
393                                                     shape.spatial[2], shape.spatial[1], shape.spatial[0] };
394     int32_t one_hot_limit = output_dims[one_hot_axis];
395
396     VF<int32_t> input_rnd_vec = {0, 1};
397
398     const auto& engine = get_test_engine();
399     tensor input_tensor(in_b, in_f, in_x, in_y);
400     auto input = memory::allocate(engine, { data_types::i32, format::bfyx, input_tensor });
401     topology topology;
402     topology.add(input_layout("input", input.get_layout()));
403     topology.add(one_hot("output","input", shape, one_hot_axis));
404
405     set_values(input, input_rnd_vec);
406
407     network network(engine, topology);
408     network.set_input_data("input", input);
409     auto outputs = network.execute();
410     EXPECT_EQ(outputs.size(), size_t(1));
411     EXPECT_EQ(outputs.begin()->first, "output");
412
413     auto output_memory = outputs.at("output").get_memory();
414     auto output_layout = output_memory.get_layout();
415     auto output_ptr = output_memory.pointer<int32_t>();
416
417     tensor output_tensor = output_layout.get_buffer_size();
418     int z_size = output_tensor.spatial[2];
419     int y_size = output_tensor.spatial[1];
420     int x_size = output_tensor.spatial[0];
421     int f_size = output_tensor.feature[0];
422     int b_size = output_tensor.batch[0];
423     EXPECT_EQ(z_size, 1);
424     EXPECT_EQ(y_size, 3);
425     EXPECT_EQ(x_size, 2);
426     EXPECT_EQ(f_size, 1);
427     EXPECT_EQ(b_size, 1);
428
429     bool test_is_correct = true;
430
431     std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
432
433     for (size_t i = 0; i < output_cpu_vec.size(); ++i) {
434         if (output_cpu_vec[i] != output_ptr[i]) {
435             test_is_correct = false;
436         }
437     }
438     EXPECT_EQ(test_is_correct, true);
439 }
440
441 TEST(one_hot_error, basic_error_wrong_axis) {
442     const auto& engine = get_test_engine();
443     auto input = memory::allocate(engine, { data_types::i32, format::bfyx,{ 1, 1, 1, 1 } });
444
445     topology topology;
446     topology.add(input_layout("input", input.get_layout()));
447     topology.add(one_hot("output", "input", tensor(1, 1, 1, 50), 5));
448
449     std::string msg_to_find = "Incorrect parameters configuration: one_hot_axis should be less or equal to 4.";
450     EXPECT_ANY_THROW(check_exception_massage(engine, topology, msg_to_find));
451 }
452
453 TEST(one_hot_error, basic_error_bad_shape) {
454     const auto& engine = get_test_engine();
455     auto input = memory::allocate(engine, { data_types::i32, format::bfyx,{ 1, 1, 1, 1 } });
456
457     topology topology;
458     topology.add(input_layout("input", input.get_layout()));
459     topology.add(one_hot("output", "input", tensor(1, 5, 1, 50), 2));
460
461     std::string msg_to_find = "Incorrect parameters configuration: shape does not fit input size.";
462     EXPECT_ANY_THROW(check_exception_massage(engine, topology, msg_to_find));
463 }