Publishing 2019 R3 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / crop_gpu_test.cpp
1 /*
2 // Copyright (c) 2017-2019 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/memory.hpp"
20 #include <api/input_layout.hpp>
21 #include "api/crop.hpp"
22 #include <api/topology.hpp>
23 #include <api/network.hpp>
24 #include <api/engine.hpp>
25 #include "test_utils/test_utils.h"
26
27 using namespace cldnn;
28 using namespace tests;
29
30 template<typename T>
31 std::vector<T> generate_random_input(size_t b, size_t f, size_t z, size_t y, size_t x, int min, int max) {
32     static std::default_random_engine generator(random_seed);
33     int k = 8; // 1/k is the resolution of the floating point numbers
34     std::uniform_int_distribution<int> distribution(k * min, k * max);
35     std::vector<T> v(b*f*x*y*z);
36     for (size_t i = 0; i < b*f*x*y*z; ++i) {
37         v[i] = (T)distribution(generator);
38         v[i] /= k;
39     }
40     return v;
41 }
42
43 template<typename T>
44 std::vector<T> generate_random_input(size_t b, size_t f, size_t y, size_t x, int min, int max) {
45     return generate_random_input<T>(b, f, 1, y, x, -min, max);
46 }
47
48 TEST(crop_gpu, basic_in2x3x2x2_crop_all) {
49     //  Reference  : 1x2x2x2
50     //  Input      : 2x3x4x5
51     //  Output     : 1x2x2x3
52
53     const auto& engine = get_test_engine();
54
55     auto batch_num = 2;
56     auto feature_num = 3;
57     auto x_size = 4;
58     auto y_size = 5;
59
60     auto crop_batch_num = batch_num - 1;
61     auto crop_feature_num = feature_num - 1;
62     auto crop_x_size = x_size - 2;
63     auto crop_y_size = y_size - 2;
64
65     auto input = memory::allocate(engine, { data_types::f32, format::yxfb,{ batch_num, feature_num, x_size, y_size } });
66
67     topology topology;
68     topology.add(input_layout("input", input.get_layout()));
69     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, { 0, 0, 0, 0 }));
70
71     std::vector<float> input_vec = generate_random_input<float>(batch_num, feature_num, y_size, x_size, -10, 10);
72     set_values(input, input_vec);
73
74     network network(engine, topology);
75
76     network.set_input_data("input", input);
77
78     auto outputs = network.execute();
79
80     auto output = outputs.at("crop").get_memory();
81     auto output_ptr = output.pointer<float>();
82
83     for (int b = 0; b < crop_batch_num; ++b) { //B
84         for (int f = 0; f < crop_feature_num; ++f) { //F
85             for (int y = 0; y < crop_y_size; ++y) { //Y
86                 for (int x = 0; x < crop_x_size; ++x) { //X
87                     int linear_id = b + batch_num * (f + feature_num * (x + x_size * y));
88                     int output_linear_id = b + crop_batch_num * (f + crop_feature_num * (x + crop_x_size * y));
89                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
90                 }
91             }
92         }
93     }
94 }
95
96 TEST(crop_gpu, basic_in2x2x2x3_crop_all) {
97     const auto& engine = get_test_engine();
98
99     auto batch_num = 2;
100     auto feature_num = 2;
101     auto x_size = 3;
102     auto y_size = 2;
103
104     auto crop_batch_num = batch_num - 1;
105     auto crop_feature_num = feature_num - 1;
106     auto crop_x_size = x_size - 1;
107     auto crop_y_size = y_size - 1;
108
109     auto input = memory::allocate(engine, { data_types::f32, format::yxfb,{ batch_num, feature_num, x_size, y_size } });
110
111     topology topology;
112     topology.add(input_layout("input", input.get_layout()));
113     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, { 0, 0, 0, 0 }));
114
115     std::vector<float> input_vec;
116     for (int i = 0; i < batch_num * feature_num * y_size * x_size; i++)
117         input_vec.push_back(i);
118     set_values(input, input_vec);
119
120     network network(engine, topology);
121
122     network.set_input_data("input", input);
123
124     auto outputs = network.execute();
125
126     auto output = outputs.at("crop").get_memory();
127     auto output_ptr = output.pointer<float>();
128
129     printf("Results:\n");
130     for (int b = 0; b < crop_batch_num; ++b) { //B
131         for (int f = 0; f < crop_feature_num; ++f) { //F
132             for (int y = 0; y < crop_y_size; ++y) { //Y
133                 for (int x = 0; x < crop_x_size; ++x) { //X
134                     int linear_id = b + batch_num * (f + feature_num * (x + x_size * y));
135                     int output_linear_id = b + crop_batch_num * (f + crop_feature_num * (x + crop_x_size * y));
136                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
137                 }
138             }
139         }
140     }
141 }
142
143 TEST(crop_gpu, basic_int_in2x3x2x2_crop_all) {
144     //  Reference  : 1x2x2x2
145     //  Input      : 2x3x4x5
146     //  Output     : 1x2x2x3
147
148     const auto& engine = get_test_engine();
149
150     auto batch_num = 2;
151     auto feature_num = 3;
152     auto x_size = 4;
153     auto y_size = 5;
154
155     auto crop_batch_num = batch_num - 1;
156     auto crop_feature_num = feature_num - 1;
157     auto crop_x_size = x_size - 2;
158     auto crop_y_size = y_size - 2;
159
160     auto input = memory::allocate(engine, { data_types::i32, format::yxfb,{ batch_num, feature_num, x_size, y_size } });
161
162     topology topology;
163     topology.add(input_layout("input", input.get_layout()));
164     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, { 0, 0, 0, 0 }));
165
166     std::vector<int32_t> input_vec = generate_random_input<int32_t>(batch_num, feature_num, y_size, x_size, -10, 10);
167     set_values(input, input_vec);
168
169     network network(engine, topology);
170
171     network.set_input_data("input", input);
172
173     auto outputs = network.execute();
174
175     auto output = outputs.at("crop").get_memory();
176     auto output_ptr = output.pointer<int32_t>();
177
178     for (int b = 0; b < crop_batch_num; ++b) { //B
179         for (int f = 0; f < crop_feature_num; ++f) { //F
180             for (int y = 0; y < crop_y_size; ++y) { //Y
181                 for (int x = 0; x < crop_x_size; ++x) { //X
182                     int linear_id = b + batch_num * (f + feature_num * (x + x_size * y));
183                     int output_linear_id = b + crop_batch_num * (f + crop_feature_num * (x + crop_x_size * y));
184                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
185                 }
186             }
187         }
188     }
189 }
190
191 TEST(crop_gpu, basic_in2x3x2x2_crop_all_bfyx) {
192     //  Reference  : 3x1x2x2
193     //  Input      : 6x2x4x3
194     //  Output     : 3x1x2x2
195
196     const auto& engine = get_test_engine();
197
198     auto batch_num = 6;
199     auto feature_num = 2;
200     auto x_size = 4;
201     auto y_size = 3;
202
203     auto crop_batch_num = batch_num - 3;
204     auto crop_feature_num = feature_num - 1;
205     auto crop_x_size = x_size - 2;
206     auto crop_y_size = y_size - 1;
207
208     auto input = memory::allocate(engine, { data_types::f32,format::bfyx,{ batch_num, feature_num, x_size, y_size } });
209
210     topology topology;
211     topology.add(input_layout("input", input.get_layout()));
212     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, {0, 0, 0, 0} ));
213
214     std::vector<float> input_vec = generate_random_input<float>(batch_num, feature_num, y_size, x_size, -10, 10);
215     set_values(input, input_vec);
216
217     network network(engine, topology);
218
219     network.set_input_data("input", input);
220
221     auto outputs = network.execute();
222
223     auto output = outputs.at("crop").get_memory();
224     auto output_ptr = output.pointer<float>();
225     std::vector<float> a;
226     for (int b = 0; b < crop_batch_num; ++b) { //B
227         for (int f = 0; f < crop_feature_num; ++f) { //F
228             for (int y = 0; y < crop_y_size; ++y) { //Y
229                 for (int x = 0; x < crop_x_size; ++x) { //X
230                     int linear_id = x + x_size * (y + y_size * (f + feature_num * b));
231                     int output_linear_id = x + crop_x_size * (y + crop_y_size * (f + crop_feature_num * b));
232                     a.push_back(output_ptr[output_linear_id]);
233                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
234                 }
235             }
236         }
237     }
238 }
239
240 TEST(crop_gpu, basic_int_in2x3x2x2_crop_all_bfyx) {
241     //  Reference  : 3x1x2x2
242     //  Input      : 6x2x4x3
243     //  Output     : 3x1x2x2
244
245     const auto& engine = get_test_engine();
246
247     auto batch_num = 6;
248     auto feature_num = 2;
249     auto x_size = 4;
250     auto y_size = 3;
251
252     auto crop_batch_num = batch_num - 3;
253     auto crop_feature_num = feature_num - 1;
254     auto crop_x_size = x_size - 2;
255     auto crop_y_size = y_size - 1;
256
257     auto input = memory::allocate(engine, { data_types::i32,format::bfyx,{ batch_num, feature_num, x_size, y_size } });
258
259     topology topology;
260     topology.add(input_layout("input", input.get_layout()));
261     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, { 0, 0, 0, 0 }));
262
263     std::vector<int32_t> input_vec = generate_random_input<int32_t>(batch_num, feature_num, y_size, x_size, -10, 10);
264     set_values(input, input_vec);
265
266     network network(engine, topology);
267
268     network.set_input_data("input", input);
269
270     auto outputs = network.execute();
271
272     auto output = outputs.at("crop").get_memory();
273     auto output_ptr = output.pointer<int32_t>();
274     std::vector<int32_t> a;
275     for (int b = 0; b < crop_batch_num; ++b) { //B
276         for (int f = 0; f < crop_feature_num; ++f) { //F
277             for (int y = 0; y < crop_y_size; ++y) { //Y
278                 for (int x = 0; x < crop_x_size; ++x) { //X
279                     int linear_id = x + x_size * (y + y_size * (f + feature_num * b));
280                     int output_linear_id = x + crop_x_size * (y + crop_y_size * (f + crop_feature_num * b));
281                     a.push_back(output_ptr[output_linear_id]);
282                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
283                 }
284             }
285         }
286     }
287 }
288
289 TEST(crop_gpu, basic_in2x3x2x2_crop_all_fyxb) {
290     //  Reference  : 3x1x2x2
291     //  Input      : 6x2x4x3
292     //  Output     : 3x1x2x2
293
294     const auto& engine = get_test_engine();
295
296     auto batch_num = 6;
297     auto feature_num = 2;
298     auto x_size = 4;
299     auto y_size = 3;
300
301     auto crop_batch_num = batch_num - 3;
302     auto crop_feature_num = feature_num - 1;
303     auto crop_x_size = x_size - 2;
304     auto crop_y_size = y_size - 1;
305
306     auto input = memory::allocate(engine, { data_types::f32,format::fyxb,{ batch_num, feature_num, x_size, y_size } });
307
308     topology topology;
309     topology.add(input_layout("input", input.get_layout()));
310     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, {0, 0, 0, 0} ));
311
312     std::vector<float> input_vec = generate_random_input<float>(batch_num, feature_num, y_size, x_size, -10, 10);
313     set_values(input, input_vec);
314
315     network network(engine, topology);
316
317     network.set_input_data("input", input);
318
319     auto outputs = network.execute();
320
321     auto output = outputs.at("crop").get_memory();
322     auto output_ptr = output.pointer<float>();
323     for (int b = 0; b < crop_batch_num; ++b) { //B
324         for (int f = 0; f < crop_feature_num; ++f) { //F
325             for (int y = 0; y < crop_y_size; ++y) { //Y
326                 for (int x = 0; x < crop_x_size; ++x) { //X
327                     int linear_id = b + batch_num * (x + x_size * (y + y_size * f));
328                     int output_linear_id = b + crop_batch_num * (x + crop_x_size * (y + crop_y_size * f));
329                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
330                 }
331             }
332         }
333     }
334 }
335
336 TEST(crop_gpu, basic_int_in2x3x2x2_crop_all_fyxb) {
337     //  Reference  : 3x1x2x2
338     //  Input      : 6x2x4x3
339     //  Output     : 3x1x2x2
340
341     const auto& engine = get_test_engine();
342
343     auto batch_num = 6;
344     auto feature_num = 2;
345     auto x_size = 4;
346     auto y_size = 3;
347
348     auto crop_batch_num = batch_num - 3;
349     auto crop_feature_num = feature_num - 1;
350     auto crop_x_size = x_size - 2;
351     auto crop_y_size = y_size - 1;
352
353     auto input = memory::allocate(engine, { data_types::i32,format::fyxb,{ batch_num, feature_num, x_size, y_size } });
354
355     topology topology;
356     topology.add(input_layout("input", input.get_layout()));
357     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size }, { 0, 0, 0, 0 }));
358
359     std::vector<int32_t> input_vec = generate_random_input<int32_t>(batch_num, feature_num, y_size, x_size, -10, 10);
360     set_values(input, input_vec);
361
362     network network(engine, topology);
363
364     network.set_input_data("input", input);
365
366     auto outputs = network.execute();
367
368     auto output = outputs.at("crop").get_memory();
369     auto output_ptr = output.pointer<int32_t>();
370     for (int b = 0; b < crop_batch_num; ++b) { //B
371         for (int f = 0; f < crop_feature_num; ++f) { //F
372             for (int y = 0; y < crop_y_size; ++y) { //Y
373                 for (int x = 0; x < crop_x_size; ++x) { //X
374                     int linear_id = b + batch_num * (x + x_size * (y + y_size * f));
375                     int output_linear_id = b + crop_batch_num * (x + crop_x_size * (y + crop_y_size * f));
376                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
377                 }
378             }
379         }
380     }
381 }
382
383 TEST(crop_gpu, basic_in2x3x2x2_crop_offsets) {
384     //  Reference  : 1x2x2x1
385     //  Offsets    : 1x0x1x1
386     //  Input      : 2x2x3x2
387     //  Output     : 1x2x2x1
388
389     //  Input:
390     //  f0: b0:  1    2  -10   b1:   0    0    -11
391     //  f0: b0:  3    4  -14   b1:   0.5 -0.5  -15
392     //  f1: b0:  5    6  -12   b1:   1.5  5.2  -13
393     //  f1: b0:  7    8  -16   b1:   12   8    -17
394
395     const auto& engine = get_test_engine();
396
397     auto batch_num = 2;
398     auto feature_num = 2;
399     auto x_size = 3;
400     auto y_size = 2;
401
402     auto crop_batch_num = batch_num - 1;
403     auto crop_feature_num = feature_num;
404     auto crop_x_size = x_size - 1;
405     auto crop_y_size = y_size - 1;
406
407     auto batch_offset = 1;
408     auto feature_offset = 0;
409     auto x_offset = 1;
410     auto y_offset = 1;
411
412     auto input = memory::allocate(engine, { data_types::f32, format::yxfb, { tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num)) } });
413
414     topology topology;
415     topology.add(input_layout("input", input.get_layout()));
416     topology.add(crop("crop", "input", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num)), { tensor(feature(0)) }));
417
418     std::vector<float> input_vec = { 1.f, 0.f, 5.f, 1.5f,
419         2.f, 0.f, 6.f, 5.2f,
420         -10.f, -11.f, -12.f, -13.f,
421         3.f, 0.5f, 7.f, 12.f,
422         4.f, -0.5f, 8.f, 8.f,
423         -14.f, -15.f, -16.f, -17.f };
424     set_values(input, input_vec);
425
426     network network(engine, topology);
427
428     network.set_input_data("input", input);
429
430     auto outputs = network.execute();
431
432     auto output = outputs.at("crop").get_memory();
433     auto output_ptr = output.pointer<float>();
434
435     for (int b = 0; b < crop_batch_num; ++b) { //B
436         for (int f = 0; f < crop_feature_num; ++f) { //F
437             for (int y = 0; y < crop_y_size; ++y) { //Y
438                 for (int x = 0; x < crop_x_size; ++x) { //X
439                     int linear_id = (b + batch_offset) + batch_num * ((f + feature_offset) + feature_num * ((x + x_offset) + x_size * (y + y_offset)));
440                     int output_linear_id = b + crop_batch_num * (f + crop_feature_num * (x + crop_x_size * y));
441                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
442                 }
443             }
444         }
445     }
446 }
447
448 TEST(crop_gpu, basic_int_in2x3x2x2_crop_offsets) {
449     //  Reference  : 1x2x2x1
450     //  Offsets    : 1x0x1x1
451     //  Input      : 2x2x3x2
452     //  Output     : 1x2x2x1
453
454     //  Input:
455     //  f0: b0:  1    2  -10   b1:   0    0    -11
456     //  f0: b0:  3    4  -14   b1:   50   -5   -15
457     //  f1: b0:  5    6  -12   b1:   15   52   -13
458     //  f1: b0:  7    8  -16   b1:   12   8    -17
459
460     const auto& engine = get_test_engine();
461
462     auto batch_num = 2;
463     auto feature_num = 2;
464     auto x_size = 3;
465     auto y_size = 2;
466
467     auto crop_batch_num = batch_num - 1;
468     auto crop_feature_num = feature_num;
469     auto crop_x_size = x_size - 1;
470     auto crop_y_size = y_size - 1;
471
472     auto batch_offset = 1;
473     auto feature_offset = 0;
474     auto x_offset = 1;
475     auto y_offset = 1;
476
477     auto input = memory::allocate(engine, { data_types::i32, format::yxfb,{ tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num)) } });
478
479     topology topology;
480     topology.add(input_layout("input", input.get_layout()));
481     topology.add(crop("crop", "input", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num)), { tensor(feature(0)) }));
482
483     std::vector<int32_t> input_vec = { 1, 0, 5, 15,
484         2, 0, 6, 52,
485         -10, -11, -12, -13,
486         3, 50, 7, 12,
487         4, -5, 8, 8,
488         -14, -15, -16, -17 };
489     set_values(input, input_vec);
490
491     network network(engine, topology);
492
493     network.set_input_data("input", input);
494
495     auto outputs = network.execute();
496
497     auto output = outputs.at("crop").get_memory();
498     auto output_ptr = output.pointer<int32_t>();
499
500     for (int b = 0; b < crop_batch_num; ++b) { //B
501         for (int f = 0; f < crop_feature_num; ++f) { //F
502             for (int y = 0; y < crop_y_size; ++y) { //Y
503                 for (int x = 0; x < crop_x_size; ++x) { //X
504                     int linear_id = (b + batch_offset) + batch_num * ((f + feature_offset) + feature_num * ((x + x_offset) + x_size * (y + y_offset)));
505                     int output_linear_id = b + crop_batch_num * (f + crop_feature_num * (x + crop_x_size * y));
506                     EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
507                 }
508             }
509         }
510     }
511 }
512
513 TEST(crop_gpu, basic_in1x4x1x1_split) {
514     // Tests split with crop implementation
515     //                 _CROP_1(1x3x1x1,offset(0x0x0x0))
516     //                |
517     //  INPUT(1x4x1x1)
518     //                |_
519     //                  CROP_2(1x1x1x1,offset(0x3x0x0))
520     //
521     //  Reference1  : 1x3x1x1
522     //  Offsets1    : 0x0x0x0
523     //  Reference2  : 1x1x1x1
524     //  Offsets2    : 0x3x0x0
525     //  Input       : 1x4x1x1
526     //  Output1     : 1x3x1x1
527     //  Output2     : 1x1x1x1
528
529     //  Input:
530     //  f0: -1.0
531     //  f1:  2.0
532     //  f2: -3.0
533     //  f3:  4.0
534
535     //  Out1:
536     //  f0: -1.0
537     //  f1:  2.0
538     //  f2: -3.0
539
540     //  Out2:
541     //  f0: 4.0
542     const auto& engine = get_test_engine();
543
544     auto batch_num = 1;
545     auto feature_num = 4;
546     auto x_size = 1;
547     auto y_size = 1;
548
549     auto crop_batch_num = 1;
550     auto crop_feature_num_1 = 3;
551     auto crop_feature_num_2 = 1;
552     auto crop_x_size = 1;
553     auto crop_y_size = 1;
554     auto feature_offset_1 = 0;
555     auto feature_offset_2 = 3;
556     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num)) } });
557
558     topology topology;
559     topology.add(input_layout("input", input.get_layout()));
560     topology.add(crop("crop1", "input", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num_1)), { tensor(feature(feature_offset_1), spatial(0,0),batch(0)) }));
561     topology.add(crop("crop2", "input", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num_2)), { tensor(feature(feature_offset_2), spatial(0,0),batch(0)) }));
562
563     std::vector<float> input_vec = { -1.f, 2.f, -3.f, 4.f };
564     std::vector<float> out1 = { -1.f, 2.f,-3.f };
565     std::vector<float> out2 = { 4.f, };
566     set_values(input, input_vec);
567     build_options bo;
568     bo.set_option(build_option::optimize_data(true));
569     bo.set_option(build_option::outputs(topology.get_primitive_ids()));
570
571     network network(engine, topology, bo);
572     network.set_input_data("input", input);
573     auto outputs = network.execute();
574
575     auto output = outputs.at("crop1").get_memory();
576     auto output_ptr = output.pointer<float>();
577
578     for (size_t i = 0; i < out1.size();i++)
579         EXPECT_EQ(output_ptr[i], out1[i]);
580
581     std::cout << std::endl;
582     auto output_2 = outputs.at("crop2").get_memory();
583     auto output_ptr_2 = output_2.pointer<float>();
584
585     for (size_t i = 0; i < out2.size();i++)
586         EXPECT_EQ(output_ptr_2[i], out2[i]);
587 }
588
589 TEST(crop_gpu, basic_int_in1x4x1x1_split) {
590     // Tests split with crop implementation
591     //                 _CROP_1(1x3x1x1,offset(0x0x0x0))
592     //                |
593     //  INPUT(1x4x1x1)
594     //                |_
595     //                  CROP_2(1x1x1x1,offset(0x3x0x0))
596     //
597     //  Reference1  : 1x3x1x1
598     //  Offsets1    : 0x0x0x0
599     //  Reference2  : 1x1x1x1
600     //  Offsets2    : 0x3x0x0
601     //  Input       : 1x4x1x1
602     //  Output1     : 1x3x1x1
603     //  Output2     : 1x1x1x1
604
605     //  Input:
606     //  f0: -1
607     //  f1:  2
608     //  f2: -3
609     //  f3:  4
610
611     //  Out1:
612     //  f0: -1
613     //  f1:  2
614     //  f2: -3
615
616     //  Out2:
617     //  f0: 4
618     const auto& engine = get_test_engine();
619
620     auto batch_num = 1;
621     auto feature_num = 4;
622     auto x_size = 1;
623     auto y_size = 1;
624
625     auto crop_batch_num = 1;
626     auto crop_feature_num_1 = 3;
627     auto crop_feature_num_2 = 1;
628     auto crop_x_size = 1;
629     auto crop_y_size = 1;
630     auto feature_offset_1 = 0;
631     auto feature_offset_2 = 3;
632     auto input = memory::allocate(engine, { data_types::i32, format::bfyx,{ tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num)) } });
633
634     topology topology;
635     topology.add(input_layout("input", input.get_layout()));
636     topology.add(crop("crop1", "input", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num_1)), { tensor(feature(feature_offset_1), spatial(0,0),batch(0)) }));
637     topology.add(crop("crop2", "input", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num_2)), { tensor(feature(feature_offset_2), spatial(0,0),batch(0)) }));
638
639     std::vector<int32_t> input_vec = { -1, 2, -3, 4 };
640     std::vector<int32_t> out1 = { -1, 2,-3 };
641     std::vector<int32_t> out2 = { 4, };
642     set_values(input, input_vec);
643     build_options bo;
644     bo.set_option(build_option::optimize_data(true));
645     bo.set_option(build_option::outputs(topology.get_primitive_ids()));
646
647     network network(engine, topology, bo);
648     network.set_input_data("input", input);
649     auto outputs = network.execute();
650
651     auto output = outputs.at("crop1").get_memory();
652     auto output_ptr = output.pointer<int32_t>();
653
654     for (size_t i = 0; i < out1.size(); i++)
655         EXPECT_EQ(output_ptr[i], out1[i]);
656
657     std::cout << std::endl;
658     auto output_2 = outputs.at("crop2").get_memory();
659     auto output_ptr_2 = output_2.pointer<int32_t>();
660
661     for (size_t i = 0; i < out2.size(); i++)
662         EXPECT_EQ(output_ptr_2[i], out2[i]);
663 }
664
665 TEST(crop_gpu, basic_in1x4x1x1_split_w_relu) {
666     // Tests split with crop implementation
667     //                        _ CROP_1(1x3x1x1,offset(0x0x0x0)) --> RELU
668     //                       |
669     //  INPUT(1x4x1x1)--RELU
670     //                       |_
671     //                          CROP_2(1x1x1x1,offset(0x3x0x0)) --> RELU
672     //
673     //  Reference1  : 1x3x1x1
674     //  Offsets1    : 0x0x0x0
675     //  Reference2  : 1x1x1x1
676     //  Offsets2    : 0x3x0x0
677     //  Input       : 1x4x1x1
678     //  Output1     : 1x3x1x1
679     //  Output2     : 1x1x1x1
680
681     //  Input:
682     //  f0: -1.0
683     //  f1:  2.0
684     //  f2: -3.0
685     //  f3:  4.0
686
687     //  Out1:
688     //  f0: 0.0
689     //  f1: 2.0
690     //  f2: 0.0
691
692     //  Out2:
693     //  f0: 4.0
694     // disable memory pool when we want to check optimized out internal results
695     engine_configuration cfg{ false, false, false, std::string(), std::string(), true /*oooq*/, std::string(),std::string(), priority_mode_types::disabled,  throttle_mode_types::disabled, false /*mem_pool*/ };
696     engine engine{ cfg };
697     auto batch_num = 1;
698     auto feature_num = 4;
699     auto x_size = 1;
700     auto y_size = 1;
701     auto crop_batch_num = 1;
702     auto crop_feature_num_1 = 3;
703     auto crop_feature_num_2 = 1;
704     auto crop_x_size = 1;
705     auto crop_y_size = 1;
706     auto feature_offset_1 = 0;
707     auto feature_offset_2 = 3;
708     auto input = memory::allocate(engine, { data_types::f32, format::bfyx,{ tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num)) } });
709
710     topology topology;
711     topology.add(input_layout("input", input.get_layout()));
712     topology.add(activation("relu", "input", activation_func::relu));
713     topology.add(crop("crop1", "relu", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num_1)), { tensor(feature(feature_offset_1), spatial(0,0),batch(0)) }));
714     topology.add(crop("crop2", "relu", tensor(batch(crop_batch_num), spatial(crop_x_size, crop_y_size), feature(crop_feature_num_2)), { tensor(feature(feature_offset_2), spatial(0,0),batch(0)) }));
715     topology.add(activation("relu1", "crop1", activation_func::relu));
716     topology.add(activation("relu2", "crop2", activation_func::relu));
717
718     std::vector<float> input_vec = { -1.f, 2.f, -3.f, 4.f };
719     std::vector<float> out1 = { 0.f, 2.f,0.f };
720     std::vector<float> out2 = { 4.f, };
721     set_values(input, input_vec);
722     build_options bo;
723     bo.set_option(build_option::optimize_data(true));
724     bo.set_option(build_option::debug(true)); //required to have optimized crop despite the fact that it's specified as an output
725
726     network network(engine, topology, bo);
727     network.set_input_data("input", input);
728     auto outputs = network.execute();
729
730     auto output = outputs.at("relu1").get_memory();
731     auto output_ptr = output.pointer<float>();
732
733     // check if crop has been executed in place
734     auto in_place = outputs.at("crop1").get_memory().is_the_same_buffer(outputs.at("relu").get_memory());
735     EXPECT_TRUE(in_place);
736
737     for (size_t i = 0; i < out1.size();i++)
738         EXPECT_EQ(output_ptr[i], out1[i]);
739
740     auto output_2 = outputs.at("relu2").get_memory();
741     auto output_ptr_2 = output_2.pointer<float>();
742
743     for (size_t i = 0; i < out2.size();i++)
744         EXPECT_EQ(output_ptr_2[i], out2[i]);
745 }
746
747 TEST(crop_gpu, basic_in3x1x2x2x1_crop_all_bfzyx) {
748     //  Reference  : 3x1x2x2x1
749     //  Input      : 6x2x4x3x2
750     //  Output     : 3x1x2x2x1
751
752     const auto& engine = get_test_engine();
753
754     auto batch_num = 6;
755     auto feature_num = 2;
756     auto x_size = 4;
757     auto y_size = 3;
758     auto z_size = 2;
759
760     auto crop_batch_num = batch_num - 3;
761     auto crop_feature_num = feature_num - 1;
762     auto crop_x_size = x_size - 2;
763     auto crop_y_size = y_size - 1;
764     auto crop_z_size = z_size - 1;
765
766     auto input = memory::allocate(engine, { data_types::f32,format::bfzyx,{ batch_num, feature_num, x_size, y_size, z_size } });
767
768     topology topology;
769     topology.add(input_layout("input", input.get_layout()));
770     topology.add(crop("crop", "input", { crop_batch_num, crop_feature_num, crop_x_size, crop_y_size, crop_z_size }, { 0, 0, 0, 0, 0 }));
771
772     std::vector<float> input_vec = generate_random_input<float>(batch_num, feature_num, y_size, x_size, -10, 10);
773     set_values(input, input_vec);
774
775     network network(engine, topology);
776
777     network.set_input_data("input", input);
778
779     auto outputs = network.execute();
780
781     auto output = outputs.at("crop").get_memory();
782     auto output_ptr = output.pointer<float>();
783     for (int b = 0; b < crop_batch_num; ++b) { //B
784         for (int f = 0; f < crop_feature_num; ++f) { //F
785             for (int z = 0; z < crop_z_size; ++z) { //Z
786                 for (int y = 0; y < crop_y_size; ++y) { //Y
787                     for (int x = 0; x < crop_x_size; ++x) { //X
788                         int linear_id = x + x_size * (y + y_size * (z + z_size * (f + feature_num * b)));
789                         int output_linear_id = x + crop_x_size * (y + crop_y_size * (z + crop_z_size * (f + crop_feature_num * b)));
790                         EXPECT_EQ(output_ptr[output_linear_id], input_vec[linear_id]);
791                     }
792                 }
793             }
794         }
795     }
796 }