Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / border_gpu_test.cpp
1 // Copyright (c) 2018 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/CPP/engine.hpp>
19 #include <api/CPP/input_layout.hpp>
20 #include <api/CPP/memory.hpp>
21 #include <api/CPP/border.hpp>
22 #include <api/CPP/topology.hpp>
23 #include <api/CPP/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
31 using namespace cldnn;
32 using namespace ::tests;
33
34
35 template<typename T>
36 static std::vector<T> generate_rnd_real_input(
37     const std::size_t b, const std::size_t f, const std::size_t y, const std::size_t x,
38     const T min = static_cast<T>(0), const T max = static_cast<T>(1), const unsigned rnd_bits = 9)
39 {
40     static std::default_random_engine rnd_gen(random_seed);
41     cldnn::tests::distributions::uniform_quantized_real_distribution<T> rnd_dist(min, max, rnd_bits);
42
43     std::vector<T> data;
44     data.reserve(b * f * y * x);
45     for (size_t i = 0; i < b * f * y * x; ++i)
46         data.push_back(rnd_dist(rnd_gen));
47
48     return data;
49 }
50
51
52 TEST(border_gpu, basic_yxfb_0x0x1x2_0x0x3x4_border_constant) {
53     //  Input (XY) : 4x3
54     //  Output (XY): 10x7
55
56     constexpr auto in_size_b = 1;
57     constexpr auto in_size_f = 1;
58     constexpr auto in_size_y = 3;
59     constexpr auto in_size_x = 4;
60
61     constexpr auto blt_size_b = 0;
62     constexpr auto blt_size_f = 0;
63     constexpr auto blt_size_y = 1;
64     constexpr auto blt_size_x = 2;
65
66     constexpr auto brb_size_b = 0;
67     constexpr auto brb_size_f = 0;
68     constexpr auto brb_size_y = 3;
69     constexpr auto brb_size_x = 4;
70
71     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
72     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
73     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
74     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
75
76     const auto& engine = get_test_engine();
77     auto input = memory::allocate(engine, {data_types::f32, format::yxfb, {in_size_b, in_size_f, in_size_x, in_size_y}});
78
79     topology topology;
80     topology.add(
81         input_layout("input", input.get_layout())
82     );
83     topology.add(
84         border("output", "input",
85                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
86                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
87                border_type::constant, 0.0f)
88     );
89
90     std::vector<float> input_data = {
91           1, -2,  3,  -4,
92           5,  6,  7,   8,
93         -10, 12, 13, -13,
94     };
95     std::vector<float> out_data = {
96         0, 0,   0,  0,  0,   0, 0, 0, 0, 0,
97         0, 0,   1, -2,  3,  -4, 0, 0, 0, 0,
98         0, 0,   5,  6,  7,   8, 0, 0, 0, 0,
99         0, 0, -10, 12, 13, -13, 0, 0, 0, 0,
100         0, 0,   0,  0,  0,   0, 0, 0, 0, 0,
101         0, 0,   0,  0,  0,   0, 0, 0, 0, 0,
102         0, 0,   0,  0,  0,   0, 0, 0, 0, 0,
103     };
104     set_values(input, input_data);
105
106     network network(engine, topology);
107     network.set_input_data("input", input);
108     auto outputs = network.execute();
109
110     auto output = outputs.at("output").get_memory();
111     auto output_ptr = output.pointer<float>();
112
113     ASSERT_EQ(out_data.size(), static_cast<std::size_t>(out_size_b * out_size_f * out_size_y * out_size_x));
114
115     for (auto b = 0; b < out_size_b; ++b) {             // B
116         for (auto f = 0; f < out_size_f; ++f) {         // F
117             for (auto y = 0; y < out_size_y; ++y) {     // Y
118                 for (auto x = 0; x < out_size_x; ++x) { // X
119                     auto output_off = ((y * out_size_x + x) * out_size_f + f) * out_size_b + b; // YXFB
120
121                     EXPECT_EQ(output_ptr[output_off], out_data[output_off]);
122                 }
123             }
124         }
125     }
126 }
127
128 TEST(border_gpu, basic_yxfb_0x0x1x2_0x0x3x4_border_constant_non_constant) {
129     //  Input (XY) : 4x3
130     //  Output (XY): 10x7
131
132     constexpr auto in_size_b = 1;
133     constexpr auto in_size_f = 1;
134     constexpr auto in_size_y = 3;
135     constexpr auto in_size_x = 4;
136
137     constexpr auto blt_size_b = 0;
138     constexpr auto blt_size_f = 0;
139     constexpr auto blt_size_y = 1;
140     constexpr auto blt_size_x = 2;
141
142     constexpr auto brb_size_b = 0;
143     constexpr auto brb_size_f = 0;
144     constexpr auto brb_size_y = 3;
145     constexpr auto brb_size_x = 4;
146
147     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
148     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
149     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
150     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
151
152     const auto& engine = get_test_engine();
153     auto input = memory::allocate(engine, {data_types::f32, format::yxfb, {in_size_b, in_size_f, in_size_x, in_size_y}});
154
155     topology topology;
156     topology.add(
157         input_layout("input", input.get_layout())
158     );
159     topology.add(
160         border("output", "input",
161                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
162                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
163                border_type::constant, 1.0f)
164     );
165
166     std::vector<float> input_data = {
167           1, -2,  3,  -4,
168           5,  6,  7,   8,
169         -10, 12, 13, -13,
170     };
171     std::vector<float> out_data = {
172         1, 1,   1,  1,  1,   1, 1, 1, 1, 1,
173         1, 1,   1, -2,  3,  -4, 1, 1, 1, 1,
174         1, 1,   5,  6,  7,   8, 1, 1, 1, 1,
175         1, 1, -10, 12, 13, -13, 1, 1, 1, 1,
176         1, 1,   1,  1,  1,   1, 1, 1, 1, 1,
177         1, 1,   1,  1,  1,   1, 1, 1, 1, 1,
178         1, 1,   1,  1,  1,   1, 1, 1, 1, 1,
179     };
180     set_values(input, input_data);
181
182     network network(engine, topology);
183     network.set_input_data("input", input);
184     auto outputs = network.execute();
185
186     auto output = outputs.at("output").get_memory();
187     auto output_ptr = output.pointer<float>();
188
189     ASSERT_EQ(out_data.size(), static_cast<std::size_t>(out_size_b * out_size_f * out_size_y * out_size_x));
190
191     for (auto b = 0; b < out_size_b; ++b) {             // B
192         for (auto f = 0; f < out_size_f; ++f) {         // F
193             for (auto y = 0; y < out_size_y; ++y) {     // Y
194                 for (auto x = 0; x < out_size_x; ++x) { // X
195                     auto output_off = ((y * out_size_x + x) * out_size_f + f) * out_size_b + b; // YXFB
196
197                     EXPECT_EQ(output_ptr[output_off], out_data[output_off]);
198                 }
199             }
200         }
201     }
202 }
203
204 TEST(border_gpu, basic_yxfb_0x0x1x2_0x0x3x4_border_mirror) {
205     //  Input (XY) : 4x3
206     //  Output (XY): 10x7
207
208     constexpr auto in_size_b = 1;
209     constexpr auto in_size_f = 1;
210     constexpr auto in_size_y = 3;
211     constexpr auto in_size_x = 4;
212
213     constexpr auto blt_size_b = 0;
214     constexpr auto blt_size_f = 0;
215     constexpr auto blt_size_y = 1;
216     constexpr auto blt_size_x = 2;
217
218     constexpr auto brb_size_b = 0;
219     constexpr auto brb_size_f = 0;
220     constexpr auto brb_size_y = 3;
221     constexpr auto brb_size_x = 4;
222
223     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
224     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
225     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
226     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
227
228     const auto& engine = get_test_engine();
229     auto input = memory::allocate(engine, {data_types::f32, format::yxfb, {in_size_b, in_size_f, in_size_x, in_size_y}});
230
231     topology topology;
232     topology.add(
233         input_layout("input", input.get_layout())
234     );
235     topology.add(
236         border("output", "input",
237                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
238                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
239                border_type::mirror)
240     );
241
242     std::vector<float> input_data = {
243           1, -2,  3,  -4,
244           5,  6,  7,   8,
245         -10, 12, 13, -13,
246     };
247     std::vector<float> out_data = {
248         -2,   1,   1, -2,  3,  -4,  -4,  3, -2,   1,
249         -2,   1,   1, -2,  3,  -4,  -4,  3, -2,   1,
250          6,   5,   5,  6,  7,   8,   8,  7,  6,   5,
251         12, -10, -10, 12, 13, -13, -13, 13, 12, -10,
252         12, -10, -10, 12, 13, -13, -13, 13, 12, -10,
253          6,   5,   5,  6,  7,   8,   8,  7,  6,   5,
254         -2,   1,   1, -2,  3,  -4,  -4,  3, -2,   1,
255     };
256     set_values(input, input_data);
257
258     network network(engine, topology);
259     network.set_input_data("input", input);
260     auto outputs = network.execute();
261
262     auto output = outputs.at("output").get_memory();
263     auto output_ptr = output.pointer<float>();
264
265     ASSERT_EQ(out_data.size(), static_cast<std::size_t>(out_size_b * out_size_f * out_size_y * out_size_x));
266
267     for (auto b = 0; b < out_size_b; ++b) {             // B
268         for (auto f = 0; f < out_size_f; ++f) {         // F
269             for (auto y = 0; y < out_size_y; ++y) {     // Y
270                 for (auto x = 0; x < out_size_x; ++x) { // X
271                     auto output_off = ((y * out_size_x + x) * out_size_f + f) * out_size_b + b; // YXFB
272
273                     EXPECT_EQ(output_ptr[output_off], out_data[output_off]);
274                 }
275             }
276         }
277     }
278 }
279
280 TEST(border_gpu, basic_yxfb_0x0x1x2_0x0x3x4_border_mirror_101) {
281     //  Input (XY) : 5x4
282     //  Output (XY): 11x8
283
284     constexpr auto in_size_b = 1;
285     constexpr auto in_size_f = 1;
286     constexpr auto in_size_y = 4;
287     constexpr auto in_size_x = 5;
288
289     constexpr auto blt_size_b = 0;
290     constexpr auto blt_size_f = 0;
291     constexpr auto blt_size_y = 1;
292     constexpr auto blt_size_x = 2;
293
294     constexpr auto brb_size_b = 0;
295     constexpr auto brb_size_f = 0;
296     constexpr auto brb_size_y = 3;
297     constexpr auto brb_size_x = 4;
298
299     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
300     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
301     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
302     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
303
304     const auto& engine = get_test_engine();
305     auto input = memory::allocate(engine, {data_types::f32, format::yxfb, {in_size_b, in_size_f, in_size_x, in_size_y}});
306
307     topology topology;
308     topology.add(
309         input_layout("input", input.get_layout())
310     );
311     topology.add(
312         border("output", "input",
313                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
314                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
315                border_type::mirror_101)
316     );
317
318     std::vector<float> input_data = {
319           1, -2,  3,  -4,  4,
320           5,  6,  7,   8, -8,
321         -10, 12, 13, -13, 10,
322         -20, 22, 23, -23, 20,
323     };
324     std::vector<float> out_data = {
325          7,  6,   5,  6,  7,   8, -8,   8,  7,  6,   5,
326          3, -2,   1, -2,  3,  -4,  4,  -4,  3, -2,   1,
327          7,  6,   5,  6,  7,   8, -8,   8,  7,  6,   5,
328         13, 12, -10, 12, 13, -13, 10, -13, 13, 12, -10,
329         23, 22, -20, 22, 23, -23, 20, -23, 23, 22, -20,
330         13, 12, -10, 12, 13, -13, 10, -13, 13, 12, -10,
331          7,  6,   5,  6,  7,   8, -8,   8,  7,  6,   5,
332          3, -2,   1, -2,  3,  -4,  4,  -4,  3, -2,   1,
333     };
334     set_values(input, input_data);
335
336     network network(engine, topology);
337     network.set_input_data("input", input);
338     auto outputs = network.execute();
339
340     auto output = outputs.at("output").get_memory();
341     auto output_ptr = output.pointer<float>();
342
343     ASSERT_EQ(out_data.size(), static_cast<std::size_t>(out_size_b * out_size_f * out_size_y * out_size_x));
344
345     for (auto b = 0; b < out_size_b; ++b) {             // B
346         for (auto f = 0; f < out_size_f; ++f) {         // F
347             for (auto y = 0; y < out_size_y; ++y) {     // Y
348                 for (auto x = 0; x < out_size_x; ++x) { // X
349                     auto output_off = ((y * out_size_x + x) * out_size_f + f) * out_size_b + b; // YXFB
350
351                     EXPECT_EQ(output_ptr[output_off], out_data[output_off]);
352                 }
353             }
354         }
355     }
356 }
357
358 TEST(border_gpu, basic_yxfb_0x0x1x2_0x0x3x4_border_edge) {
359     //  Input (XY) : 5x4
360     //  Output (XY): 11x8
361
362     constexpr auto in_size_b = 1;
363     constexpr auto in_size_f = 1;
364     constexpr auto in_size_y = 4;
365     constexpr auto in_size_x = 5;
366
367     constexpr auto blt_size_b = 0;
368     constexpr auto blt_size_f = 0;
369     constexpr auto blt_size_y = 1;
370     constexpr auto blt_size_x = 2;
371
372     constexpr auto brb_size_b = 0;
373     constexpr auto brb_size_f = 0;
374     constexpr auto brb_size_y = 3;
375     constexpr auto brb_size_x = 4;
376
377     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
378     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
379     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
380     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
381
382     const auto& engine = get_test_engine();
383     auto input = memory::allocate(engine, {data_types::f32, format::yxfb, {in_size_b, in_size_f, in_size_x, in_size_y}});
384
385     topology topology;
386     topology.add(
387         input_layout("input", input.get_layout())
388     );
389     topology.add(
390         border("output", "input",
391                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
392                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
393                border_type::edge)
394     );
395
396     std::vector<float> input_data = {
397           1, -2,  3,  -4,  4,
398           5,  6,  7,   8, -8,
399         -10, 12, 13, -13, 10,
400         -20, 22, 23, -23, 20,
401     };
402     std::vector<float> out_data = {
403           1,   1,   1, -2,  3,  -4,  4,  4,  4,  4,  4,
404           1,   1,   1, -2,  3,  -4,  4,  4,  4,  4,  4,
405           5,   5,   5,  6,  7,   8, -8, -8, -8, -8, -8,
406         -10, -10, -10, 12, 13, -13, 10, 10, 10, 10, 10,
407         -20, -20, -20, 22, 23, -23, 20, 20, 20, 20, 20,
408         -20, -20, -20, 22, 23, -23, 20, 20, 20, 20, 20,
409         -20, -20, -20, 22, 23, -23, 20, 20, 20, 20, 20,
410         -20, -20, -20, 22, 23, -23, 20, 20, 20, 20, 20
411     };
412     set_values(input, input_data);
413
414     network network(engine, topology);
415     network.set_input_data("input", input);
416     auto outputs = network.execute();
417
418     auto output = outputs.at("output").get_memory();
419     auto output_ptr = output.pointer<float>();
420
421     ASSERT_EQ(out_data.size(), static_cast<std::size_t>(out_size_b * out_size_f * out_size_y * out_size_x));
422
423     for (auto b = 0; b < out_size_b; ++b) {             // B
424         for (auto f = 0; f < out_size_f; ++f) {         // F
425             for (auto y = 0; y < out_size_y; ++y) {     // Y
426                 for (auto x = 0; x < out_size_x; ++x) { // X
427                     auto output_off = ((y * out_size_x + x) * out_size_f + f) * out_size_b + b; // YXFB
428
429                     EXPECT_EQ(output_ptr[output_off], out_data[output_off]);
430                 }
431             }
432         }
433     }
434 }
435
436 TEST(border_gpu, basic_bfyx_2x1x2x3_1x2x3x4_border_constant) {
437     constexpr auto in_size_b = 2;
438     constexpr auto in_size_f = 3;
439     constexpr auto in_size_y = 5;
440     constexpr auto in_size_x = 4;
441
442     constexpr auto blt_size_b = 2;
443     constexpr auto blt_size_f = 1;
444     constexpr auto blt_size_y = 2;
445     constexpr auto blt_size_x = 3;
446
447     constexpr auto brb_size_b = 1;
448     constexpr auto brb_size_f = 2;
449     constexpr auto brb_size_y = 3;
450     constexpr auto brb_size_x = 4;
451
452     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
453     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
454     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
455     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
456
457     const auto& engine = get_test_engine();
458     auto input = memory::allocate(engine, {data_types::f32, format::bfyx, {in_size_b, in_size_f, in_size_x, in_size_y}});
459
460     topology topology;
461     topology.add(
462         input_layout("input", input.get_layout())
463     );
464     topology.add(
465         border("output", "input",
466                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
467                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
468                border_type::constant,
469                0.0f)
470     );
471
472     std::vector<float> input_data = generate_rnd_real_input<float>(in_size_b, in_size_f, in_size_y, in_size_x, -8.0f, 8.0f);
473     set_values(input, input_data);
474
475     network network(engine, topology);
476     network.set_input_data("input", input);
477     auto outputs = network.execute();
478
479     auto output = outputs.at("output").get_memory();
480     auto output_ptr = output.pointer<float>();
481
482     for (auto b = 0; b < out_size_b; ++b) {             // B
483         for (auto f = 0; f < out_size_f; ++f) {         // F
484             for (auto y = 0; y < out_size_y; ++y) {     // Y
485                 for (auto x = 0; x < out_size_x; ++x) { // X
486                     auto output_off = ((b * out_size_f + f) * out_size_y + y) * out_size_x + x; // BFYX
487
488                     if (b < blt_size_b || b >= out_size_b - brb_size_b ||
489                         f < blt_size_f || f >= out_size_f - brb_size_f ||
490                         y < blt_size_y || y >= out_size_y - brb_size_y ||
491                         x < blt_size_x || x >= out_size_x - brb_size_x)
492                     {
493                         EXPECT_EQ(output_ptr[output_off], 0.0f);
494                     }
495                     else
496                     {
497                         auto input_off  = (((b - blt_size_b) * in_size_f + f - blt_size_f) * in_size_y + y - blt_size_y) * in_size_x + x - blt_size_x; // BFYX
498                         EXPECT_EQ(output_ptr[output_off], input_data[input_off]);
499                     }
500                 }
501             }
502         }
503     }
504 }
505
506 TEST(border_gpu, basic_bfyx_2x1x2x3_1x2x3x4_border_mirror) {
507     constexpr auto in_size_b = 2;
508     constexpr auto in_size_f = 3;
509     constexpr auto in_size_y = 5;
510     constexpr auto in_size_x = 4;
511
512     constexpr auto blt_size_b = 2;
513     constexpr auto blt_size_f = 1;
514     constexpr auto blt_size_y = 2;
515     constexpr auto blt_size_x = 3;
516
517     constexpr auto brb_size_b = 1;
518     constexpr auto brb_size_f = 2;
519     constexpr auto brb_size_y = 3;
520     constexpr auto brb_size_x = 4;
521
522     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
523     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
524     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
525     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
526
527     const auto& engine = get_test_engine();
528     auto input = memory::allocate(engine, {data_types::f32, format::bfyx, {in_size_b, in_size_f, in_size_x, in_size_y}});
529
530     topology topology;
531     topology.add(
532         input_layout("input", input.get_layout())
533     );
534     topology.add(
535         border("output", "input",
536                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
537                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
538                border_type::mirror)
539     );
540
541     std::vector<float> input_data = generate_rnd_real_input<float>(in_size_b, in_size_f, in_size_y, in_size_x, -8.0f, 8.0f);
542     set_values(input, input_data);
543
544     network network(engine, topology);
545     network.set_input_data("input", input);
546     auto outputs = network.execute();
547
548     auto output = outputs.at("output").get_memory();
549     auto output_ptr = output.pointer<float>();
550
551     for (auto b = 0; b < out_size_b; ++b) {             // B
552         for (auto f = 0; f < out_size_f; ++f) {         // F
553             for (auto y = 0; y < out_size_y; ++y) {     // Y
554                 for (auto x = 0; x < out_size_x; ++x) { // X
555                     auto output_off = ((b * out_size_f + f) * out_size_y + y) * out_size_x + x; // BFYX
556
557                     auto in_b = (b >= blt_size_b && b < out_size_b - brb_size_b) ? b - blt_size_b : (b < blt_size_b ? blt_size_b - 1 - b : in_size_b + out_size_b - brb_size_b - 1 - b);
558                     auto in_f = (f >= blt_size_f && f < out_size_f - brb_size_f) ? f - blt_size_f : (f < blt_size_f ? blt_size_f - 1 - f : in_size_f + out_size_f - brb_size_f - 1 - f);
559                     auto in_y = (y >= blt_size_y && y < out_size_y - brb_size_y) ? y - blt_size_y : (y < blt_size_y ? blt_size_y - 1 - y : in_size_y + out_size_y - brb_size_y - 1 - y);
560                     auto in_x = (x >= blt_size_x && x < out_size_x - brb_size_x) ? x - blt_size_x : (x < blt_size_x ? blt_size_x - 1 - x : in_size_x + out_size_x - brb_size_x - 1 - x);
561
562                     auto input_off  = ((in_b * in_size_f + in_f) * in_size_y + in_y) * in_size_x + in_x; // BFYX
563
564
565                     EXPECT_EQ(output_ptr[output_off], input_data[input_off]);
566                 }
567             }
568         }
569     }
570 }
571
572 TEST(border_gpu, basic_bfyx_2x1x2x3_1x2x3x4_border_mirror_101) {
573     constexpr auto in_size_b = 3;
574     constexpr auto in_size_f = 4;
575     constexpr auto in_size_y = 6;
576     constexpr auto in_size_x = 5;
577
578     constexpr auto blt_size_b = 2;
579     constexpr auto blt_size_f = 1;
580     constexpr auto blt_size_y = 2;
581     constexpr auto blt_size_x = 3;
582
583     constexpr auto brb_size_b = 1;
584     constexpr auto brb_size_f = 2;
585     constexpr auto brb_size_y = 3;
586     constexpr auto brb_size_x = 4;
587
588     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
589     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
590     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
591     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
592
593     const auto& engine = get_test_engine();
594     auto input = memory::allocate(engine, {data_types::f32, format::bfyx, {in_size_b, in_size_f, in_size_x, in_size_y}});
595
596     topology topology;
597     topology.add(
598         input_layout("input", input.get_layout())
599     );
600     topology.add(
601         border("output", "input",
602                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
603                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
604                border_type::mirror_101)
605     );
606
607     std::vector<float> input_data = generate_rnd_real_input<float>(in_size_b, in_size_f, in_size_y, in_size_x, -8.0f, 8.0f);
608     set_values(input, input_data);
609
610     network network(engine, topology);
611     network.set_input_data("input", input);
612     auto outputs = network.execute();
613
614     auto output = outputs.at("output").get_memory();
615     auto output_ptr = output.pointer<float>();
616
617     for (auto b = 0; b < out_size_b; ++b) {             // B
618         for (auto f = 0; f < out_size_f; ++f) {         // F
619             for (auto y = 0; y < out_size_y; ++y) {     // Y
620                 for (auto x = 0; x < out_size_x; ++x) { // X
621                     auto output_off = ((b * out_size_f + f) * out_size_y + y) * out_size_x + x; // BFYX
622
623                     auto in_b = (b >= blt_size_b && b < out_size_b - brb_size_b) ? b - blt_size_b : (b < blt_size_b ? blt_size_b - b : in_size_b + out_size_b - brb_size_b - 2 - b);
624                     auto in_f = (f >= blt_size_f && f < out_size_f - brb_size_f) ? f - blt_size_f : (f < blt_size_f ? blt_size_f - f : in_size_f + out_size_f - brb_size_f - 2 - f);
625                     auto in_y = (y >= blt_size_y && y < out_size_y - brb_size_y) ? y - blt_size_y : (y < blt_size_y ? blt_size_y - y : in_size_y + out_size_y - brb_size_y - 2 - y);
626                     auto in_x = (x >= blt_size_x && x < out_size_x - brb_size_x) ? x - blt_size_x : (x < blt_size_x ? blt_size_x - x : in_size_x + out_size_x - brb_size_x - 2 - x);
627
628                     auto input_off  = ((in_b * in_size_f + in_f) * in_size_y + in_y) * in_size_x + in_x; // BFYX
629
630
631                     EXPECT_EQ(output_ptr[output_off], input_data[input_off]);
632                 }
633             }
634         }
635     }
636 }
637
638 TEST(border_gpu, basic_bfyx_2x1x2x3_1x2x3x4_border_edge) {
639     constexpr auto in_size_b = 3;
640     constexpr auto in_size_f = 4;
641     constexpr auto in_size_y = 6;
642     constexpr auto in_size_x = 5;
643
644     constexpr auto blt_size_b = 2;
645     constexpr auto blt_size_f = 1;
646     constexpr auto blt_size_y = 2;
647     constexpr auto blt_size_x = 3;
648
649     constexpr auto brb_size_b = 1;
650     constexpr auto brb_size_f = 2;
651     constexpr auto brb_size_y = 3;
652     constexpr auto brb_size_x = 4;
653
654     constexpr auto out_size_b = in_size_b + blt_size_b + brb_size_b;
655     constexpr auto out_size_f = in_size_f + blt_size_f + brb_size_f;
656     constexpr auto out_size_y = in_size_y + blt_size_y + brb_size_y;
657     constexpr auto out_size_x = in_size_x + blt_size_x + brb_size_x;
658
659     const auto& engine = get_test_engine();
660     auto input = memory::allocate(engine, {data_types::f32, format::bfyx, {in_size_b, in_size_f, in_size_x, in_size_y}});
661
662     topology topology;
663     topology.add(
664         input_layout("input", input.get_layout())
665     );
666     topology.add(
667         border("output", "input",
668                {blt_size_b, blt_size_f, blt_size_x, blt_size_y},
669                {brb_size_b, brb_size_f, brb_size_x, brb_size_y},
670                border_type::edge)
671     );
672
673     std::vector<float> input_data = generate_rnd_real_input<float>(in_size_b, in_size_f, in_size_y, in_size_x, -8.0f, 8.0f);
674     set_values(input, input_data);
675
676     network network(engine, topology);
677     network.set_input_data("input", input);
678     auto outputs = network.execute();
679
680     auto output = outputs.at("output").get_memory();
681     auto output_ptr = output.pointer<float>();
682
683     for (auto b = 0; b < out_size_b; ++b) {             // B
684         for (auto f = 0; f < out_size_f; ++f) {         // F
685             for (auto y = 0; y < out_size_y; ++y) {     // Y
686                 for (auto x = 0; x < out_size_x; ++x) { // X
687                     auto output_off = ((b * out_size_f + f) * out_size_y + y) * out_size_x + x; // BFYX
688
689                     auto in_b = (b >= blt_size_b && b < out_size_b - brb_size_b) ? b - blt_size_b : (b < blt_size_b ? 0 : in_size_b - 1);
690                     auto in_f = (f >= blt_size_f && f < out_size_f - brb_size_f) ? f - blt_size_f : (f < blt_size_f ? 0 : in_size_f - 1);
691                     auto in_y = (y >= blt_size_y && y < out_size_y - brb_size_y) ? y - blt_size_y : (y < blt_size_y ? 0 : in_size_y - 1);
692                     auto in_x = (x >= blt_size_x && x < out_size_x - brb_size_x) ? x - blt_size_x : (x < blt_size_x ? 0 : in_size_x - 1);
693
694                     auto input_off  = ((in_b * in_size_f + in_f) * in_size_y + in_y) * in_size_x + in_x; // BFYX
695
696
697                     EXPECT_EQ(output_ptr[output_off], input_data[input_off]);
698                 }
699             }
700         }
701     }
702 }