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