mvn_tests.cpp 14.2 KB
Newer Older
1
// Copyright (C) 2018-2019 Intel Corporation
openvino-pushbot's avatar
openvino-pushbot committed
2 3 4 5 6 7 8 9 10 11 12 13 14
// SPDX-License-Identifier: Apache-2.0
//

#include <gtest/gtest.h>
#include <gmock/gmock-spec-builders.h>
#include "mkldnn_plugin/mkldnn_graph.h"

#include "test_graph.hpp"

#include "single_layer_common.hpp"
#include <mkldnn_plugin/mkldnn_extension_utils.h>
#include <extension/ext_list.hpp>
#include "tests_common.hpp"
15
#include "ir_gen_helper.hpp"
openvino-pushbot's avatar
openvino-pushbot committed
16

17
using namespace InferenceEngine;
openvino-pushbot's avatar
openvino-pushbot committed
18 19 20
using namespace ::testing;
using namespace std;
using namespace mkldnn;
21
using namespace single_layer_tests;
openvino-pushbot's avatar
openvino-pushbot committed
22 23 24


struct mvn_test_params {
25 26
    // Formats: NCHW, NCDHW
    vector<size_t> dims;
openvino-pushbot's avatar
openvino-pushbot committed
27 28 29 30 31 32 33 34 35

    int across_channels;
    int normalize_variance;
    float eps;

    size_t num_prim_desc;
    bool isBlockedFormat;
    int selectedType;

36
    vector<std::function<void(MKLDNNPlugin::PrimitiveDescInfo)>> comp;
openvino-pushbot's avatar
openvino-pushbot committed
37 38
};

39 40
extern InferenceEngine::IExtensionPtr make_FakeExtensions();

openvino-pushbot's avatar
openvino-pushbot committed
41
template <typename data_t>
42
void ref_mvn(const TBlob<data_t> &src, TBlob<data_t> &dst, mvn_test_params prm) {
openvino-pushbot's avatar
openvino-pushbot committed
43 44
    const data_t *src_data = src.readOnly();
    data_t *dst_data = dst.data();
45
    size_t dims_size = prm.dims.size();
openvino-pushbot's avatar
openvino-pushbot committed
46

47 48 49 50 51
    size_t N = prm.dims[0];
    size_t C = prm.dims[1];
    size_t D = dims_size > 4 ? prm.dims[dims_size - 3lu] : 1lu;
    size_t H = dims_size > 3 ? prm.dims[dims_size - 2lu] : 1lu;
    size_t W = prm.dims[dims_size - 1lu];
openvino-pushbot's avatar
openvino-pushbot committed
52 53 54

    float eps = prm.eps;

55 56 57 58 59 60
    size_t C1 = H * W;
    size_t C2 = C1 * D;
    size_t C3 = C2 * C;

    for (size_t b = 0lu; b < N; b++) {
        size_t cb = b * C3;
openvino-pushbot's avatar
openvino-pushbot committed
61 62
        // Calculate mean value
        if (prm.across_channels) {
63 64 65 66 67 68 69 70 71 72
            double mean = 0.0;
            for (size_t c = 0lu; c < C; c++) {
                size_t cc = cb + c * C2;
                for (size_t d = 0lu; d < D; d++) {
                    size_t cd = cc + d * C1;
                    for (size_t h = 0lu; h < H; h++) {
                        size_t ch = cd + h * W;
                        for (size_t w = 0lu; w < W; w++) {
                            mean += src_data[ch + w];
                        }
openvino-pushbot's avatar
openvino-pushbot committed
73 74 75
                    }
                }
            }
76 77 78 79 80 81 82 83 84 85 86
            mean /= (double)C3;
            for (size_t c = 0lu; c < C; c++) {
                size_t cc = cb + c * C2;
                for (size_t d = 0lu; d < D; d++) {
                    size_t cd = cc + d * C1;
                    for (size_t h = 0lu; h < H; h++) {
                        size_t ch = cd + h * W;
                        for (size_t w = 0lu; w < W; w++) {
                            size_t index = ch + w;
                            dst_data[index] = src_data[index] - mean;
                        }
openvino-pushbot's avatar
openvino-pushbot committed
87 88 89 90
                    }
                }
            }
        } else {
91 92 93 94 95 96 97 98 99 100
            for (size_t c = 0lu; c < C; c++) {
                size_t cc = cb + c * C2;
                double mean = 0.0;
                for (size_t d = 0lu; d < D; d++) {
                    size_t cd = cc + d * C1;
                    for (size_t h = 0lu; h < H; h++) {
                        size_t ch = cd + h * W;
                        for (size_t w = 0lu; w < W; w++) {
                            mean += src_data[ch + w];
                        }
openvino-pushbot's avatar
openvino-pushbot committed
101 102 103
                    }
                }

104 105 106 107 108 109 110 111 112 113
                mean /= (double)C2;

                for (size_t d = 0lu; d < D; d++) {
                    size_t cd = cc + d * C1;
                    for (size_t h = 0lu; h < H; h++) {
                        size_t ch = cd + h * W;
                        for (size_t w = 0lu; w < W; w++) {
                            size_t index = ch + w;
                            dst_data[index] = src_data[index] - mean;
                        }
openvino-pushbot's avatar
openvino-pushbot committed
114 115 116 117 118 119 120
                    }
                }
            }
        }
    }

    if (prm.normalize_variance) {
121 122
        for (size_t b = 0; b < N; b++) {
            size_t cb = b * C3;
openvino-pushbot's avatar
openvino-pushbot committed
123 124
            // Calculate variances value
            if (prm.across_channels) {
125 126 127 128 129 130 131 132 133 134
                double variance = 0.f;
                for (size_t c = 0lu; c < C; c++) {
                    size_t cc = cb + c * C2;
                    for (size_t d = 0lu; d < D; d++) {
                        size_t cd = cc + d * C1;
                        for (size_t h = 0lu; h < H; h++) {
                            size_t ch = cd + h * W;
                            for (size_t w = 0lu; w < W; w++) {
                                variance += std::pow(dst_data[ch + w], 2);
                            }
openvino-pushbot's avatar
openvino-pushbot committed
135 136 137
                        }
                    }
                }
138
                variance /= C3;
openvino-pushbot's avatar
openvino-pushbot committed
139
                variance += eps;
140 141 142 143 144 145 146 147 148 149
                variance = std::pow(variance, 0.5f);
                for (size_t c = 0lu; c < C; c++) {
                    size_t cc = cb + c * C2;
                    for (size_t d = 0lu; d < D; d++) {
                        size_t cd = cc + d * C1;
                        for (size_t h = 0lu; h < H; h++) {
                            size_t ch = cd + h * W;
                            for (size_t w = 0lu; w < W; w++) {
                                dst_data[ch + w] /= variance;
                            }
openvino-pushbot's avatar
openvino-pushbot committed
150 151 152 153
                        }
                    }
                }
            } else {
154 155 156 157 158 159 160 161 162 163
                for (size_t c = 0lu; c < C; c++) {
                    size_t cc = cb + c * C2;
                    double variance = 0.0;
                    for (size_t d = 0lu; d < D; d++) {
                        size_t cd = cc + d * C1;
                        for (size_t h = 0lu; h < H; h++) {
                            size_t ch = cd + h * W;
                            for (size_t w = 0lu; w < W; w++) {
                                variance += std::pow(dst_data[ch + w], 2);
                            }
openvino-pushbot's avatar
openvino-pushbot committed
164 165
                        }
                    }
166
                    variance /= C2;
openvino-pushbot's avatar
openvino-pushbot committed
167
                    variance += eps;
168 169 170 171 172 173 174 175
                    variance = std::pow(variance, 0.5f);
                    for (size_t d = 0lu; d < D; d++) {
                        size_t cd = cc + d * C1;
                        for (size_t h = 0lu; h < H; h++) {
                            size_t ch = cd + h * W;
                            for (size_t w = 0lu; w < W; w++) {
                                dst_data[ch + w] /= variance;
                            }
openvino-pushbot's avatar
openvino-pushbot committed
176 177 178 179 180 181 182 183 184
                        }
                    }
                }
            }
        }
    }
}

class MKLDNNCPUExtMVNTests: public TestsCommon, public WithParamInterface<mvn_test_params> {
185
    std::string layers_t = R"V0G0N(
openvino-pushbot's avatar
openvino-pushbot committed
186 187 188
        <layer name="fakeLayer" id="1" type="_FL_" precision="FP32">
            <input>
                <port id="1">
189
                    __SRC_DIMS__
openvino-pushbot's avatar
openvino-pushbot committed
190 191 192 193
                </port>
            </input>
            <output>
                <port id="2">
194
                    __SRC_DIMS__
openvino-pushbot's avatar
openvino-pushbot committed
195 196 197 198 199 200 201
                </port>
            </output>
        </layer>
        <layer name="mvn" id="2" type="MVN" precision="FP32">
            <data across_channels="_AC_" normalize_variance="_NV_" eps="_EPS_"/>
            <input>
                <port id="3">
202
                    __SRC_DIMS__
openvino-pushbot's avatar
openvino-pushbot committed
203 204 205 206
                </port>
            </input>
            <output>
                <port id="4">
207
                    __SRC_DIMS__
openvino-pushbot's avatar
openvino-pushbot committed
208 209 210
                </port>
            </output>
        </layer>
211 212 213
)V0G0N";

    std::string edges_t = R"V0G0N(
openvino-pushbot's avatar
openvino-pushbot committed
214 215 216 217 218
        <edge from-layer="0" from-port="0" to-layer="1" to-port="1"/>
        <edge from-layer="1" from-port="2" to-layer="2" to-port="3"/>
)V0G0N";

    std::string getModel(mvn_test_params p) {
219
        std::string model = layers_t;
openvino-pushbot's avatar
openvino-pushbot committed
220 221 222 223 224
        if (p.isBlockedFormat)
            REPLACE_WITH_STR(model, "_FL_", "FakeLayerBLK");
        else
            REPLACE_WITH_STR(model, "_FL_", "FakeLayerPLN");

225 226 227 228 229 230
        std::string s_dims;
        for (auto& dim : p.dims) {
            s_dims += "\n                    <dim>";
            s_dims += std::to_string(dim) + "</dim>";
        }
	REPLACE_WITH_STR(model, "__SRC_DIMS__", s_dims);
openvino-pushbot's avatar
openvino-pushbot committed
231 232 233 234 235

        REPLACE_WITH_NUM(model, "_AC_", p.across_channels);
        REPLACE_WITH_NUM(model, "_NV_", p.normalize_variance);
        REPLACE_WITH_NUM(model, "_EPS_", p.eps);

236 237
        model = IRTemplateGenerator::getIRTemplate("MVN_Only", p.dims, "FP32", model, edges_t);

openvino-pushbot's avatar
openvino-pushbot committed
238 239 240 241 242 243 244 245 246 247 248 249 250
        return model;
    }

protected:
    virtual void TearDown() {
    }

    virtual void SetUp() {
        try {
            TestsCommon::SetUp();
            mvn_test_params p = ::testing::WithParamInterface<mvn_test_params>::GetParam();
            std::string model = getModel(p);

251
            CNNNetReader net_reader;
openvino-pushbot's avatar
openvino-pushbot committed
252 253
            ASSERT_NO_THROW(net_reader.ReadNetwork(model.data(), model.length()));

254
            InferenceEngine::Extension cpuExt(make_so_name("cpu_extension"));
openvino-pushbot's avatar
openvino-pushbot committed
255
            MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr(new MKLDNNPlugin::MKLDNNExtensionManager());
256 257 258
            extMgr->AddExtension(InferenceEngine::IExtensionPtr(&cpuExt, [](InferenceEngine::IExtension*){}));
            extMgr->AddExtension(make_FakeExtensions());

openvino-pushbot's avatar
openvino-pushbot committed
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281

            MKLDNNGraphTestClass graph;
            graph.CreateGraph(net_reader.getNetwork(), extMgr);

            auto& nodes = graph.getNodes();
            nodes = graph.getNodes();

            for (auto &node : nodes) {
                if (node->getName() == "mvn") {
                    ASSERT_EQ(p.num_prim_desc, node->getSupportedPrimitiveDescriptors().size());
                    for (size_t j = 0; j < p.num_prim_desc && j < p.comp.size(); j++) {
                        p.comp.at(j)(node->getSupportedPrimitiveDescriptors().at(j));
                    }
                    ASSERT_NE(nullptr, node->getSelectedPrimitiveDescriptor());
                    ASSERT_EQ(p.selectedType,
                              node->getSelectedPrimitiveDescriptor()->getImplementationType() & p.selectedType);
                }
            }
            if (p.isBlockedFormat)
                ASSERT_EQ(6, nodes.size());
            else
                ASSERT_EQ(5, nodes.size()); // TODO: should be 4 (redudant reorder in case of both layers are inplace)

282 283 284 285 286 287 288 289 290 291 292
            SizeVector dims_src = p.dims;

            Layout layout = ANY;
            switch (p.dims.size()) {
                case 4:
                    layout = NCHW;
                    break;
                case 5:
                    layout = NCDHW;
                    break;
            }
openvino-pushbot's avatar
openvino-pushbot committed
293

294
            Blob::Ptr src = make_shared_blob<float>({ Precision::FP32, dims_src, layout });
openvino-pushbot's avatar
openvino-pushbot committed
295 296 297
            src->allocate();
            fill_data(src->buffer(), src->size());

298
            auto * srcPtr = dynamic_cast<TBlob<float>*>(src.get());
openvino-pushbot's avatar
openvino-pushbot committed
299 300 301 302

            if (srcPtr == nullptr)
                FAIL() << "Cannot cast blob to TBlob<float>.";

303 304
            BlobMap srcs;
            srcs.insert(std::pair<std::string, Blob::Ptr>("in1", src));
openvino-pushbot's avatar
openvino-pushbot committed
305

306
            OutputsDataMap out;
openvino-pushbot's avatar
openvino-pushbot committed
307
            out = net_reader.getNetwork().getOutputsInfo();
308
            BlobMap outputBlobs;
openvino-pushbot's avatar
openvino-pushbot committed
309

310
            std::pair<std::string, DataPtr> item = *out.begin();
openvino-pushbot's avatar
openvino-pushbot committed
311

312 313
            TBlob<float>::Ptr output;
            output = make_shared_blob<float>(item.second->getTensorDesc());
openvino-pushbot's avatar
openvino-pushbot committed
314 315 316 317 318
            output->allocate();
            outputBlobs[item.first] = output;

            graph.Infer(srcs, outputBlobs);

319
            TBlob<float> dst_ref(item.second->getTensorDesc());
openvino-pushbot's avatar
openvino-pushbot committed
320 321
            dst_ref.allocate();
            ref_mvn(*srcPtr, dst_ref, p);
322 323
            compare(*output, dst_ref, 0.0001f);
        } catch (const details::InferenceEngineException &e) {
openvino-pushbot's avatar
openvino-pushbot committed
324 325 326 327 328 329 330 331 332 333
            FAIL() << e.what();
        }
    }
};

TEST_P(MKLDNNCPUExtMVNTests, TestsMVN) {}

INSTANTIATE_TEST_CASE_P(
        TestsMVN, MKLDNNCPUExtMVNTests,
        ::testing::Values(
334
        /*0*/   mvn_test_params{{2, 64, 15, 15}, 0, 0, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
openvino-pushbot's avatar
openvino-pushbot committed
335 336 337 338 339 340 341 342
                mvn_test_params{{2,  2, 33, 65}, 0, 0, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 15, 15}, 0, 1, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2,  2, 33, 65}, 0, 1, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 15, 15}, 1, 0, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2,  2, 33, 65}, 1, 0, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 15, 15}, 1, 1, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2,  2, 33, 65}, 1, 1, 0.00001, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 15, 15}, 0, 0, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
343
        /*9*/   mvn_test_params{{2,  2, 33, 65}, 0, 0, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
openvino-pushbot's avatar
openvino-pushbot committed
344 345 346 347
                mvn_test_params{{2, 64, 15, 15}, 0, 1, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2,  2, 33, 65}, 0, 1, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 15, 15}, 1, 0, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2,  2, 33, 65}, 1, 0, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
348 349 350 351 352 353 354 355 356 357 358 359 360 361
        /*14*/  mvn_test_params{{2,640, 15, 15}, 1, 1, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2,  2, 33, 65}, 1, 1, 0.00001, 2, true, MKLDNNPlugin::impl_desc_type::unknown },

                // 5D
        /*16*/  mvn_test_params{{2, 64, 24, 32, 40}, 0, 0, 0.00001f, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 24, 32, 40}, 0, 1, 0.00001f, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 24, 32, 40}, 1, 0, 0.00001f, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 24, 32, 40}, 1, 1, 0.00001f, 2, false, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 24, 32, 40}, 0, 0, 0.00001f, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 24, 32, 40}, 0, 1, 0.00001f, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{2, 64, 24, 32, 40}, 1, 0, 0.00001f, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
        /*23*/  mvn_test_params{{2, 64, 24, 32, 40}, 1, 1, 0.00001f, 2, true, MKLDNNPlugin::impl_desc_type::unknown },
                mvn_test_params{{1, 64, 32, 32, 32}, 0, 1, 0.001f, 2, true, MKLDNNPlugin::impl_desc_type::unknown }
            ));