Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / reshape_gpu_test.cpp
1 /*
2 // Copyright (c) 2017 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 #include <gtest/gtest.h>
19 #include <api/CPP/topology.hpp>
20 #include <api/CPP/network.hpp>
21 #include <api/CPP/engine.hpp>
22
23 #include <api/CPP/data.hpp>
24 #include <api/CPP/reshape.hpp>
25 #include <api/CPP/input_layout.hpp>
26
27 #include "test_utils/test_utils.h"
28
29 using namespace cldnn;
30 using namespace tests;
31 using namespace testing;
32
33 void verify_float(const float &output_value, const float &value)
34 {
35     EXPECT_FLOAT_EQ(output_value, value);
36 }
37
38 void verify_int(const int32_t &output_value, const int32_t &value)
39 {
40     EXPECT_EQ(output_value, value);
41 }
42
43 template <class ElemType>
44 void generic_reshape_test(format fmt, tensor const& input_size, tensor const& reshape_size, bool in_place, padding const& input_padd = padding(), padding const& output_padd = padding())
45 {
46     const auto& engine = get_test_engine();
47
48     //allocate input memory
49     auto data_type = data_types::f32;
50     if (std::is_same<ElemType, FLOAT16>::value)
51         data_type = data_types::f16;
52     else if (std::is_same<ElemType, int8_t>::value)
53         data_type = data_types::i8;
54     else if (std::is_same<ElemType, int32_t>::value)
55         data_type = data_types::i32;
56     else if (std::is_same<ElemType, int64_t>::value)
57         data_type = data_types::i64;
58
59     auto input = memory::allocate(engine, { data_type, fmt, input_size });
60     
61     {
62         auto input_ptr = input.cldnn::memory::pointer<ElemType>();
63         auto input_itr = input_ptr.begin();
64
65         auto elements = input_size.count();
66
67         int value = 1;
68         for (size_t i = 0; i < elements; ++i)
69             *input_itr++ = (ElemType)value++;
70     }
71
72     topology tpl;
73     std::string reshape_input = "input";
74
75     tpl.add(input_layout("input", input.get_layout()));
76     if (input_padd)
77     {
78         auto padded_input_layout = input.get_layout();
79         padded_input_layout.data_padding = input_padd;
80         tpl.add(reorder("reorder", "input", padded_input_layout));
81         reshape_input = "reorder";
82     }
83     tpl.add(reshape("reshape", reshape_input, reshape_size, output_padd));
84
85     build_options bo;
86     bo.set_option(build_option::outputs({ reshape_input, "reshape" }));
87
88     network net(engine, tpl, bo);
89     net.set_input_data("input", input);
90     auto outputs = net.execute();
91
92     ASSERT_TRUE(outputs.size() == 2 && outputs.count("reshape") == 1 && outputs.count(reshape_input) == 1);
93     auto net_input = outputs.at(reshape_input).get_memory();
94     auto output = outputs.at("reshape").get_memory();
95
96     EXPECT_TRUE(output.get_layout().data_type == input.get_layout().data_type);     //reshape should not change data_type
97     EXPECT_TRUE(output.get_layout().format == input.get_layout().format); //reshape should not change format
98
99     //output size should be equal to requested plus output padding
100     ASSERT_TRUE(output.get_layout().size == reshape_size);
101     ASSERT_TRUE(output.get_layout().get_buffer_size() == reshape_size.add(output_padd.lower_size()).add(output_padd.upper_size()));
102
103     {
104         auto output_ptr = output.pointer<const ElemType>();
105         auto output_itr = output_ptr.begin();
106
107         auto sizes = reshape_size.sizes(fmt);
108         auto lower = output_padd.lower_size().sizes(fmt);
109         auto upper = output_padd.upper_size().sizes(fmt);
110         auto buffer_sizes = sizes;
111         int32_t accum = 1;
112         for (size_t i = 1; i <= sizes.size(); ++i)
113         {
114             buffer_sizes[sizes.size() - i] = accum;
115             accum *= lower[sizes.size() - i] + sizes[sizes.size() - i] + upper[sizes.size() - i];
116         }
117
118         int value = 1;
119
120         output_itr += lower[0] * buffer_sizes[0];
121         for (int d1 = 0; d1 < sizes[0]; ++d1)
122         {
123             output_itr += lower[1] * buffer_sizes[1];
124             for (int d2 = 0; d2 < sizes[1]; ++d2)
125             {
126                 output_itr += lower[2] * buffer_sizes[2];
127                 for (int d3 = 0; d3 < sizes[2]; ++d3)
128                 {
129                     output_itr += lower[3] * buffer_sizes[3];
130                     for (int d4 = 0; d4 < sizes[3]; ++d4)
131                     {
132                         auto& output_value = *output_itr;
133                         ++output_itr;
134                         if (data_type == data_types::f16 || data_type == data_types::f32)
135                             verify_float(static_cast<float>(output_value), static_cast<float>((ElemType)value));
136                         else
137                             verify_int(static_cast<int32_t>(output_value), static_cast<int32_t>(value));
138                         ++value;
139                     }
140
141                     output_itr += upper[3] * buffer_sizes[3];
142                 }
143
144                 output_itr += upper[2] * buffer_sizes[2];
145             }
146
147             output_itr += upper[1] * buffer_sizes[1];
148         }
149     }
150 }
151
152 TEST(reshape_gpu_f32, basic_2dim_in_place)
153 {
154     generic_reshape_test<float>(
155         format::bfyx,
156         tensor(1, 1, 2, 2),
157         tensor(1, 1, 4, 1),
158         true);
159 }
160
161 TEST(reshape_gpu_f16, basic_2dim_in_place)
162 {
163     generic_reshape_test<FLOAT16>(
164         format::bfyx,
165         tensor(1, 1, 2, 2),
166         tensor(1, 1, 1, 4),
167         true);
168 }
169
170 TEST(reshape_gpu_i8, basic_2dim_in_place)
171 {
172     generic_reshape_test<int8_t>(
173         format::bfyx,
174         tensor(1, 1, 2, 2),
175         tensor(1, 1, 1, 4),
176         true);
177 }
178
179 TEST(reshape_gpu_i32, basic_2dim_in_place)
180 {
181     generic_reshape_test<int32_t>(
182         format::bfyx,
183         tensor(1, 1, 2, 2),
184         tensor(1, 1, 1, 4),
185         true);
186 }
187
188 TEST(reshape_gpu_i64, basic_2dim_in_place)
189 {
190     generic_reshape_test<int64_t>(
191         format::bfyx,
192         tensor(1, 1, 2, 2),
193         tensor(1, 1, 1, 4),
194         true);
195 }
196
197 TEST(reshape_gpu_f32, basic_4dim_in_place)
198 {
199     generic_reshape_test<float>(
200         format::yxfb,
201         tensor(9, 9, 2, 4),
202         tensor(27, 2, 3, 4),
203         true);
204 }
205
206 TEST(reshape_gpu_f16, basic_4dim_in_place)
207 {
208     generic_reshape_test<FLOAT16>(
209         format::yxfb,
210         tensor(9, 9, 2, 4),
211         tensor(3, 4, 27, 2),
212         true);
213 }
214
215 TEST(reshape_gpu_i32, basic_4dim_in_place)
216 {
217     generic_reshape_test<int32_t>(
218         format::yxfb,
219         tensor(9, 9, 2, 4),
220         tensor(3, 4, 27, 2),
221         true);
222 }
223
224 TEST(reshape_gpu_i64, basic_4dim_in_place)
225 {
226     generic_reshape_test<int64_t>(
227         format::yxfb,
228         tensor(9, 9, 2, 4),
229         tensor(3, 4, 27, 2),
230         true);
231 }
232
233 TEST(reshpape_gpu_f32, basic_2dim_output_padd)
234 {
235     generic_reshape_test<float>(
236         format::byxf,
237         tensor(1, 1, 4, 2),
238         tensor(1, 1, 8, 1),
239         false,
240         padding(),
241         padding(std::vector<int>{ 0,0,1,1 })
242         );
243 }
244
245 TEST(reshape_gpu_f16, basic_2dim_output_padd)
246 {
247     generic_reshape_test<FLOAT16>(
248         format::byxf,
249         tensor(1, 1, 3, 4),
250         tensor(1, 1, 2, 6),
251         false,
252         padding(),
253         padding(std::vector<int>{ 0,0,2,2 })
254         );
255 }
256
257 TEST(reshape_gpu_i8, basic_2dim_output_padd)
258 {
259     generic_reshape_test<int8_t>(
260         format::byxf,
261         tensor(1, 1, 3, 4),
262         tensor(1, 1, 2, 6),
263         false,
264         padding(),
265         padding(std::vector<int>{ 0, 0, 2, 2 })
266         );
267 }
268
269 TEST(reshape_gpu_i32, basic_2dim_output_padd)
270 {
271     generic_reshape_test<int32_t>(
272         format::byxf,
273         tensor(1, 1, 3, 4),
274         tensor(1, 1, 2, 6),
275         false,
276         padding(),
277         padding(std::vector<int>{ 0, 0, 2, 2 })
278         );
279 }
280
281 TEST(reshape_gpu_i64, basic_2dim_output_padd)
282 {
283     generic_reshape_test<int64_t>(
284         format::byxf,
285         tensor(1, 1, 3, 4),
286         tensor(1, 1, 2, 6),
287         false,
288         padding(),
289         padding(std::vector<int>{ 0, 0, 2, 2 })
290         );
291 }
292
293 TEST(reshape_gpu_f32, basic_2dim_input_padd)
294 {
295     generic_reshape_test<float>(
296         format::fyxb,
297         tensor(1, 1, 2, 5),
298         tensor(1, 1, 5, 2),
299         false,
300         padding({ 0,0,3,2 }, { 0,0,1,4 })
301         );
302 }
303
304 TEST(reshape_gpu_f16, basic_2dim_input_padd)
305 {
306     generic_reshape_test<FLOAT16>(
307         format::fyxb,
308         tensor(1, 1, 3, 3),
309         tensor(1, 1, 1, 9),
310         false,
311         padding({ 0,0,4,1 }, { 0,0,2,3 })
312         );
313 }
314
315 TEST(reshape_gpu_i8, basic_2dim_input_padd)
316 {
317     generic_reshape_test<int8_t>(
318         format::fyxb,
319         tensor(1, 1, 3, 3),
320         tensor(1, 1, 1, 9),
321         false,
322         padding({ 0,0,4,1 }, { 0,0,2,3 })
323         );
324 }
325
326 TEST(reshape_gpu_i32, basic_2dim_input_padd)
327 {
328     generic_reshape_test<int32_t>(
329         format::fyxb,
330         tensor(1, 1, 3, 3),
331         tensor(1, 1, 1, 9),
332         false,
333         padding({ 0,0,4,1 }, { 0,0,2,3 })
334         );
335 }
336
337 TEST(reshape_gpu_i64, basic_2dim_input_padd)
338 {
339     generic_reshape_test<int64_t>(
340         format::fyxb,
341         tensor(1, 1, 3, 3),
342         tensor(1, 1, 1, 9),
343         false,
344         padding({ 0,0,4,1 }, { 0,0,2,3 })
345         );
346 }
347
348 TEST(reshape_gpu_f32, basic_2dim_input_output_padd)
349 {
350     generic_reshape_test<float>(
351         format::byxf,
352         tensor(1, 1, 5, 7),
353         tensor(1, 1, 7, 5),
354         false,
355         padding({ 0,0,4,4 }, { 0,0,1,1 }),
356         padding({ 0,0,0,0 }, { 0,0,3,0 })
357         );
358 }
359
360 TEST(reshape_gpu_f16, basic_2dim_input_output_padd)
361 {
362     generic_reshape_test<FLOAT16>(
363         format::byxf,
364         tensor(1, 1, 6, 6),
365         tensor(1, 1, 3, 12),
366         false,
367         padding({ 0,0,1,1 }, { 0,0,0,0 }),
368         padding({ 0,0,2,1 }, { 0,0,1,2 })
369         );
370 }
371
372 TEST(reshape_gpu_i8, basic_2dim_input_output_padd)
373 {
374     generic_reshape_test<int8_t>(
375         format::byxf,
376         tensor(1, 1, 5, 7),
377         tensor(1, 1, 7, 5),
378         false,
379         padding({ 0,0,4,4 }, { 0,0,1,1 }),
380         padding({ 0,0,0,0 }, { 0,0,3,0 })
381         );
382 }
383
384 TEST(reshape_gpu_i32, basic_2dim_input_output_padd)
385 {
386     generic_reshape_test<int32_t>(
387         format::byxf,
388         tensor(1, 1, 5, 7),
389         tensor(1, 1, 7, 5),
390         false,
391         padding({ 0,0,4,4 }, { 0,0,1,1 }),
392         padding({ 0,0,0,0 }, { 0,0,3,0 })
393         );
394 }
395
396 TEST(reshape_gpu_i64, basic_2dim_input_output_padd)
397 {
398     generic_reshape_test<int64_t>(
399         format::byxf,
400         tensor(1, 1, 5, 7),
401         tensor(1, 1, 7, 5),
402         false,
403         padding({ 0,0,4,4 }, { 0,0,1,1 }),
404         padding({ 0,0,0,0 }, { 0,0,3,0 })
405         );
406 }
407
408 TEST(reshpape_gpu_f32, basic_4dim_output_padd)
409 {
410     generic_reshape_test<float>(
411         format::bfyx,
412         tensor(2, 5, 7, 3),
413         tensor(1, 14, 15, 1),
414         false,
415         padding(),
416         padding({ 1,0,0,1 },{ 0,2,3,0 })
417         );
418 }
419
420 TEST(reshape_gpu_f16, basic_4dim_output_padd)
421 {
422     generic_reshape_test<FLOAT16>(
423         format::bfyx,
424         tensor(5, 4, 2, 2),
425         tensor(40, 2, 1, 1),
426         false,
427         padding(),
428         padding({ 0,2,0,1 },{ 0,2,3,0 })
429         );
430 }
431
432 TEST(reshape_gpu_f32, basic_4dim_input_padd)
433 {
434     generic_reshape_test<float>(
435         format::yxfb,
436         tensor(8, 128, 3, 3),
437         tensor(16, 8, 8, 9),
438         false,
439         padding({ 0,1,3,3}, { 0,1,1,1 })
440         );
441 }
442
443 TEST(reshape_gpu_f16, basic_4dim_input_padd)
444 {
445     generic_reshape_test<FLOAT16>(
446         format::yxfb,
447         tensor(2, 32, 8, 8),
448         tensor(8, 128, 1, 4),
449         false,
450         padding({ 2,2,1,0 }, { 1,2,2,0 })
451         );
452 }
453
454 TEST(reshape_gpu_f32, basic_4dim_input_output_padd)
455 {
456     generic_reshape_test<float>(
457         format::fyxb,
458         tensor(8, 1024, 25, 25),
459         tensor(8, 64, 100, 100),
460         false,
461         padding({ 2,0,2,1 }, { 0,1,4,0 }),
462         padding({ 1,2,3,4 }, { 0,4,1,1 })
463         );
464 }
465
466 TEST(reshape_gpu_f16, basic_4dim_input_output_padd)
467 {
468     generic_reshape_test<FLOAT16>(
469         format::byxf,
470         tensor(32, 3, 227, 227),
471         tensor(8, 12, 227, 227),
472         false,
473         padding({ 0,1,4,4 }, { 0,1,1,1 }),
474         padding({ 0,29,29,0 }, { 0,0,0,0 })
475         );
476 }
477
478 TEST(reshape_gpu_f32, multiple_users_with_reorder) {
479     // Tests split with crop implementation
480     //                                                   _ REORDER(yxfb) --> RELU(yxfb)
481     //                                                  |
482     //  INPUT(bfyx,2x2x1x1)--RELU(bfyx)--RESHAPE(4x1x1x1)  
483     //                                                  |_
484     //                                                     RELU(bfyx)
485
486     //  Input:
487     //  b0f0: -1.0
488     //  b0f1:  2.0
489     //  b1f0: -3.0
490     //  b1f1:  4.0
491
492     //  Out1:
493     //  b0f0:  0.0
494     //  b0f1:  0.0
495     //  b1f0:  2.0
496     //  b1f1:  4.0
497
498     //  Out2:
499     //  b0f0:  0.0
500     //  b0f1:  2.0
501     //  b1f0:  0.0
502     //  b1f1:  4.0
503
504     const auto& engine = get_test_engine();
505     auto batch_num = 2;
506     auto feature_num = 2;
507     auto x_size = 1;
508     auto y_size = 1;
509     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num)) } });
510
511     topology topology;
512     topology.add(input_layout("input", input.get_layout()));
513     topology.add(activation("relu", "input", activation_relu));
514     topology.add(reshape("reshape", "relu", tensor(batch(4))));
515     topology.add(reorder("reorder1", "reshape", format::yxfb, data_types::f32));
516     topology.add(activation("relu1", "reorder1", activation_relu));
517     topology.add(activation("relu2", "reshape", activation_relu));
518
519     std::vector<float> input_vec = { -1.f, 2.f, -3.f, 4.f };
520     std::vector<float> out1 = { 0.f, 0.f, 2.f, 4.0f };
521     std::vector<float> out2 = { 0.f, 2.f, 0.f, 4.0f };
522     set_values(input, input_vec);
523
524     network network(engine, topology);
525     network.set_input_data("input", input);
526     auto outputs = network.execute();
527
528     auto output = outputs.at("relu1").get_memory();
529     auto output_ptr = output.pointer<float>();
530
531     for (size_t i = 0; i < out1.size(); i++)
532         EXPECT_EQ(output_ptr[i], out1[i]);
533
534     auto output_2 = outputs.at("relu2").get_memory();
535     auto output_ptr_2 = output_2.pointer<float>();
536
537     for (size_t i = 0; i < out2.size(); i++)
538         EXPECT_EQ(output_ptr_2[i], out2[i]);
539 }
540
541 TEST(reshape_gpu_f32, calc_output_shape) {
542
543     //  INPUT(bfyx,2x2x1x1) -- RESHAPE(1, 1, 0, -1)  
544
545     //  Input:
546     //  b0f0: -1.0
547     //  b0f1:  2.0
548     //  b1f0: -3.0
549     //  b1f1:  4.0
550     //
551     // output_shape (1, 1, 1, 4)
552
553     const auto& engine = get_test_engine();
554
555     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 2, 1, 1 } });
556
557     topology topology;
558     topology.add(input_layout("input", input.get_layout()));
559     topology.add(reshape("reshape", "input", tensor(1, 1, 0, -1)));
560
561     set_values(input, { -1.f, 2.f, -3.f, 4.f });
562
563     network network(engine, topology);
564     network.set_input_data("input", input);
565     auto outputs = network.execute();
566
567     EXPECT_EQ(outputs.size(), size_t(1));
568     EXPECT_EQ(outputs.begin()->first, "reshape");
569
570     auto output = outputs.at("reshape").get_memory();
571
572     EXPECT_TRUE(output.get_layout().data_type == input.get_layout().data_type);
573     EXPECT_TRUE(output.get_layout().format == input.get_layout().format);
574
575     ASSERT_TRUE(output.get_layout().size == tensor(1, 1, 1, 4));
576
577     float answers[4] = { -1.f, 2.f, -3.f, 4.f };
578
579     auto output_ptr = output.pointer<float>();
580     for (int i = 0; i < 4; i++)
581     {
582         EXPECT_TRUE(are_equal(answers[i], output_ptr[i]));
583     }
584 }