[IE TESTS] dynavic batch for mvn layer (#1010)
[platform/upstream/dldt.git] / inference-engine / tests / ie_test_utils / functional_test_utils / layer_test_utils.cpp
1 // Copyright (C) 2019-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include "layer_test_utils.hpp"
6
7 namespace LayerTestsUtils {
8
9 LayerTestsCommon::LayerTestsCommon() : threshold(1e-2f) {
10     core = PluginCache::get().ie(targetDevice);
11 }
12
13 void LayerTestsCommon::Run() {
14     SKIP_IF_CURRENT_TEST_IS_DISABLED()
15
16     ConfigurePlugin();
17     LoadNetwork();
18     Infer();
19     Validate();
20 }
21
22 LayerTestsCommon::~LayerTestsCommon() {
23     if (!configuration.empty()) {
24         PluginCache::get().reset();
25     }
26 }
27
28 InferenceEngine::Blob::Ptr LayerTestsCommon::GenerateInput(const InferenceEngine::InputInfo &info) const {
29     return FuncTestUtils::createAndFillBlob(info.getTensorDesc());
30 }
31
32 void LayerTestsCommon::Compare(const std::vector<std::uint8_t> &expected, const InferenceEngine::Blob::Ptr &actual) {
33     ASSERT_EQ(expected.size(), actual->byteSize());
34     const auto &expectedBuffer = expected.data();
35
36     auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(actual);
37     IE_ASSERT(memory);
38     const auto lockedMemory = memory->wmap();
39     const auto actualBuffer = lockedMemory.as<const std::uint8_t *>();
40
41     const auto &precision = actual->getTensorDesc().getPrecision();
42     auto bufferSize = actual->size();
43     // With dynamic batch, you need to size
44     if (configuration.count(InferenceEngine::PluginConfigParams::KEY_DYN_BATCH_ENABLED)) {
45         auto batchSize = actual->getTensorDesc().getDims()[0];
46         auto halfBatchSize = batchSize > 1 ? batchSize/ 2 : 1;
47         bufferSize = (actual->size() * halfBatchSize / batchSize);
48     }
49     const auto &size = bufferSize;
50     switch (precision) {
51         case InferenceEngine::Precision::FP32:
52             Compare(reinterpret_cast<const float *>(expectedBuffer), reinterpret_cast<const float *>(actualBuffer),
53                     size, threshold);
54             break;
55         case InferenceEngine::Precision::I32:
56             Compare(reinterpret_cast<const std::int32_t *>(expectedBuffer),
57                     reinterpret_cast<const std::int32_t *>(actualBuffer), size, 0);
58             break;
59         default:
60             FAIL() << "Comparator for " << precision << " precision isn't supported";
61     }
62 }
63
64 void LayerTestsCommon::ConfigurePlugin() {
65     if (!configuration.empty()) {
66         core->SetConfig(configuration, targetDevice);
67     }
68 }
69
70 void LayerTestsCommon::ConfigureNetwork() const {
71     for (const auto &in : cnnNetwork.getInputsInfo()) {
72         if (inLayout != InferenceEngine::Layout::ANY) {
73             in.second->setLayout(inLayout);
74         }
75         if (inPrc != InferenceEngine::Precision::UNSPECIFIED) {
76             in.second->setPrecision(inPrc);
77         }
78     }
79
80     for (const auto &out : cnnNetwork.getOutputsInfo()) {
81         if (outLayout != InferenceEngine::Layout::ANY) {
82             out.second->setLayout(outLayout);
83         }
84         if (outPrc != InferenceEngine::Precision::UNSPECIFIED) {
85             out.second->setPrecision(outPrc);
86         }
87     }
88 }
89
90 void LayerTestsCommon::LoadNetwork() {
91     cnnNetwork = InferenceEngine::CNNNetwork{function};
92     ConfigureNetwork();
93     executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice);
94 }
95
96 void LayerTestsCommon::Infer() {
97     inferRequest = executableNetwork.CreateInferRequest();
98     inputs.clear();
99
100     for (const auto &input : cnnNetwork.getInputsInfo()) {
101         const auto &info = input.second;
102         auto blob = GenerateInput(*info);
103         inferRequest.SetBlob(info->name(), blob);
104         inputs.push_back(blob);
105     }
106     if (configuration.count(InferenceEngine::PluginConfigParams::KEY_DYN_BATCH_ENABLED) &&
107         configuration.count(InferenceEngine::PluginConfigParams::YES)) {
108         auto batchSize = cnnNetwork.getInputsInfo().begin()->second->getTensorDesc().getDims()[0] / 2;
109         inferRequest.SetBatch(batchSize);
110     }
111     inferRequest.Infer();
112 }
113
114 std::vector<std::vector<std::uint8_t>> LayerTestsCommon::CalculateRefs() {
115     // nGraph interpreter does not support f16
116     // IE converts f16 to f32
117     ngraph::pass::ConvertPrecision<ngraph::element::Type_t::f16, ngraph::element::Type_t::f32>().run_on_function(function);
118     function->validate_nodes_and_infer_types();
119     auto referenceInputs = std::vector<std::vector<std::uint8_t>>(inputs.size());
120     for (std::size_t i = 0; i < inputs.size(); ++i) {
121         const auto& input = inputs[i];
122         const auto& inputSize = input->byteSize();
123
124         auto& referenceInput = referenceInputs[i];
125         referenceInput.resize(inputSize);
126
127         auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(input);
128         IE_ASSERT(memory);
129         const auto lockedMemory = memory->wmap();
130         const auto buffer = lockedMemory.as<const std::uint8_t*>();
131         std::copy(buffer, buffer + inputSize, referenceInput.data());
132     }
133
134     const auto &actualOutputs = GetOutputs();
135     const auto &convertType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(actualOutputs[0]->getTensorDesc().getPrecision());
136     std::vector<std::vector<std::uint8_t>> expectedOutputs;
137     switch (refMode) {
138         case INTERPRETER: {
139             expectedOutputs = ngraph::helpers::interpreterFunction(function, referenceInputs, convertType);
140             break;
141         }
142         case CONSTANT_FOLDING: {
143             const auto &foldedFunc = ngraph::helpers::foldFunction(function, referenceInputs);
144             expectedOutputs = ngraph::helpers::getConstData(foldedFunc, convertType);
145             break;
146         }
147         case IE: {
148             // reference inference on device with other options and nGraph function has to be implemented here
149             break;
150         }
151     }
152
153     return expectedOutputs;
154 }
155
156 std::vector<InferenceEngine::Blob::Ptr> LayerTestsCommon::GetOutputs() {
157     auto outputs = std::vector<InferenceEngine::Blob::Ptr>{};
158     for (const auto &output : cnnNetwork.getOutputsInfo()) {
159         const auto &name = output.first;
160         outputs.push_back(inferRequest.GetBlob(name));
161     }
162     return outputs;
163 }
164
165 void LayerTestsCommon::Compare(const std::vector<std::vector<std::uint8_t>>& expectedOutputs, const std::vector<InferenceEngine::Blob::Ptr>& actualOutputs) {
166     for (std::size_t outputIndex = 0; outputIndex < expectedOutputs.size(); ++outputIndex) {
167         const auto& expected = expectedOutputs[outputIndex];
168         const auto& actual = actualOutputs[outputIndex];
169         Compare(expected, actual);
170     }
171 }
172
173 void LayerTestsCommon::Validate() {
174     auto expectedOutputs = CalculateRefs();
175     const auto& actualOutputs = GetOutputs();
176
177     if (expectedOutputs.empty()) {
178         return;
179     }
180
181     IE_ASSERT(actualOutputs.size() == expectedOutputs.size())
182         << "nGraph interpreter has " << expectedOutputs.size() << " outputs, while IE " << actualOutputs.size();
183
184     Compare(expectedOutputs, actualOutputs);
185 }
186
187 void LayerTestsCommon::SetRefMode(RefMode mode) {
188     refMode = mode;
189 }
190 }  // namespace LayerTestsUtils