Merge pull request #129 from asuhov/2019-r1
[platform/upstream/dldt.git] / inference-engine / tests / unit / engines / mkldnn / graph / layers / extensions / depth_to_space_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 depth_to_space_test_params {
22     InferenceEngine::SizeVector in_shape;
23     size_t block_size;
24     InferenceEngine::SizeVector out_shape;
25
26     std::vector<float> reference;
27     std::vector<std::function<void(MKLDNNPlugin::PrimitiveDescInfo)>> comp;
28 };
29
30 void ref_depth_to_space(
31     InferenceEngine::TBlob<float> &src,
32     InferenceEngine::TBlob<float> &dst,
33     size_t block_size
34 ) {
35     size_t i;
36     const float *src_data = src.data();
37     InferenceEngine::SizeVector src_dims = src.getTensorDesc().getDims();
38     InferenceEngine::SizeVector srcStrides = src.getTensorDesc().getBlockingDesc().getStrides();
39     float* dst_data = dst.data();
40     InferenceEngine::SizeVector dst_dims = dst.getTensorDesc().getDims();
41     InferenceEngine::SizeVector dstStrides = dst.getTensorDesc().getBlockingDesc().getStrides();
42
43     if (src_dims.size() < 3)
44         FAIL() << " Incorrect number of input dimensions!";
45
46     if (dst_dims.size() < 2)
47         FAIL() << " Incorrect number of output dimensions!";
48
49     if (block_size == 0)
50         FAIL() << " Incorrect block_size parameter is zero!";
51
52     if (src_dims[src_dims.size() - 3] % (block_size * block_size))
53         FAIL() << " block_size parameter is incompatible with input tensor Color dimension size!";
54
55     if (dst_dims.size() > 2 && src_dims[src_dims.size() - 3] != (dst_dims[dst_dims.size() - 3] * block_size * block_size))
56         FAIL() << " Input/Output tensor Color dimension is incompatible with block_size!";
57
58     if (dst_dims[dst_dims.size() - 2] != (src_dims[src_dims.size() - 2] * block_size))
59         FAIL() << " Input/Output tensor Height dimension is incompatible with block_size!";
60
61     if (dst_dims[dst_dims.size() - 1] != (src_dims[src_dims.size() - 1] * block_size))
62         FAIL() << " Input/Output tensor Width dimension is incompatible with block_size!";
63
64     size_t X = 1;
65     for (i = 0; i < (src_dims.size() - 3); i++)
66         X *= src_dims[i];
67
68     size_t C = src_dims[src_dims.size() - 3];
69     size_t H = src_dims[src_dims.size() - 2];
70     size_t W = src_dims[src_dims.size() - 1];
71
72     for (size_t x = 0, k = 0; x < X; ++x) {
73         for (size_t h = 0; h < H; ++h) {
74             for (size_t c = 0; c < C; c += block_size) {
75                 for (size_t w = 0; w < W; ++w) {
76                     for (size_t b = 0; b < block_size; ++b) {
77                         size_t idx = x * C*H*W + (c + b) * H*W + h * W + w;
78                         dst_data[k++] = src_data[idx];
79                     }
80                 }
81             }
82         }
83     }
84 }
85
86 void ref_space_to_depth(
87     InferenceEngine::TBlob<float> &src,
88     InferenceEngine::TBlob<float> &dst,
89     size_t block_size
90 ) {
91     size_t i;
92     const float *src_data = src.data();
93     InferenceEngine::SizeVector src_dims = src.getTensorDesc().getDims();
94     InferenceEngine::SizeVector srcStrides = src.getTensorDesc().getBlockingDesc().getStrides();
95     float* dst_data = dst.data();
96     InferenceEngine::SizeVector dst_dims = dst.getTensorDesc().getDims();
97     InferenceEngine::SizeVector dstStrides = dst.getTensorDesc().getBlockingDesc().getStrides();
98
99     if (dst_dims.size() < 3)
100         FAIL() << " Incorrect number of output dimensions!";
101
102     if (src_dims.size() < 2)
103         FAIL() << " Incorrect number of input dimensions!";
104
105     if (block_size == 0)
106         FAIL() << " Incorrect block_size parameter is zero!";
107
108     if (dst_dims[dst_dims.size() - 3] % (block_size * block_size))
109         FAIL() << " block_size parameter is incompatible with input tensor Color dimension size!";
110
111     if (src_dims.size() > 2 && dst_dims[dst_dims.size() - 3] != (src_dims[dst_dims.size() - 3] * block_size * block_size))
112         FAIL() << " Input/Output tensor Color dimension is incompatible with block_size!";
113
114     if (src_dims[src_dims.size() - 2] != (dst_dims[dst_dims.size() - 2] * block_size))
115         FAIL() << " Input/Output tensor Height dimension is incompatible with block_size!";
116
117     if (src_dims[src_dims.size() - 1] != (dst_dims[dst_dims.size() - 1] * block_size))
118         FAIL() << " Input/Output tensor Width dimension is incompatible with block_size!";
119
120     size_t X = 1;
121     for (i = 0; i < (dst_dims.size() - 3); i++)
122         X *= dst_dims[i];
123
124     size_t C = dst_dims[dst_dims.size() - 3];
125     size_t H = dst_dims[dst_dims.size() - 2];
126     size_t W = dst_dims[dst_dims.size() - 1];
127
128     for (size_t x = 0, k = 0; x < X; ++x) {
129         for (size_t h = 0; h < H; ++h) {
130             for (size_t c = 0; c < C; c += block_size) {
131                 for (size_t w = 0; w < W; ++w) {
132                     for (size_t b = 0; b < block_size; ++b) {
133                         size_t idx = x * C*H*W + (c + b) * H*W + h * W + w;
134                         dst_data[idx] = src_data[k++];
135                     }
136                 }
137             }
138         }
139     }
140 }
141
142 class MKLDNNCPUExtDepthToSpaceTests : public TestsCommon, public WithParamInterface<depth_to_space_test_params> {
143     std::string model_t = R"V0G0N(
144 <net Name="DepthToSpace_net" version="2" precision="FP32" batch="1">
145     <layers>
146         <layer name="input" type="Input" precision="FP32" id="1">
147             <output>
148                 <port id="1">
149                     _IN_
150                 </port>
151             </output>s
152         </layer>
153         <layer name="output" id="2" type="DepthToSpace" precision="FP32">
154             <data block_size="_BS_"/>
155             <input>
156                 <port id="1">
157                     _IN_
158                 </port>
159            </input>
160             <output>
161                 <port id="2">
162                     _OUT_
163                 </port>
164             </output>
165         </layer>
166     </layers>
167     <edges>
168         <edge from-layer="1" from-port="1" to-layer="2" to-port="1"/>
169     </edges>
170 </net>
171 )V0G0N";
172
173     std::string getModel(depth_to_space_test_params p) {
174         std::string model = model_t;
175         std::string in_shape, out_shape;
176
177         for (size_t i = 0; i < p.in_shape.size(); i++) {
178             in_shape += "<dim>";
179             in_shape += std::to_string(p.in_shape[i]) + "</dim>\n";
180         }
181         for (size_t i = 0; i < p.out_shape.size(); i++) {
182             out_shape += "<dim>";
183             out_shape += std::to_string(p.out_shape[i]) + "</dim>\n";
184         }
185         REPLACE_WITH_STR(model, "_IN_", in_shape);
186         REPLACE_WITH_STR(model, "_OUT_", out_shape);
187         REPLACE_WITH_NUM(model, "_BS_", p.block_size);
188
189         return model;
190     }
191
192 protected:
193     virtual void TearDown() {
194     }
195
196     virtual void SetUp() {
197         try {
198             TestsCommon::SetUp();
199             depth_to_space_test_params p = ::testing::WithParamInterface<depth_to_space_test_params>::GetParam();
200             std::string model = getModel(p);
201
202             InferenceEngine::CNNNetReader net_reader;
203             ASSERT_NO_THROW(net_reader.ReadNetwork(model.data(), model.length()));
204
205             InferenceEngine::Extension cpuExt(make_so_name("cpu_extension"));
206             MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr(new MKLDNNPlugin::MKLDNNExtensionManager());
207             extMgr->AddExtension(InferenceEngine::IExtensionPtr(&cpuExt, [](InferenceEngine::IExtension*){}));
208
209             MKLDNNGraphTestClass graph;
210             graph.CreateGraph(net_reader.getNetwork(), extMgr);
211
212             // Output Data
213             InferenceEngine::OutputsDataMap out;
214             out = net_reader.getNetwork().getOutputsInfo();
215             InferenceEngine::BlobMap outputBlobs;
216
217             std::pair<std::string, InferenceEngine::DataPtr> item = *out.begin();
218
219             InferenceEngine::TBlob<float>::Ptr output;
220             output = InferenceEngine::make_shared_blob<float>(item.second->getTensorDesc());
221             output->allocate();
222             outputBlobs[item.first] = output;
223
224             // Output Reference
225             InferenceEngine::TBlob<float> dst_ref(item.second->getTensorDesc());
226             dst_ref.allocate();
227
228             // Input Data
229             InferenceEngine::Blob::Ptr src;
230             src = InferenceEngine::make_shared_blob<float>({ InferenceEngine::Precision::FP32, p.in_shape, InferenceEngine::TensorDesc::getLayoutByDims(p.in_shape) });
231             src->allocate();
232             fill_data_dbgval(src->buffer(), src->size());
233             auto * srcPtr = dynamic_cast<InferenceEngine::TBlob<float>*>(src.get());
234             if (srcPtr == nullptr)
235                 FAIL() << "Cannot cast blob to TBlob<float>.";
236
237             // Check results
238             InferenceEngine::SizeVector out_dims;
239             ref_depth_to_space(*srcPtr, dst_ref, p.block_size);
240
241             //  Check results
242             if(p.reference.size())
243                 if (memcmp(dst_ref.data(), &p.reference[0], p.reference.size() * sizeof(float)) != 0)
244                     FAIL() << "Wrong result with compare TF reference!";
245
246             InferenceEngine::BlobMap srcs;
247             srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("input", src));
248
249             // Infer
250             graph.Infer(srcs, outputBlobs);
251             compare(*output, dst_ref);
252         } catch (const InferenceEngine::details::InferenceEngineException &e) {
253             FAIL() << e.what();
254         }
255     }
256 };
257
258 class MKLDNNCPUExtSpaceToDepthTests : public TestsCommon, public WithParamInterface<depth_to_space_test_params> {
259     std::string model_t = R"V0G0N(
260 <net Name="SpaceToDepth_net" version="2" precision="FP32" batch="1">
261     <layers>
262         <layer name="input" type="Input" precision="FP32" id="1">
263             <output>
264                 <port id="1">
265                     _IN_
266                 </port>
267             </output>s
268         </layer>
269         <layer name="output" id="2" type="SpaceToDepth" precision="FP32">
270             <data block_size="_BS_"/>
271             <input>
272                 <port id="1">
273                     _IN_
274                 </port>
275            </input>
276             <output>
277                 <port id="2">
278                     _OUT_
279                 </port>
280             </output>
281         </layer>
282     </layers>
283     <edges>
284         <edge from-layer="1" from-port="1" to-layer="2" to-port="1"/>
285     </edges>
286 </net>
287 )V0G0N";
288
289     std::string getModel(depth_to_space_test_params p) {
290         std::string model = model_t;
291         std::string in_shape, out_shape;
292
293         for (size_t i = 0; i < p.out_shape.size(); i++) {
294             in_shape += "<dim>";
295             in_shape += std::to_string(p.out_shape[i]) + "</dim>\n";
296         }
297         for (size_t i = 0; i < p.in_shape.size(); i++) {
298             out_shape += "<dim>";
299             out_shape += std::to_string(p.in_shape[i]) + "</dim>\n";
300         }
301         REPLACE_WITH_STR(model, "_IN_", in_shape);
302         REPLACE_WITH_STR(model, "_OUT_", out_shape);
303         REPLACE_WITH_NUM(model, "_BS_", p.block_size);
304
305         return model;
306     }
307
308 protected:
309     virtual void TearDown() {
310     }
311
312     virtual void SetUp() {
313         try {
314             TestsCommon::SetUp();
315             depth_to_space_test_params p = ::testing::WithParamInterface<depth_to_space_test_params>::GetParam();
316             std::string model = getModel(p);
317             //std::cout << model;
318             InferenceEngine::CNNNetReader net_reader;
319             ASSERT_NO_THROW(net_reader.ReadNetwork(model.data(), model.length()));
320
321             InferenceEngine::Extension cpuExt(make_so_name("cpu_extension"));
322             MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr(new MKLDNNPlugin::MKLDNNExtensionManager());
323             extMgr->AddExtension(InferenceEngine::IExtensionPtr(&cpuExt, [](InferenceEngine::IExtension*) {}));
324
325             MKLDNNGraphTestClass graph;
326             graph.CreateGraph(net_reader.getNetwork(), extMgr);
327
328             // Output Data
329             InferenceEngine::OutputsDataMap out;
330             out = net_reader.getNetwork().getOutputsInfo();
331             InferenceEngine::BlobMap outputBlobs;
332
333             std::pair<std::string, InferenceEngine::DataPtr> item = *out.begin();
334
335             InferenceEngine::TBlob<float>::Ptr output;
336             output = InferenceEngine::make_shared_blob<float>(item.second->getTensorDesc());
337             output->allocate();
338             outputBlobs[item.first] = output;
339
340             // Output Reference
341             InferenceEngine::TBlob<float> dst_ref(item.second->getTensorDesc());
342             dst_ref.allocate();
343
344             // Input Data
345             InferenceEngine::Blob::Ptr src;
346             src = InferenceEngine::make_shared_blob<float>({ InferenceEngine::Precision::FP32, p.out_shape, InferenceEngine::TensorDesc::getLayoutByDims(p.out_shape) });
347             src->allocate();
348             if (p.reference.size())
349                 memcpy(static_cast<float*>(src->buffer()), &p.reference[0], sizeof(float)*p.reference.size());
350             auto * srcPtr = dynamic_cast<InferenceEngine::TBlob<float>*>(src.get());
351             if (srcPtr == nullptr)
352                 FAIL() << "Cannot cast blob to TBlob<float>.";
353
354             // Check results
355             InferenceEngine::SizeVector out_dims;
356             ref_space_to_depth(*srcPtr, dst_ref, p.block_size);
357
358             //  Check results
359             if (p.reference.size()) {
360             //    fill_data_dbgval(src->buffer(), src->size());
361             //    if (memcmp(dst_ref.data(), &p.reference[0], p.reference.size() * sizeof(float)) != 0)
362             //        FAIL() << "Wrong result with compare TF reference!";
363             }
364
365             InferenceEngine::BlobMap srcs;
366             srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("input", src));
367
368             // Infer
369             graph.Infer(srcs, outputBlobs);
370             compare(*output, dst_ref);
371         }
372         catch (const InferenceEngine::details::InferenceEngineException &e) {
373             FAIL() << e.what();
374         }
375     }
376 };
377
378
379
380 class MKLDNNCPUExtDepthToSpaceToDepthTests : public TestsCommon, public WithParamInterface<depth_to_space_test_params> {
381     std::string model_t = R"V0G0N(
382 <net Name="DepthToSpaceToDepth_net" version="2" precision="FP32" batch="1">
383     <layers>
384         <layer name="input" type="Input" precision="FP32" id="1">
385             <output>
386                 <port id="1">
387                     _IN_
388                 </port>
389             </output>s
390         </layer>
391         <layer name="intermediate" id="2" type="DepthToSpace" precision="FP32">
392             <data block_size="_BS_"/>
393             <input>
394                 <port id="1">
395                     _IN_
396                 </port>
397            </input>
398             <output>
399                 <port id="2">
400                     _OUT_
401                 </port>
402             </output>
403         </layer>
404         <layer name="output" id="3" type="SpaceToDepth" precision="FP32">
405             <data block_size="_BS_"/>
406             <input>
407                 <port id="1">
408                     _OUT_
409                 </port>
410            </input>
411             <output>
412                 <port id="2">
413                     _IN_
414                 </port>
415             </output>
416         </layer>
417     </layers>
418     <edges>
419         <edge from-layer="1" from-port="1" to-layer="2" to-port="1"/>
420         <edge from-layer="2" from-port="2" to-layer="3" to-port="1"/>
421     </edges>
422 </net>
423 )V0G0N";
424
425     std::string getModel(depth_to_space_test_params p) {
426         std::string model = model_t;
427         std::string in_shape, out_shape;
428
429         for (size_t i = 0; i < p.in_shape.size(); i++) {
430             in_shape += "<dim>";
431             in_shape += std::to_string(p.in_shape[i]) + "</dim>\n";
432         }
433         for (size_t i = 0; i < p.out_shape.size(); i++) {
434             out_shape += "<dim>";
435             out_shape += std::to_string(p.out_shape[i]) + "</dim>\n";
436         }
437         REPLACE_WITH_STR(model, "_IN_", in_shape);
438         REPLACE_WITH_STR(model, "_OUT_", out_shape);
439         REPLACE_WITH_NUM(model, "_BS_", p.block_size);
440
441         return model;
442     }
443
444 protected:
445     virtual void TearDown() {
446     }
447
448     virtual void SetUp() {
449         try {
450             TestsCommon::SetUp();
451             depth_to_space_test_params p = ::testing::WithParamInterface<depth_to_space_test_params>::GetParam();
452             std::string model = getModel(p);
453
454             InferenceEngine::CNNNetReader net_reader;
455             ASSERT_NO_THROW(net_reader.ReadNetwork(model.data(), model.length()));
456
457             InferenceEngine::Extension cpuExt(make_so_name("cpu_extension"));
458             MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr(new MKLDNNPlugin::MKLDNNExtensionManager());
459             extMgr->AddExtension(InferenceEngine::IExtensionPtr(&cpuExt, [](InferenceEngine::IExtension*) {}));
460
461             MKLDNNGraphTestClass graph;
462             graph.CreateGraph(net_reader.getNetwork(), extMgr);
463
464             // Output Data
465             InferenceEngine::OutputsDataMap out;
466             out = net_reader.getNetwork().getOutputsInfo();
467             InferenceEngine::BlobMap outputBlobs;
468
469             std::pair<std::string, InferenceEngine::DataPtr> item = *out.begin();
470
471             InferenceEngine::TBlob<float>::Ptr output;
472             output = InferenceEngine::make_shared_blob<float>(item.second->getTensorDesc());
473             output->allocate();
474             outputBlobs[item.first] = output;
475
476             // Input Data
477             InferenceEngine::Blob::Ptr src;
478             src = InferenceEngine::make_shared_blob<float>({ InferenceEngine::Precision::FP32, p.in_shape, InferenceEngine::TensorDesc::getLayoutByDims(p.in_shape) });
479             src->allocate();
480             fill_data_dbgval(src->buffer(), src->size());
481             auto * srcPtr = dynamic_cast<InferenceEngine::TBlob<float>*>(src.get());
482             if (srcPtr == nullptr)
483                 FAIL() << "Cannot cast blob to TBlob<float>.";
484
485             InferenceEngine::BlobMap srcs;
486             srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("input", src));
487
488             // Infer
489             graph.Infer(srcs, outputBlobs);
490             compare(*output, *src);
491         }
492         catch (const InferenceEngine::details::InferenceEngineException &e) {
493             FAIL() << e.what();
494         }
495     }
496 };
497
498 TEST_P(MKLDNNCPUExtDepthToSpaceTests, TestsDepthToSpace) {}
499 //  Test data vectors
500 static std::vector<float> test0 = { 0.f, 6.f, 1.f, 7.f, 2.f, 8.f, 12.f, 18.f, 13.f, 19.f, 14.f, 20.f, 3.f, 9.f, 4.f, 10.f, 5.f, 11.f, 15.f, 21.f, 16.f, 22.f, 17.f, 23.f};
501 INSTANTIATE_TEST_CASE_P(
502     TestsDepthToSpace, MKLDNNCPUExtDepthToSpaceTests,
503             ::testing::Values(
504 // Params: in_shape, block_size, out_shape, reference
505                 depth_to_space_test_params{ { 1, 4, 2, 3 }, 2, { 1, 1, 4, 6 }, test0 },
506                 depth_to_space_test_params{ { 4, 2, 3 }, 2, { 1, 1, 4, 6 }, test0 },
507                 depth_to_space_test_params{ { 1, 4, 2, 3 }, 2, { 4, 6 }, test0 },
508                 depth_to_space_test_params{ { 4, 2, 3 }, 2, { 4, 6 }, test0 },
509                 depth_to_space_test_params{ { 5, 4, 2, 3 }, 2, { 5, 1, 4, 6 }, test0 },
510                 depth_to_space_test_params{ { 2, 3, 5, 4, 2, 3 }, 2, { 2, 3, 5, 1, 4, 6 }, test0 }
511 ));
512
513
514 TEST_P(MKLDNNCPUExtDepthToSpaceToDepthTests, TestsDepthToSpaceToDepth) {}
515 INSTANTIATE_TEST_CASE_P(
516     TestsDepthToSpaceToDepth, MKLDNNCPUExtDepthToSpaceToDepthTests,
517     ::testing::Values(
518         // Params: in_shape, block_size, out_shape, reference
519         depth_to_space_test_params{ { 1, 9, 2, 3 }, 3,{ 1, 1, 6, 9 },{} },
520         depth_to_space_test_params{ { 16, 2, 3 }, 4,{ 1, 1, 8, 12 },{} },
521         depth_to_space_test_params{ { 1, 25, 4, 3 }, 5,{ 20, 15 },{} },
522         depth_to_space_test_params{ { 72, 10, 3 }, 6,{ 2, 60, 18 },{} },
523         depth_to_space_test_params{ { 5, 8, 2, 3 }, 2,{ 5, 2, 4, 6 },{} },
524         depth_to_space_test_params{ { 2, 3, 5, 16, 2, 3 }, 2,{ 2, 3, 5, 4, 4, 6 },{} }
525 ));