1 // Copyright (c) 2019 Intel Corporation
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 ///////////////////////////////////////////////////////////////////////////////////////////////////
16 #include <gtest/gtest.h>
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>
25 #include "test_utils/test_utils.h"
26 #include "test_utils/uniform_quantized_real_distribution.hpp"
30 using namespace cldnn;
31 using namespace ::tests;
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) {
39 size_t padding_y = input_padding_y + output_padding_y;
40 size_t padding_x = input_padding_x + output_padding_x;
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]))));
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;
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;
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;
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;
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];
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);
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);
102 topology.add(input_layout("input", input.get_layout()));
103 topology.add(one_hot("output", "input", shape, one_hot_axis));
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");
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>();
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());
127 bool test_is_correct = true;
128 VF<T> output_cpu_vec = flatten_4d<T>(test_input_fmt, output_cpu);
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;
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;
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);
157 TEST(one_hot_gpu_i32, bfzyx_ax4) {
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];
171 VF<int32_t> input_rnd_vec = {0, 1};
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 });
177 topology.add(input_layout("input", input.get_layout()));
178 topology.add(one_hot("output","input", shape, one_hot_axis));
180 set_values(input, input_rnd_vec);
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");
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>();
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);
204 bool test_is_correct = true;
206 std::vector<int32_t> output_cpu_vec = {1, 0, 0, 0, 0,
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;
214 EXPECT_EQ(test_is_correct, true);
217 TEST(one_hot_gpu_i32, bfzyx_ax0) {
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];
228 VF<int32_t> input_rnd_vec = {0, 1};
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 });
234 topology.add(input_layout("input", input.get_layout()));
235 topology.add(one_hot("output","input", shape, one_hot_axis));
237 set_values(input, input_rnd_vec);
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");
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>();
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);
261 bool test_is_correct = true;
263 std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
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;
270 EXPECT_EQ(test_is_correct, true);
273 TEST(one_hot_gpu_i32, bfzyx_ax1) {
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];
284 VF<int32_t> input_rnd_vec = {0, 1};
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 });
290 topology.add(input_layout("input", input.get_layout()));
291 topology.add(one_hot("output","input", shape, one_hot_axis));
293 set_values(input, input_rnd_vec);
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");
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>();
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);
317 bool test_is_correct = true;
319 std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
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;
326 EXPECT_EQ(test_is_correct, true);
329 TEST(one_hot_gpu_i32, bfzyx_ax2) {
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];
340 VF<int32_t> input_rnd_vec = {0, 1};
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 });
346 topology.add(input_layout("input", input.get_layout()));
347 topology.add(one_hot("output","input", shape, one_hot_axis));
349 set_values(input, input_rnd_vec);
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");
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>();
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);
373 bool test_is_correct = true;
375 std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
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;
382 EXPECT_EQ(test_is_correct, true);
385 TEST(one_hot_gpu_i32, bfzyx_ax3) {
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];
396 VF<int32_t> input_rnd_vec = {0, 1};
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 });
402 topology.add(input_layout("input", input.get_layout()));
403 topology.add(one_hot("output","input", shape, one_hot_axis));
405 set_values(input, input_rnd_vec);
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");
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>();
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);
429 bool test_is_correct = true;
431 std::vector<int32_t> output_cpu_vec = {1, 0, 0, 1, 0, 0};
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;
438 EXPECT_EQ(test_is_correct, true);
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 } });
446 topology.add(input_layout("input", input.get_layout()));
447 topology.add(one_hot("output", "input", tensor(1, 1, 1, 50), 5));
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));
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 } });
458 topology.add(input_layout("input", input.get_layout()));
459 topology.add(one_hot("output", "input", tensor(1, 5, 1, 50), 2));
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));