2cf9b3e39ce98542e382311fdeec994a9cadfce7
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / tests / test_cases / removing_output_node_test.cpp
1 /*
2 // Copyright (c) 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/CPP/topology.hpp>
20 #include <api/CPP/network.hpp>
21 #include <api/CPP/engine.hpp>
22
23 #include <api/CPP/data.hpp>
24 #include <api/CPP/reshape.hpp>
25 #include <api/CPP/input_layout.hpp>
26 #include <api/CPP/shuffle_channels.hpp>
27 #include <api/CPP/strided_slice.hpp>
28
29 #include "test_utils/test_utils.h"
30
31 using namespace cldnn;
32 using namespace tests;
33 using namespace testing;
34
35 TEST(removing_output_node, multiple_outputs) {
36     // Tests split with crop implementation
37     //                                                   _ strided_slice(bfyx)
38     //                                                  |
39     //  INPUT(bfyx,3x2x1x1)--shuffle_channels(bfyx)-----|
40     //                                                  |_
41     //                                                     reshape(bfyx);
42
43     const auto& engine = get_test_engine();
44     auto batch_num = 6;
45     auto feature_num = 1;
46     auto x_size = 1;
47     auto y_size = 1;
48     int32_t axis = 0;
49     int32_t group = 2;
50
51     tensor initial_shape = tensor(spatial(x_size, y_size), feature(feature_num), batch(batch_num));
52     tensor after_strided_slice = tensor(spatial(y_size, feature_num), feature(batch_num), batch(1));
53     tensor after_reshape = tensor(feature(batch_num * feature_num * y_size * x_size));
54
55     auto input = memory::allocate(engine, { data_types::f32, format::bfyx, initial_shape });
56     auto begin = memory::allocate(engine, { data_types::i32, format::bfyx, { 4, 1, 1, 1 } });
57     auto end = memory::allocate(engine, { data_types::i32, format::bfyx, { 4, 1, 1, 1 } });
58     auto strides = memory::allocate(engine, { data_types::i32, format::bfyx, { 4, 1, 1, 1 } });
59
60     set_values(begin, {
61             1, 0, 1, 0
62     });
63     set_values(end, {
64             2, 2, 4, 4
65     });
66     set_values(strides, {
67             1, 1, 1, 2
68     });
69
70     topology topology;
71     topology.add(input_layout("input", input.get_layout()));
72     topology.add(shuffle_channels("shuffle_channels", "input", group, axis));
73     topology.add(reshape("reshape", "shuffle_channels", after_reshape));
74     topology.add(data("input2", begin));
75     topology.add(data("input3", end));
76     topology.add(data("input4", strides));
77     topology.add(strided_slice("strided_slice", "shuffle_channels", "input2", "input3", "input4", {}, {}, { 1 }, {}));
78
79     std::vector<float> input_vec = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
80     std::vector<float> out_vec = { 0.0f, 3.0f, 1.0f, 4.0f, 2.0f, 5.0f };
81     set_values(input, input_vec);
82
83     build_options bo;
84     bo.set_option(build_option::outputs({ "shuffle_channels", "reshape", "strided_slice" }));
85
86     network network(engine, topology, bo);
87     network.set_input_data("input", input);
88     auto outputs = network.execute();
89
90     auto output = outputs.at("reshape").get_memory();
91     auto output_ptr = output.pointer<float>();
92
93     ASSERT_TRUE(output.get_layout().size == after_reshape);
94
95     for (size_t i = 0; i < out_vec.size(); i++)
96         EXPECT_EQ(output_ptr[i], out_vec[i]);
97
98     // checking the output node has the same name after output node deleting due to StridedSlice optimization
99     ASSERT_TRUE(outputs.find("strided_slice") != outputs.end());
100     auto output2 = outputs.at("strided_slice").get_memory();
101     auto output_ptr2 = output.pointer<float>();
102
103     ASSERT_TRUE(output2.get_layout().size == after_strided_slice);
104
105     for (size_t i = 0; i < out_vec.size(); i++)
106         EXPECT_EQ(output_ptr2[i], out_vec[i]);
107 }
108
109 TEST(removing_output_node, output_node_optimization) {
110     //  Filter : 2x3
111     //  Stride : 2x1
112     //  Input  : 4x5
113     //  Output : 2x3
114     //
115     //  Input:
116     //  1  2  3  4  5
117     //  2  2  3  4  6
118     //  3  3  3  5  1
119     //  1  1  1  1  1
120     //
121     //  Filter:
122     //  1  2  1
123     //  2  1  2
124     //
125     //  Output:
126     //  21  28  39
127     //  18  20  20
128
129     const auto& engine = get_test_engine();
130
131     auto input = memory::allocate(engine, { data_types::f32,format::yxfb,{ 1, 1, 5, 4 } });
132     auto weights = memory::allocate(engine, { data_types::f32,format::bfyx,{ 1, 1, 3, 2 } });
133
134     set_values(input, { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 2.0f, 2.0f, 3.0f, 4.0f, 6.0f, 3.0f, 3.0f, 3.0f, 5.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f });
135     set_values(weights, { 1.0f, 2.0f, 1.0f, 2.0f, 1.0f, 2.0f });
136     VVF<float> output_vec = {
137             { 20.0f, 27.0f, 38.0f },
138             { 17.0f, 19.0f, 19.0f } };
139
140     topology topology;
141     topology.add(input_layout("input", input.get_layout()));
142     topology.add(data("weights", weights));
143     topology.add(convolution("conv", "input", { "weights" }, { 1,1,1,2 }));
144     topology.add(activation("relu", "conv", activation_relu));
145
146     network network(engine, topology);
147     network.set_input_data("input", input);
148
149     // checking the output node has the same name after output node deleting due to ReLU optimization
150     auto outputs = network.execute();
151     EXPECT_EQ(outputs.size(), size_t(1));
152     EXPECT_EQ(outputs.begin()->first, "relu");
153
154     auto output_memory = outputs.at("relu").get_memory();
155     auto output_layout = output_memory.get_layout();
156     auto output_ptr = output_memory.pointer<float>();
157
158     int y_size = output_layout.size.spatial[1];
159     int x_size = output_layout.size.spatial[0];
160     int f_size = output_layout.size.feature[0];
161     int b_size = output_layout.size.batch[0];
162     EXPECT_EQ(output_layout.format, format::yxfb);
163     EXPECT_EQ(y_size, 2);
164     EXPECT_EQ(x_size, 3);
165     EXPECT_EQ(f_size, 1);
166     EXPECT_EQ(b_size, 1);
167     for (int y = 0; y < y_size; ++y) {
168         for (int x = 0; x < x_size; ++x) {
169             EXPECT_EQ(output_vec[y][x], output_ptr[y * x_size + x]);
170         }
171     }
172 }