Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / helpers / single_layer_common.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <cmath>
6 #include <ie_blob.h>
7 #include <ie_layers_property.hpp>
8 #include <ie_precision.hpp>
9 #include <inference_engine/precision_utils.h>
10 #include <gtest/gtest.h>
11 #include "single_layer_common.hpp"
12 #include <math.h>
13
14 using namespace InferenceEngine;
15
16 void get_common_dims(const Blob &blob,
17                      int32_t &dimx,
18                      int32_t &dimy,
19                      int32_t &dimz) {
20     if (blob.dims().size() == 2) {
21         dimz = 1;
22         dimy = blob.dims()[1];
23         dimx = blob.dims()[0];
24     } else if (blob.dims().size() == 3 || (blob.dims().size() == 4 && blob.dims()[3] == 1)) {
25         dimx = blob.dims()[0];
26         dimy = blob.dims()[1];
27         dimz = blob.dims()[2];
28     }
29 }
30
31 void get_common_dims(const Blob &blob,
32                      int32_t &dimx,
33                      int32_t &dimy,
34                      int32_t &dimz,
35                      int32_t &dimn) {
36     dimn = 1;
37     if (blob.dims().size() == 2) {
38         dimz = 1;
39         dimy = blob.dims()[1];
40         dimx = blob.dims()[0];
41     } else if (blob.dims().size() == 3 || (blob.dims().size() == 4 && blob.dims()[3] == 1)) {
42         dimx = blob.dims()[0];
43         dimy = blob.dims()[1];
44         dimz = blob.dims()[2];
45     } else {
46         if (blob.dims().size() == 4 && blob.dims()[3] != 1) {
47             dimx = blob.dims()[0];
48             dimy = blob.dims()[1];
49             dimz = blob.dims()[2];
50             dimn = blob.dims()[3];
51         }
52     }
53 }
54
55 void GenRandomDataCommon(Blob::Ptr blob) {
56     if (blob->precision() == Precision::U8) {
57         auto * blobRawDataU8 = blob->buffer().as<uint8_t*>();
58         size_t count = blob->size();
59         for (size_t i = 0; i < count; i++) {
60             auto val = static_cast<uint8_t>(rand() % 256);
61             blobRawDataU8[i] = val;
62         }
63     } else if (blob->precision() == Precision::FP16) {
64         float scale = 2.0f / RAND_MAX;
65         /* fill by random data in the range (-1, 1)*/
66         auto * blobRawDataFp16 = blob->buffer().as<ie_fp16 *>();
67         size_t count = blob->size();
68         for (size_t indx = 0; indx < count; ++indx) {
69             float val = rand();
70             val = val * scale - 1.0f;
71             blobRawDataFp16[indx] = PrecisionUtils::f32tof16(val);
72         }
73     } else if (blob->precision() == Precision::FP32) {
74         float scale = 2.0f / RAND_MAX;
75         /* fill by random data in the range (-1, 1)*/
76         auto * blobRawDataFp16 = blob->buffer().as<float*>();
77         size_t count = blob->size();
78         for (size_t i = 0; i < count; i++) {
79             float val = rand();
80             val = val * scale - 1.0f;
81             blobRawDataFp16[i] = val;
82         }
83     }
84 }
85
86 BufferWrapper::BufferWrapper(const Blob::Ptr& blob) : BufferWrapper(blob, blob->precision()) {}
87
88 BufferWrapper::BufferWrapper(const Blob::Ptr& blob, Precision _precision) : precision(_precision) {
89     if (precision == Precision::FP16) {
90         fp16_ptr = blob->buffer().as<ie_fp16*>();
91     } else if (precision == Precision::FP32) {
92         fp32_ptr = blob->buffer().as<float*>();
93     } else {
94         THROW_IE_EXCEPTION << "Unsupported precision for compare: " << precision;
95     }
96 }
97
98 float BufferWrapper::operator[](size_t index) {
99     if (precision == Precision::FP16) return PrecisionUtils::f16tof32(fp16_ptr[index]);
100     return fp32_ptr[index];
101 }
102
103 void BufferWrapper::insert(size_t index, float value) {
104     if (precision == Precision::FP16) {
105         fp16_ptr[index] = PrecisionUtils::f32tof16(value);
106     } else {
107         fp32_ptr[index] = value;
108     }
109 }
110
111 void CompareCommon(const Blob::Ptr& actual, const Blob::Ptr& expected, float tolerance) {
112     ASSERT_NE(actual, nullptr);
113     ASSERT_NE(expected, nullptr);
114
115     Layout res_layout = actual->layout();
116     Layout ref_layout = expected->layout();
117     SizeVector res_dims = actual->getTensorDesc().getDims();
118
119     BufferWrapper res_ptr(actual);
120     BufferWrapper ref_ptr(expected);
121
122     size_t res_size = actual->size();
123     size_t ref_size = expected->size();
124     ASSERT_EQ(res_size, ref_size);
125
126     float max_error = 0;
127     size_t actualMaxErrId = 0;
128     size_t expectedMaxErrId = 0;
129
130     if (res_layout == NCHW || res_layout == NHWC) {
131         size_t N = res_dims[0];
132         size_t C = res_dims[1];
133         size_t H = res_dims[2];
134         size_t W = res_dims[3];
135
136         for (size_t n = 0; n < N; n++) {
137             for (size_t c = 0; c < C; c++) {
138                 for (size_t h = 0; h < H; h++) {
139                     for (size_t w = 0; w < W; w++) {
140                         size_t actualIdx = res_layout == NCHW ?
141                                            w + h * W + c * W * H + n * W * H * C : c + w * C + h * C * W +
142                                                                                    n * W * H * C;
143                         size_t expectedIdx = ref_layout == NCHW ?
144                                              w + h * W + c * W * H + n * W * H * C : c + w * C + h * C * W +
145                                                                                      n * C * W * H;
146                         float cur_diff = fabs(res_ptr[actualIdx] - ref_ptr[expectedIdx]);
147                         if (cur_diff > max_error) {
148                             max_error = cur_diff;
149                             actualMaxErrId = actualIdx;
150                             expectedMaxErrId = expectedIdx;
151                         }
152                     }
153                 }
154             }
155         }
156     } else {
157         if (res_layout == NC) {
158
159             size_t N = res_dims[0];
160             size_t C = res_dims[1];
161             for (size_t n = 0; n < N; n++) {
162                 for (size_t c = 0; c < C; c++) {
163                     size_t actualIdx =   c +  n * C;
164                     float cur_diff = fabs(res_ptr[actualIdx] - ref_ptr[actualIdx]);
165                     if (cur_diff > max_error) {
166                         max_error = cur_diff;
167                         actualMaxErrId = actualIdx;
168                         expectedMaxErrId = actualIdx;
169                     }
170                 }
171             }
172         } else {
173             for (size_t i = 0; i < ref_size; i++) {
174                 float cur_diff = fabs(res_ptr[i] - ref_ptr[i]);
175                 if (cur_diff > max_error) {
176                     max_error = cur_diff;
177                     actualMaxErrId = expectedMaxErrId = i;
178                 }
179             }
180         }
181     }
182
183     ASSERT_NEAR(ref_ptr[expectedMaxErrId], res_ptr[actualMaxErrId], tolerance)
184                                 << "expectedMaxErrId = " << expectedMaxErrId
185                                 << " actualMaxErrId = " << actualMaxErrId;
186 }
187
188 void fill_data_common(BufferWrapper& data, size_t size, size_t duty_ratio) {
189     for (size_t i = 0; i < size; i++) {
190         if ((i / duty_ratio) % 2 == 1) {
191             data.insert(i, 0.0);
192         } else {
193             data.insert(i, sin((float) i));
194         }
195     }
196 }