Publishing R3
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / deconvolution_gpu_test.cpp
1 /*
2 // Copyright (c) 2016 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
19 #include <gtest/gtest.h>
20 #include "api/CPP/memory.hpp"
21 #include <api/CPP/input_layout.hpp>
22 #include "api/CPP/deconvolution.hpp"
23 #include <api/CPP/data.hpp>
24 #include <api/CPP/topology.hpp>
25 #include <api/CPP/network.hpp>
26 #include <api/CPP/engine.hpp>
27 #include "test_utils/test_utils.h"
28 #include "test_utils/float16.h"
29 #include "api/CPP/reorder.hpp"
30
31
32 using namespace cldnn;
33 using namespace tests;
34
35 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x1_nopad) {
36     //  Filter : 2x2
37     //  Input  : 2x2
38     //  Output : 3x3
39     //
40     //  Input:
41     //  8  0.5
42     //  6  9
43     //
44     //  Filter
45     //  -2   0.5
46     //   3.5 1.5
47     //
48     //  Bias
49     //  2
50     //
51     //  Output:
52     //  -14    5     2.25 
53     //   18    0.75  7.25   
54     //   23    42.5  15.5   
55
56     engine engine;
57
58     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
59     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
60     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
61
62     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
63     set_values(weights, { -2.0f, 0.5f, 3.5f, 1.5f });
64     set_values(biases, { 2.0f });
65
66     topology topology(
67         input_layout("input", input.get_layout()),
68         data("weights", weights),
69         data("biases", biases),
70         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1,1,1,1 })
71     );
72
73     network network(engine, topology);
74     network.set_input_data("input", input);
75
76     auto outputs = network.execute();
77     EXPECT_EQ(outputs.size(), size_t(1));
78     EXPECT_EQ(outputs.begin()->first, "deconv");
79
80     auto output_prim = outputs.begin()->second.get_memory();
81
82     auto output_ptr = output_prim.pointer<float>();
83
84     std::vector<float> expected_output_vec = {
85         -14.f, 5.f, 2.25f,
86         18.f, 0.75f, 7.25f,
87         23.f, 42.5f, 15.5f
88     };
89
90     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
91     {
92         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
93     }
94 }
95
96
97 TEST(deconvolution_f32_fw_gpu, no_bias_basic_wsiz2x2_in2x2x1x1_nopad) {
98     //  Filter : 2x2
99     //  Input  : 2x2
100     //  Output : 3x3
101     //
102     //  Input:
103     //  8  0.5
104     //  6  9
105     //
106     //  Filter
107     //  -2   0.5
108     //   3.5 1.5
109     //
110     //  no bias
111     //  
112     //
113     //  Output:
114     //  -14    5     2.25 
115     //   18    0.75  7.25   
116     //   23    42.5  15.5   
117
118     engine engine;
119
120     auto input = memory::allocate(engine, { data_types::f32, format::yxfb,{ 1, 1, 2, 2 } });
121     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb,{ 1, 1, 2, 2 } });
122
123     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
124     set_values(weights, { -2.0f, 0.5f, 3.5f, 1.5f });
125
126     topology topology(
127         input_layout("input", input.get_layout()),
128         data("weights", weights),
129         deconvolution("deconv", "input", { "weights" })
130     );
131
132     network network(engine, topology);
133     network.set_input_data("input", input);
134
135     auto outputs = network.execute();
136     EXPECT_EQ(outputs.size(), size_t(1));
137     EXPECT_EQ(outputs.begin()->first, "deconv");
138
139     auto output_prim = outputs.begin()->second.get_memory();
140
141     auto output_ptr = output_prim.pointer<float>();
142
143     std::vector<float> expected_output_vec = {
144         -16.f, 3.f, 0.25f,
145         16.f, -1.25f, 5.25f,
146         21.f, 40.5f, 13.5f
147     };
148
149     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
150     {
151         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
152     }
153 }
154
155
156 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x1_nopad_bfyx) {    //  Filter : 2x2
157     //  Input  : 2x2
158     //  Output : 3x3
159     //
160     //  Input:
161     //  8  0.5
162     //  6  9
163     //
164     //  Filter
165     //  -2   0.5
166     //   3.5 1.5
167     //
168     //  Bias
169     //  2
170     //
171     //  Output:
172     //  -14    5     2.25 
173     //   18    0.75  7.25   
174     //   23    42.5  15.5   
175
176     engine engine;
177
178     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
179     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 2, 2 } });
180     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
181
182     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
183     set_values(weights, { -2.0f, 0.5f, 3.5f, 1.5f });
184     set_values(biases, { 2.0f });
185
186     topology topology(
187         input_layout("input", input.get_layout()),
188         data("weights", weights),
189         data("biases", biases),
190         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1,1,1,1 })
191     );
192
193     network network(engine, topology);
194     network.set_input_data("input", input);
195
196     auto outputs = network.execute();
197     EXPECT_EQ(outputs.size(), size_t(1));
198     EXPECT_EQ(outputs.begin()->first, "deconv");
199
200     auto output_prim = outputs.begin()->second.get_memory();
201
202     auto output_ptr = output_prim.pointer<float>();
203
204     std::vector<float> expected_output_vec = {
205         -14.f, 5.f, 2.25f,
206         18.f, 0.75f, 7.25f,
207         23.f, 42.5f, 15.5f
208     };
209
210     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
211     {
212         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
213     }
214 }
215
216 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x1_pad1) {
217     //  Filter : 2x2
218     //  Input  : 2x2
219     //  Output : 1x1
220     //  Pad    : 1x1
221     //
222     //  Input:
223     //  8  0.5
224     //  6  9
225     //
226     //  Filter
227     //  -2   0.5
228     //   3.5 1.5
229     //
230     //  Bias
231     //  2
232     //
233     //  Output:
234     //  0.75  
235
236     engine engine;
237
238     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
239     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
240     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
241
242     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
243     set_values(weights, { -2.0f, 0.5f, 3.5f, 1.5f });
244     set_values(biases, { 2.0f });
245
246     topology topology(
247         input_layout("input", input.get_layout()),
248         data("weights", weights),
249         data("biases", biases),
250         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 1, 1 }, { 0, 0, -1, -1 })
251     );
252
253     network network(engine, topology);
254     network.set_input_data("input", input);
255
256     auto outputs = network.execute();
257     EXPECT_EQ(outputs.size(), size_t(1));
258     EXPECT_EQ(outputs.begin()->first, "deconv");
259
260     auto output_prim = outputs.begin()->second.get_memory();
261
262     auto output_ptr = output_prim.pointer<float>();
263
264     EXPECT_FLOAT_EQ(0.75f, output_ptr[0]);
265 }
266
267 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x1_stride2_nopad) {
268     //  Filter : 2x2
269     //  Input  : 2x2
270     //  Output : 1x1
271     //  Stride : 2x2
272     //
273     //  Input:
274     //  8  0.5
275     //  6  9
276     //
277     //  Filter
278     //  -2   0.5
279     //   3.5 1.5
280     //
281     //  Bias
282     //  1
283     //
284     //  Output:
285     //  0.75  
286
287     engine engine;
288
289     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
290     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
291     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
292
293     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
294     set_values(weights, { -2.0f, 0.5f, 3.5f, 1.5f });
295     set_values(biases, { 1.0f });
296
297     topology topology(
298         input_layout("input", input.get_layout()),
299         data("weights", weights),
300         data("biases", biases),
301         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1,1,2,2 })
302     );
303
304     network network(engine, topology);
305     network.set_input_data("input", input);
306
307     auto outputs = network.execute();
308     EXPECT_EQ(outputs.size(), size_t(1));
309     EXPECT_EQ(outputs.begin()->first, "deconv");
310
311     auto output_prim = outputs.begin()->second.get_memory();
312
313     auto output_ptr = output_prim.pointer<float>();
314
315     std::vector<float> expected_output_vec = {
316         -15.f, 5.f, 0.f, 1.25f,
317         29.f, 13.f, 2.75f, 1.75,
318         -11.f, 4.f, -17.f, 5.5f,
319         22.f, 10.f, 32.5f, 14.5f
320     };
321
322     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
323     {
324         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
325     }
326 }
327
328 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x1_stride4_pad2) {
329     //  Filter : 3x3
330     //  Input  : 2x2
331     //  Output : 1x1
332     //  Stride : 4x4
333     //  Pad    : 2x2
334     //
335     //  Input:
336     //  8  0.5
337     //  6  9
338     //
339     //  Filter
340     //  -2   0.5   1
341     //   3.5 1.5   2
342     //   3   4     5
343     //
344     //  Bias
345     //  0
346     //
347     //  Output:
348     //  40   0    1.5
349     //  0    0    0
350     //  6    0   -18
351
352     engine engine;
353
354     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
355     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 3, 3 } });
356     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
357
358     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
359     set_values(weights, { -2.0f, 0.5f, 1.f, 3.5f, 1.5f, 2.f, 3.f, 4.f, 5.f });
360     set_values(biases, { 0.0f });
361
362     topology topology(
363         input_layout("input", input.get_layout()),
364         data("weights", weights),
365         data("biases", biases),
366         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 4, 4 }, { 0, 0, -2, -2 })
367     );
368
369     network network(engine, topology);
370     network.set_input_data("input", input);
371
372     auto outputs = network.execute();
373     EXPECT_EQ(outputs.size(), size_t(1));
374     EXPECT_EQ(outputs.begin()->first, "deconv");
375
376     auto output_prim = outputs.begin()->second.get_memory();
377
378     auto output_ptr = output_prim.pointer<float>();
379
380     std::vector<float> expected_output_vec = {
381         40.f, 0.f, 1.5f,
382         0.f, 0.f, 0.f,
383         6.f, 0.f, -18.f
384     };
385
386     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
387     {
388         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
389     }
390 }
391
392 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x2_stride2_pad1) {
393     //  Filter : 2x2
394     //  Input  : 2x2x1x2
395     //  Output : 2x2x1x2
396     //  Stride : 2x2
397     //  Pad    : 1x1
398     //
399     //  Input:
400     //  8  0.5    1   3
401     //  6  9      2   4
402     //
403     //  Filter
404     //  -2   2
405     //   7  -0.5
406     //
407     //  Bias
408     //  1
409     //
410     //  Output:
411     //  -3    4.5    0.5   22
412     //   13  -17     5    -7
413
414     engine engine;
415
416     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 2, 1, 2, 2 } });
417     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
418     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
419
420     set_values(input, { 8.f, 1.f, 0.5f, 3.f, 6.f, 2.f, 9.f, 4.f });
421     set_values(weights, { -2.f, 2.f, 7.f, -0.5f });
422     set_values(biases, { 1.0f });
423
424     topology topology(
425         input_layout("input", input.get_layout()),
426         data("weights", weights),
427         data("biases", biases),
428         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
429     );
430
431     network network(engine, topology);
432     network.set_input_data("input", input);
433
434     auto outputs = network.execute();
435     EXPECT_EQ(outputs.size(), size_t(1));
436     EXPECT_EQ(outputs.begin()->first, "deconv");
437
438     auto output_prim = outputs.begin()->second.get_memory();
439
440     auto output_ptr = output_prim.pointer<float>();
441
442     std::vector<float> expected_output_vec = {
443         -3.f, 0.5f, 4.5f, 22.f,
444         13.f, 5.f, -17.f, -7.f
445     };
446
447     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
448     {
449         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
450     }
451 }
452
453 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2x2_in2x2x1x1_stride2_pad1) {
454     //  Filter : 2x2
455     //  Input  : 2x2x1x1
456     //  Output : 2x2x1x1
457     //  Stride : 2x2
458     //  Pad    : 1x1
459     //
460     //  Input:
461     //  8  0.5
462     //  6  9
463     //
464     //  Filter
465     //  f0:-2   2
466     //  f0: 7  -0.5
467     //  f1:-2   2
468     //  f1: 7  -0.5
469     //
470     //  Bias
471     //  1  5
472     //
473     //  Output:
474     //  f0: -3   4.5 
475     //  f0: 13   -17 
476     //  f1: 1    8.5
477     //  f1: 17 - 13
478
479     engine engine;
480
481     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
482     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 2, 1, 2, 2 } });
483     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 2, 1 } });
484
485     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
486     set_values(weights, { -2.f, -2.f, 2.f, 2.f, 7.f, 7.f, -0.5f, -0.5f });
487     set_values(biases, { 1.0f, 5.0f });
488
489     topology topology(
490         input_layout("input", input.get_layout()),
491         data("weights", weights),
492         data("biases", biases),
493         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
494     );
495
496     network network(engine, topology);
497     network.set_input_data("input", input);
498
499     auto outputs = network.execute();
500     EXPECT_EQ(outputs.size(), size_t(1));
501     EXPECT_EQ(outputs.begin()->first, "deconv");
502
503     auto output_prim = outputs.begin()->second.get_memory();
504
505     auto output_ptr = output_prim.pointer<float>();
506
507     std::vector<float> expected_output_vec = {
508         -3.f, 1.f, 4.5f, 8.5f,
509         13.f, 17.f, -17.f, -13.f
510     };
511
512     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
513     {
514         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
515     }
516 }
517
518 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x2_bfyx_stride2_pad1) {
519     //  Filter : 2x2
520     //  Input  : 2x2x1x2
521     //  Output : 2x2x1x2
522     //  Stride : 2x2
523     //  Pad    : 1x1
524     //
525     //  Input:
526     //  8  0.5    1   3
527     //  6  9      2   4
528     //
529     //  Filter
530     //  -2   2
531     //   7  -0.5
532     //
533     //  Bias
534     //  1
535     //
536     //  Output:
537     //  -3    4.5    0.5   22
538     //   13  -17     5    -7
539
540     engine engine;
541
542     auto input = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 1, 2, 2 } });
543     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 2, 2 } });
544     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
545
546     set_values(input, { 8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f });
547     set_values(weights, { -2.f, 2.f, 7.f, -0.5f });
548     set_values(biases, { 1.0f });
549
550     topology topology(
551         input_layout("input", input.get_layout()),
552         data("weights", weights),
553         data("biases", biases),
554         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
555     );
556
557     network network(engine, topology);
558     network.set_input_data("input", input);
559
560     auto outputs = network.execute();
561     EXPECT_EQ(outputs.size(), size_t(1));
562     EXPECT_EQ(outputs.begin()->first, "deconv");
563
564     auto output_prim = outputs.begin()->second.get_memory();
565
566     auto output_ptr = output_prim.pointer<float>();
567
568     std::vector<float> expected_output_vec = {
569         -3.f, 4.5f, 13.f, -17.f,
570         .5f, 22.f, 5.f, -7.f
571     };
572
573     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
574     {
575         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
576     }
577 }
578
579 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x2_bfyx_stride2_pad1_input_padding) {
580     //  Filter : 2x2
581     //  Input  : 2x2x1x2
582     //  Output : 2x2x1x2
583     //  Stride : 2x2
584     //  Out Padding   : 1x1
585     //  Input Padding : 2x1 (with reorder)
586     //
587     //  Input:
588     //  8  0.5    1   3
589     //  6  9      2   4
590     //
591     //  Filter
592     //  -2   2
593     //   7  -0.5
594     //
595     //  Bias
596     //  1
597     //
598     //  Output:
599     //  -3    4.5    0.5   22
600     //   13  -17     5    -7
601
602     engine engine;
603
604     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 1, 2, 2 } });
605     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 2 } });
606     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 1, 1 } });
607
608     set_values(input, { 8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f });
609     set_values(weights, { -2.f, 2.f, 7.f, -0.5f });
610     set_values(biases, { 1.0f });
611
612     topology topology(
613         input_layout("input", input.get_layout()),
614         reorder("reorder", "input", input.get_layout().with_padding({ { 0, 0, 1, 2 }, 0 })),
615         data("weights", weights),
616         data("biases", biases),
617         deconvolution("deconv", "reorder", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
618     );
619
620     network network(engine, topology);
621     network.set_input_data("input", input);
622
623     auto outputs = network.execute();
624     EXPECT_EQ(outputs.size(), size_t(1));
625     EXPECT_EQ(outputs.begin()->first, "deconv");
626
627     auto output_prim = outputs.begin()->second.get_memory();
628
629     auto output_ptr = output_prim.pointer<float>();
630
631     std::vector<float> expected_output_vec = {
632         -3.f, 4.5f, 13.f, -17.f,
633         .5f, 22.f, 5.f, -7.f
634     };
635
636     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
637     {
638         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
639     }
640 }
641
642 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2x2_in2x2x1x1_stride2_pad1_input_padding) {
643     //  Filter : 2x2
644     //  Input  : 2x2x1x1
645     //  Output : 2x2x1x1
646     //  Stride : 2x2
647     //  Out Padding   : 1x1
648     //  Input Padding : 2x1 (with reorder)
649     //
650     //  Input:
651     //  8  0.5
652     //  6  9
653     //
654     //  Filter
655     //  f0:-2   2
656     //  f0: 7  -0.5
657     //  f1:-2   2
658     //  f1: 7  -0.5
659     //
660     //  Bias
661     //  1  5
662     //
663     //  Output:
664     //  f0: -3   4.5 
665     //  f0: 13   -17 
666     //  f1: 1    8.5
667     //  f1: 17 - 13
668
669     engine engine;
670
671     auto input = memory::allocate(engine, { data_types::f32, format::yxfb,{ 1, 1, 2, 2 } });
672     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb,{ 2, 1, 2, 2 } });
673     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 1 } });
674
675     set_values(input, { 8.f, 0.5f, 6.f, 9.f });
676     set_values(weights, { -2.f, -2.f, 2.f, 2.f, 7.f, 7.f, -0.5f, -0.5f });
677     set_values(biases, { 1.0f, 5.0f });
678
679     topology topology(
680         input_layout("input", input.get_layout()),
681         reorder("reorder", "input", input.get_layout().with_padding({ { 0, 0, 1, 2 }, 0 })),
682         data("weights", weights),
683         data("biases", biases),
684         deconvolution("deconv", "reorder", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
685     );
686
687     network network(engine, topology);
688     network.set_input_data("input", input);
689
690     auto outputs = network.execute();
691     EXPECT_EQ(outputs.size(), size_t(1));
692     EXPECT_EQ(outputs.begin()->first, "deconv");
693
694     auto output_prim = outputs.begin()->second.get_memory();
695
696     auto output_ptr = output_prim.pointer<float>();
697
698     std::vector<float> expected_output_vec = {
699         -3.f, 1.f, 4.5f, 8.5f,
700         13.f, 17.f, -17.f, -13.f
701     };
702
703     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
704     {
705         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
706     }
707 }
708
709 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in2x2x1x2_bfyx_yxfb_stride2_pad1) {
710     //  Filter : 2x2
711     //  Input  : 2x2x1x2
712     //  Output : 2x2x1x2
713     //  Stride : 2x2
714     //  Pad    : 1x1
715     //
716     //  Input:
717     //  8  0.5    1   3
718     //  6  9      2   4
719     //
720     //  Filter
721     //  -2   2
722     //   7  -0.5
723     //
724     //  Bias
725     //  1
726     //
727     //  Output:
728     //  -3    4.5    0.5   22
729     //   13  -17     5    -7
730
731     engine engine;
732
733     auto input = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 1, 2, 2 } });
734     auto weights = memory::allocate(engine, { data_types::f32, format::yxfb, { 1, 1, 2, 2 } });
735     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx, { 1, 1, 1, 1 } });
736
737     set_values(input, { 8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f });
738     set_values(weights, { -2.f, 2.f, 7.f, -0.5f });
739     set_values(biases, { 1.0f });
740
741     topology topology(
742         input_layout("input", input.get_layout()),
743         data("weights", weights),
744         data("biases", biases),
745         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
746     );
747
748     network network(engine, topology);
749     network.set_input_data("input", input);
750
751     auto outputs = network.execute();
752     EXPECT_EQ(outputs.size(), size_t(1));
753     EXPECT_EQ(outputs.begin()->first, "deconv");
754
755     auto output_prim = outputs.begin()->second.get_memory();
756
757     auto output_ptr = output_prim.pointer<float>();
758
759     std::vector<float> expected_output_vec = {
760         -3.f, 4.5f, 13.f, -17.f,
761         .5f, 22.f, 5.f, -7.f
762     };
763
764     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
765     {
766         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
767     }
768 }
769
770 TEST(deconvolution_f16_fw_gpu, basic_wsiz2x2_in2x2x1x2_bfyx_yxfb_stride2_pad1) {
771     //  Filter : 2x2
772     //  Input  : 2x2x1x2
773     //  Output : 2x2x1x2
774     //  Stride : 2x2
775     //  Pad    : 1x1
776     //
777     //  Input:
778     //  8  0.5    1   3
779     //  6  9      2   4
780     //
781     //  Filter
782     //  -2   2
783     //   7  -0.5
784     //
785     //  Bias
786     //  1
787     //
788     //  Output:
789     //  -3    4.5    0.5   22
790     //   13  -17     5    -7
791
792     engine engine;
793
794     auto input = memory::allocate(engine, { data_types::f16, format::bfyx,{ 2, 1, 2, 2 } });
795     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 2 } });
796     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 1, 1 } });
797
798     cldnn::build_options options;
799     options.set_option(cldnn::build_option::optimize_data(true));
800
801     set_values(input, { FLOAT16(8.f), FLOAT16(0.5f), FLOAT16(6.f), FLOAT16(9.f),
802         FLOAT16(1.f), FLOAT16(3.f), FLOAT16(2.f), FLOAT16(4.f) });
803     set_values(weights, { -2.f, 2.f, 7.f, -0.5f});
804     set_values(biases, { 1.0f });
805
806     topology topology(
807         input_layout("input", input.get_layout()),
808         data("weights", weights),
809         data("biases", biases),
810         deconvolution("deconv", "input", { "weights" }, { "biases" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
811     );
812
813     network network(engine, topology, options);
814     network.set_input_data("input", input);
815
816     auto outputs = network.execute();
817     EXPECT_EQ(outputs.size(), size_t(1));
818     EXPECT_EQ(outputs.begin()->first, "deconv");
819
820     auto output_prim = outputs.begin()->second.get_memory();
821
822     auto output_ptr = output_prim.pointer<uint16_t>();
823
824     std::vector<float> expected_output_vec = {
825         -3.f, 4.5f, 13.f, -17.f,
826         .5f, 22.f, 5.f, -7.f
827     };
828
829     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
830     {
831         EXPECT_FLOAT_EQ(expected_output_vec[i], float16_to_float32(output_ptr[i]));
832     }
833 }
834
835 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in1x2x2x2_bfyx_stride2_pad1_split2) {
836     //  Filter : 2x2x2x2
837     //  Input  : 2x2x1x2
838     //  Output : 2x2x1x2
839     //  Stride : 2x2
840     //  Pad    : 1x1
841     //
842     //  Input:
843     //  8  0.5    1   3
844     //  6  9      2   4
845     //
846     //  Filter1
847     //  -2   2
848     //   7  -0.5
849     //
850     //  Bias
851     //  1
852     //
853     //  Filter2
854     //  -4   1
855     //  -9  -7
856     //
857     //  Bias
858     //  -1
859     //
860     //  Output:
861     //  -3    4.5    -8   -28
862     //   13  -17     1    -17
863
864     engine engine;
865
866     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 2, 2, 2 } });
867     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 2 } });
868     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 1, 1 } });
869     auto weights2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 2 } });
870     auto biases2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 1, 1 } });
871
872     set_values(input, { 8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f });
873     set_values(weights, { -2.f, 2.f, 7.f, -0.5f });
874     set_values(biases, { 1.0f });
875     set_values(weights2, { -4.f, 1.f, -9.f, -7.f });
876     set_values(biases2, { -1.0f });
877
878     topology topology(
879         input_layout("input", input.get_layout()),
880         data("weights", weights),
881         data("biases", biases),
882         data("weights2", weights2),
883         data("biases2", biases2),
884         deconvolution("deconv", "input", { "weights", "weights2" }, { "biases", "biases2" }, { 1, 1, 2, 2 }, { 0, 0, -1, -1 })
885     );
886
887     network network(engine, topology);
888     network.set_input_data("input", input);
889
890     auto outputs = network.execute();
891     EXPECT_EQ(outputs.size(), size_t(1));
892     EXPECT_EQ(outputs.begin()->first, "deconv");
893
894     auto output_prim = outputs.begin()->second.get_memory();
895
896     auto output_ptr = output_prim.pointer<float>();
897
898     std::vector<float> expected_output_vec = {
899         -3.f, 4.5f, 13.f, -17.f,
900         -8.f, -28.f, 1.f, -17.f
901     };
902
903     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
904     {
905         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
906     }
907 }
908
909 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in1x2x2x2_bfyx_stride2_pad1_split2_depthwise_sep_opt) {
910     //  Test for depthwise separable optimization, there are 16 weights and biases (split 16)
911     //  data is similar as in basic_wsiz2x2_in1x2x2x2_bfyx_stride2_pad1_split2
912
913     engine engine; 
914
915     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 16, 2, 2 } });
916     set_values(input, 
917     { 8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f, 
918         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
919         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
920         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
921         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
922         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
923         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
924         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f
925     });
926
927     topology topology(input_layout("input", input.get_layout()));
928
929     std::vector<primitive_id> weights_vec;
930     std::vector<primitive_id> bias_vec;
931
932     for (uint32_t i = 0; i < 8; i++)
933     {
934         auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 2 } });
935         auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 1, 1 } });
936         auto weights2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 2 } });
937         auto biases2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 1, 1 } });
938
939         set_values(weights, { -2.f, 2.f, 7.f, -0.5f });
940         set_values(biases, { 1.0f });
941         set_values(weights2, { -4.f, 1.f, -9.f, -7.f });
942         set_values(biases2, { -1.0f });
943
944         primitive_id weights_id = "weights_" + std::to_string(i);
945         primitive_id weights2_id = "weights2_" + std::to_string(i);
946         primitive_id bias_id = "biases_" + std::to_string(i);
947         primitive_id bias2_id = "biases2_" + std::to_string(i);
948
949         weights_vec.push_back(weights_id);
950         weights_vec.push_back(weights2_id);
951         bias_vec.push_back(bias_id);
952         bias_vec.push_back(bias2_id);
953
954         topology.add(
955             data(weights_id, weights),
956             data(bias_id, biases),
957             data(weights2_id, weights2),
958             data(bias2_id, biases2)
959             );
960     }
961
962     topology.add(deconvolution("deconv", "input", weights_vec, bias_vec, { 1, 1, 2, 2 }, { 0, 0, -1, -1 }));
963
964     network network(engine, topology);
965     network.set_input_data("input", input);
966
967     auto outputs = network.execute();
968     EXPECT_EQ(outputs.size(), size_t(1));
969     EXPECT_EQ(outputs.begin()->first, "deconv");
970
971     auto output_prim = outputs.begin()->second.get_memory();
972
973     auto output_ptr = output_prim.pointer<float>();
974
975     std::vector<float> expected_output_vec = {
976         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
977         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
978         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
979         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
980         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
981         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
982         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
983         -3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f,
984     };
985
986     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
987     {
988         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
989     }
990 }
991
992 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in1x2x2x2_bfyx_stride2_pad1_split2_depthwise_sep_opt_ofm2) {
993     //  Test for depthwise separable optimization, there are 16 weights and biases (split 16)
994     //  data is similar as in basic_wsiz2x2_in1x2x2x2_bfyx_stride2_pad1_split2
995
996     engine engine;
997
998     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 16, 2, 2 } });
999     set_values(input,
1000     { 8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1001         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1002         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1003         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1004         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1005         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1006         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f,
1007         8.f, 0.5f, 6.f, 9.f, 1.f, 3.f, 2.f, 4.f
1008     });
1009
1010     topology topology(input_layout("input", input.get_layout()));
1011
1012     std::vector<primitive_id> weights_vec;
1013     std::vector<primitive_id> bias_vec;
1014
1015     for (uint32_t i = 0; i < 8; i++)
1016     {
1017         auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 1, 2, 2 } });
1018         auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 1 } });
1019         auto weights2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 2, 1, 2, 2 } });
1020         auto biases2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 2, 1 } });
1021
1022         set_values(weights, { -2.f, 2.f, 7.f, -0.5f, -2.f, 2.f, 7.f, -0.5f });
1023         set_values(biases, { 1.0f, 1.0f });
1024         set_values(weights2, { -4.f, 1.f, -9.f, -7.f, -4.f, 1.f, -9.f, -7.f });
1025         set_values(biases2, { -1.0f, -1.0f });
1026
1027         primitive_id weights_id = "weights_" + std::to_string(i);
1028         primitive_id weights2_id = "weights2_" + std::to_string(i);
1029         primitive_id bias_id = "biases_" + std::to_string(i);
1030         primitive_id bias2_id = "biases2_" + std::to_string(i);
1031
1032         weights_vec.push_back(weights_id);
1033         weights_vec.push_back(weights2_id);
1034         bias_vec.push_back(bias_id);
1035         bias_vec.push_back(bias2_id);
1036
1037         topology.add(
1038             data(weights_id, weights),
1039             data(bias_id, biases),
1040             data(weights2_id, weights2),
1041             data(bias2_id, biases2)
1042         );
1043     }
1044
1045     topology.add(deconvolution("deconv", "input", weights_vec, bias_vec, { 1, 1, 2, 2 }, { 0, 0, -1, -1 }));
1046
1047     network network(engine, topology);
1048     network.set_input_data("input", input);
1049
1050     auto outputs = network.execute();
1051     EXPECT_EQ(outputs.size(), size_t(1));
1052     EXPECT_EQ(outputs.begin()->first, "deconv");
1053
1054     auto output_prim = outputs.begin()->second.get_memory();
1055
1056     auto output_ptr = output_prim.pointer<float>();
1057
1058     std::vector<float> expected_output_vec = {
1059         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1060         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1061         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1062         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1063         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1064         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1065         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1066         -3.f, 4.5f, 13.f, -17.f,-3.f, 4.5f, 13.f, -17.f, -8.f, -28.f, 1.f, -17.f, -8.f, -28.f, 1.f, -17.f,
1067     };
1068
1069     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
1070     {
1071         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
1072     }
1073 }
1074
1075 TEST(deconvolution_f32_fw_gpu, basic_wsiz2x2_in1x6x1x1_bfyx_stride2_pad1_split2_ofm3) {
1076     //  Filter : 1x1
1077     //  Stride : 1x1
1078     //  Input  : 1x1x4
1079     //  Output : 1x1x6
1080     //
1081     //  Input:
1082     //  f0:  1.5
1083     //  f1:  0.5
1084     //
1085     //  f2:  2
1086     //  f3: -1.0
1087     //
1088     //  Filter1:
1089     //  -2   1   ofm=0
1090     //   1   3   ofm=1
1091     //   0.5 8   ofm=2
1092     //  Bias1:
1093     //   1   5   3
1094     //
1095     //  Filter2:
1096     //   4  -4   ofm=3
1097     //   2   0.5 ofm=4
1098     //  -0.5 3   ofm=5
1099     //
1100     //  Bias2:
1101     //  -1   2.5 2
1102     //
1103     //  Output:
1104     //  -1.5  
1105     //   8
1106     //   7.75
1107     //
1108     //   11
1109     //   6
1110     //  -2
1111
1112     engine engine;
1113
1114     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 4, 1, 1 } });
1115     auto weights = memory::allocate(engine, { data_types::f32, format::bfyx,{ 3, 2, 1, 1 } });
1116     auto biases = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 3, 1 } });
1117     auto weights2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 3, 2, 1, 1 } });
1118     auto biases2 = memory::allocate(engine, { data_types::f32, format::bfyx,{ 1, 1, 3, 1 } });
1119
1120     set_values(input, {
1121         1.5f, 0.5f, 2.0f, -1.0f
1122     });
1123     set_values(weights, { -2.0f, 1.0f, 1.0f, 3.0f, 0.5f, 8.0f });
1124     set_values(biases, { 1.0f, 5.0f, 3.0f });
1125     set_values(weights2, { 4.0f, -4.0f, 2.0f, 0.5f, -0.5f, 3.0f });
1126     set_values(biases2, { -1.0f, 2.5f, 2.0f });
1127
1128     topology topology(
1129         input_layout("input", input.get_layout()),
1130         data("weights", weights),
1131         data("biases", biases),
1132         data("weights2", weights2),
1133         data("biases2", biases2),
1134         deconvolution("deconv", "input", { "weights", "weights2" }, { "biases", "biases2" }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 })
1135     );
1136
1137     network network(engine, topology);
1138     network.set_input_data("input", input);
1139
1140     auto outputs = network.execute();
1141     EXPECT_EQ(outputs.size(), size_t(1));
1142     EXPECT_EQ(outputs.begin()->first, "deconv");
1143
1144     auto output_prim = outputs.begin()->second.get_memory();
1145
1146     auto output_ptr = output_prim.pointer<float>();
1147
1148     std::vector<float> expected_output_vec = {
1149         -1.5f, 8.0f, 7.75f, 11.0f, 6.0f, -2.0f
1150     };
1151     for (unsigned int i = 0; i < expected_output_vec.size(); i++)
1152     {
1153         EXPECT_FLOAT_EQ(expected_output_vec[i], output_ptr[i]);
1154     }
1155 }