Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / engines / mkldnn / graph / layers / extensions / shuffle_channels_tests.cpp
1 // Copyright (C) 2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <gtest/gtest.h>
6 #include <gmock/gmock-spec-builders.h>
7 #include "mkldnn_plugin/mkldnn_graph.h"
8
9 #include "test_graph.hpp"
10
11 #include "single_layer_common.hpp"
12 #include <mkldnn_plugin/mkldnn_extension_utils.h>
13 #include <extension/ext_list.hpp>
14 #include "tests_common.hpp"
15
16
17 using namespace ::testing;
18 using namespace std;
19 using namespace mkldnn;
20
21 struct shuffle_channels_test_params {
22     InferenceEngine::SizeVector in_out_shape;
23     int axis;
24     int group;
25
26     std::vector<float> reference;
27     std::vector<std::function<void(MKLDNNPlugin::PrimitiveDescInfo)>> comp;
28 };
29
30 void ref_shuffle_channels(
31     InferenceEngine::TBlob<float> &src,
32     InferenceEngine::TBlob<float> &dst,
33     int axis,
34     int group
35 ) {
36     size_t i;
37     const float *src_data = src.data();
38     InferenceEngine::SizeVector src_dims = src.getTensorDesc().getDims();
39     InferenceEngine::SizeVector srcStrides = src.getTensorDesc().getBlockingDesc().getStrides();
40     float* dst_data = dst.data();
41     InferenceEngine::SizeVector dst_dims = dst.getTensorDesc().getDims();
42     InferenceEngine::SizeVector dstStrides = dst.getTensorDesc().getBlockingDesc().getStrides();
43
44     if (axis < 0)
45         axis += dst_dims.size();
46
47     if (axis < 0 || axis >= dst_dims.size())
48         FAIL() << "Incorrect input parameters dimensions and axis number!";
49
50     if (dst_dims[axis] % group)
51         FAIL() << "Group parameter must evenly divide the channel dimension!";
52
53     //  Find number of dictionaries, index range and data length
54     size_t numDictionaries = 1;
55     for (i = 0; i <= axis; i++)
56         numDictionaries *= dst_dims[i];
57
58     size_t channelsNum = dst_dims[axis] / group;
59
60     size_t dataLength = 1;
61     for (i = axis + 1; i < dst_dims.size(); i++)
62         dataLength *= dst_dims[i];
63
64     if (dataLength == 0)
65         FAIL() << "Incorrect input parameters dimension!";
66
67     size_t j, k;
68     for (j = 0, k = 0; j < numDictionaries; j += dst_dims[axis]) {
69         for (i = 0; i < (dst_dims[axis] * channelsNum); i += channelsNum, k += dataLength) {
70             int idx = j + i / dst_dims[axis] + i % dst_dims[axis];
71             memcpy(&dst_data[k], &src_data[dataLength * idx], sizeof(float) * dataLength);
72         }
73     }
74 }
75
76 class MKLDNNCPUExtShuffleChannelsTests : public TestsCommon, public WithParamInterface<shuffle_channels_test_params> {
77     std::string model_t = R"V0G0N(
78 <net Name="ShuffleChannels_net" version="2" precision="FP32" batch="1">
79     <layers>
80         <layer name="input" type="Input" precision="FP32" id="1">
81             <output>
82                 <port id="1">
83                     _IN_OUT_
84                 </port>
85             </output>
86         </layer>
87         <layer name="output" id="2" type="ShuffleChannels" precision="FP32">
88             <data axis="_AX_" group="_GR_"/>
89             <input>
90                 <port id="1">
91                     _IN_OUT_
92                 </port>
93            </input>
94             <output>
95                 <port id="2">
96                     _IN_OUT_
97                 </port>
98             </output>
99         </layer>
100     </layers>
101     <edges>
102         <edge from-layer="1" from-port="1" to-layer="2" to-port="1"/>
103     </edges>
104 </net>
105 )V0G0N";
106
107     std::string getModel(shuffle_channels_test_params p) {
108         std::string model = model_t;
109         std::string in_out_shape;
110
111         for (size_t i = 0; i < p.in_out_shape.size(); i++) {
112             in_out_shape += "<dim>";
113             in_out_shape += std::to_string(p.in_out_shape[i]) + "</dim>\n";
114         }
115         REPLACE_WITH_STR(model, "_IN_OUT_", in_out_shape);
116         REPLACE_WITH_NUM(model, "_AX_", p.axis);
117         REPLACE_WITH_NUM(model, "_GR_", p.group);
118
119         return model;
120     }
121
122 protected:
123     virtual void TearDown() {
124     }
125
126     virtual void SetUp() {
127         try {
128             TestsCommon::SetUp();
129             shuffle_channels_test_params p = ::testing::WithParamInterface<shuffle_channels_test_params>::GetParam();
130             std::string model = getModel(p);
131             ////std::cout << model;
132             InferenceEngine::CNNNetReader net_reader;
133             ASSERT_NO_THROW(net_reader.ReadNetwork(model.data(), model.length()));
134
135             InferenceEngine::Extension cpuExt(make_so_name("cpu_extension"));
136             MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr(new MKLDNNPlugin::MKLDNNExtensionManager());
137             extMgr->AddExtension(InferenceEngine::IExtensionPtr(&cpuExt, [](InferenceEngine::IExtension*){}));
138
139             MKLDNNGraphTestClass graph;
140             graph.CreateGraph(net_reader.getNetwork(), extMgr);
141
142             // Output Data
143             InferenceEngine::OutputsDataMap out;
144             out = net_reader.getNetwork().getOutputsInfo();
145             InferenceEngine::BlobMap outputBlobs;
146
147             std::pair<std::string, InferenceEngine::DataPtr> item = *out.begin();
148
149             InferenceEngine::TBlob<float>::Ptr output;
150             output = InferenceEngine::make_shared_blob<float>(item.second->getTensorDesc());
151             output->allocate();
152             outputBlobs[item.first] = output;
153
154             // Output Reference
155             InferenceEngine::TBlob<float> dst_ref(item.second->getTensorDesc());
156             dst_ref.allocate();
157
158             // Input Data
159             InferenceEngine::Blob::Ptr src;
160             src = InferenceEngine::make_shared_blob<float>({ InferenceEngine::Precision::FP32, p.in_out_shape, InferenceEngine::TensorDesc::getLayoutByDims(p.in_out_shape) });
161             src->allocate();
162             fill_data_dbgval(src->buffer(), src->size());
163             auto * srcPtr = dynamic_cast<InferenceEngine::TBlob<float>*>(src.get());
164             if (srcPtr == nullptr)
165                 FAIL() << "Cannot cast blob to TBlob<float>.";
166
167             // Check results
168             InferenceEngine::SizeVector out_dims;
169             ref_shuffle_channels(*srcPtr, dst_ref, p.axis, p.group);
170
171             //  Check results
172             if (memcmp(dst_ref.data(), &p.reference[0], p.reference.size() * sizeof(float)) != 0)
173                 FAIL() << "Wrong result with compare TF reference!";
174
175             InferenceEngine::BlobMap srcs;
176             srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("input", src));
177
178             // Infer
179             graph.Infer(srcs, outputBlobs);
180             compare(*output, dst_ref);
181         } catch (const InferenceEngine::details::InferenceEngineException &e) {
182             FAIL() << e.what();
183         }
184     }
185 };
186
187
188 TEST_P(MKLDNNCPUExtShuffleChannelsTests, TestsShuffleChannels) {}
189
190 //  Test data vectors
191 static std::vector<float> test0 = { 0.f, 1.f, 2.f, 3.f, 12.f, 13.f, 14.f, 15.f, 24.f, 25.f, 26.f, 27.f, 36.f, 37.f, 38.f, 39.f, 48.f, 49.f, 50.f, 51.f,
192                                     4.f, 5.f, 6.f, 7.f, 16.f, 17.f, 18.f, 19.f, 28.f, 29.f, 30.f, 31.f, 40.f, 41.f, 42.f, 43.f, 52.f, 53.f, 54.f, 55.f,
193                                     8.f, 9.f, 10.f, 11.f, 20.f, 21.f, 22.f, 23.f, 32.f, 33.f, 34.f, 35.f, 44.f, 45.f, 46.f, 47.f, 56.f, 57.f, 58.f, 59.f };
194 static std::vector<float> test4 = { 0.f, 2.f, 4.f, 1.f, 3.f, 5.f, 6.f, 8.f, 10.f, 7.f, 9.f, 11.f, 12.f, 14.f, 16.f, 13.f, 15.f, 17.f, 18.f, 20.f, 22.f, 19.f, 21.f, 23.f };
195 static std::vector<float> test5 = { 0.f, 1.f, 4.f, 5.f, 8.f, 9.f, 2.f, 3.f, 6.f, 7.f, 10.f, 11.f, 12.f, 13.f, 16.f, 17.f, 20.f, 21.f, 14.f, 15.f, 18.f, 19.f, 22.f, 23.f };
196 static std::vector<float> test6 = { 0.f, 3.f, 1.f, 4.f, 2.f, 5.f, 6.f, 9.f, 7.f, 10.f, 8.f, 11.f, 12.f, 15.f, 13.f, 16.f, 14.f, 17.f, 18.f, 21.f, 19.f, 22.f, 20.f, 23.f };
197 static std::vector<float> test7 = { 0.f, 1.f, 6.f, 7.f, 2.f, 3.f, 8.f, 9.f, 4.f, 5.f, 10.f, 11.f, 12.f, 13.f, 18.f, 19.f, 14.f, 15.f, 20.f, 21.f, 16.f, 17.f, 22.f, 23.f };
198 static std::vector<float> test8 = { 0.f, 3.f, 1.f, 4.f, 2.f, 5.f };
199
200 INSTANTIATE_TEST_CASE_P(
201     TestsShuffleChannels, MKLDNNCPUExtShuffleChannelsTests,
202             ::testing::Values(
203 // Params: in_out_shape, axis, group, reference
204 /* 0 */         shuffle_channels_test_params{ { 1, 15, 2, 2 }, 1, 5, test0 },
205                 shuffle_channels_test_params{ { 1, 15, 2, 2 }, -3, 5, test0 },
206                 shuffle_channels_test_params{ { 15, 2, 2 }, 0, 5, test0 },
207                 shuffle_channels_test_params{ { 15, 2, 2 }, -3, 5, test0 },
208                 shuffle_channels_test_params{ { 2, 2, 6 }, -1, 3, test4 },
209 /* 5 */         shuffle_channels_test_params{ { 2, 6, 2 }, -2, 3, test5 },
210                 shuffle_channels_test_params{ { 2, 2, 6 }, -1, 2, test6 },
211                 shuffle_channels_test_params{ { 2, 6, 2 }, -2, 2, test7 },
212                 shuffle_channels_test_params{ { 6 }, 0, 2, test8 }
213             ));