Move legacy transformations and ops to legacy library (#2624)
[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 <transformations/op_conversions/convert_batch_to_space.hpp>
6 #include <transformations/op_conversions/convert_space_to_batch.hpp>
7
8 #include "layer_test_utils.hpp"
9
10 namespace LayerTestsUtils {
11
12 LayerTestsCommon::LayerTestsCommon() : threshold(1e-2f) {
13     core = PluginCache::get().ie(targetDevice);
14 }
15
16 void LayerTestsCommon::Run() {
17     SKIP_IF_CURRENT_TEST_IS_DISABLED()
18
19     LoadNetwork();
20     Infer();
21     Validate();
22 }
23
24 InferenceEngine::Blob::Ptr LayerTestsCommon::GenerateInput(const InferenceEngine::InputInfo &info) const {
25     return FuncTestUtils::createAndFillBlob(info.getTensorDesc());
26 }
27
28 void LayerTestsCommon::Compare(const std::vector<std::uint8_t> &expected, const InferenceEngine::Blob::Ptr &actual) {
29     ASSERT_EQ(expected.size(), actual->byteSize());
30     const auto &expectedBuffer = expected.data();
31
32     auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(actual);
33     IE_ASSERT(memory);
34     const auto lockedMemory = memory->wmap();
35     const auto actualBuffer = lockedMemory.as<const std::uint8_t *>();
36
37     const auto &precision = actual->getTensorDesc().getPrecision();
38     const auto &size = actual->size();
39     switch (precision) {
40         case InferenceEngine::Precision::FP32:
41             Compare(reinterpret_cast<const float *>(expectedBuffer), reinterpret_cast<const float *>(actualBuffer),
42                     size, threshold);
43             break;
44         case InferenceEngine::Precision::I32:
45             Compare(reinterpret_cast<const std::int32_t *>(expectedBuffer),
46                     reinterpret_cast<const std::int32_t *>(actualBuffer), size, 0);
47             break;
48         default:
49             FAIL() << "Comparator for " << precision << " precision isn't supported";
50     }
51 }
52
53 void LayerTestsCommon::Compare(const InferenceEngine::Blob::Ptr &expected, const InferenceEngine::Blob::Ptr &actual) {
54     auto get_raw_buffer = [] (const InferenceEngine::Blob::Ptr &blob) {
55         auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(blob);
56         IE_ASSERT(memory);
57         const auto lockedMemory = memory->wmap();
58         return lockedMemory.as<const std::uint8_t *>();
59     };
60     const auto expectedBuffer = get_raw_buffer(expected);
61     const auto actualBuffer = get_raw_buffer(actual);
62
63     const auto &precision = actual->getTensorDesc().getPrecision();
64     const auto &size = actual->size();
65     switch (precision) {
66         case InferenceEngine::Precision::FP32:
67             Compare(reinterpret_cast<const float *>(expectedBuffer), reinterpret_cast<const float *>(actualBuffer),
68                     size, threshold);
69             break;
70         case InferenceEngine::Precision::I32:
71             Compare(reinterpret_cast<const std::int32_t *>(expectedBuffer),
72                     reinterpret_cast<const std::int32_t *>(actualBuffer), size, 0);
73             break;
74         default:
75             FAIL() << "Comparator for " << precision << " precision isn't supported";
76     }
77 }
78
79 void LayerTestsCommon::ConfigureNetwork() const {
80     for (const auto &in : cnnNetwork.getInputsInfo()) {
81         if (inLayout != InferenceEngine::Layout::ANY) {
82             in.second->setLayout(inLayout);
83         }
84         if (inPrc != InferenceEngine::Precision::UNSPECIFIED) {
85             in.second->setPrecision(inPrc);
86         }
87     }
88
89     for (const auto &out : cnnNetwork.getOutputsInfo()) {
90         if (outLayout != InferenceEngine::Layout::ANY) {
91             out.second->setLayout(outLayout);
92         }
93         if (outPrc != InferenceEngine::Precision::UNSPECIFIED) {
94             out.second->setPrecision(outPrc);
95         }
96     }
97 }
98
99 void LayerTestsCommon::LoadNetwork() {
100     cnnNetwork = InferenceEngine::CNNNetwork{function};
101     ConfigureNetwork();
102     executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice, configuration);
103 }
104
105 void LayerTestsCommon::Infer() {
106     inferRequest = executableNetwork.CreateInferRequest();
107     inputs.clear();
108
109     for (const auto &input : executableNetwork.GetInputsInfo()) {
110         const auto &info = input.second;
111         auto blob = GenerateInput(*info);
112         inferRequest.SetBlob(info->name(), blob);
113         inputs.push_back(blob);
114     }
115     if (configuration.count(InferenceEngine::PluginConfigParams::KEY_DYN_BATCH_ENABLED) &&
116         configuration.count(InferenceEngine::PluginConfigParams::YES)) {
117         auto batchSize = executableNetwork.GetInputsInfo().begin()->second->getTensorDesc().getDims()[0] / 2;
118         inferRequest.SetBatch(batchSize);
119     }
120     inferRequest.Infer();
121 }
122
123 std::vector<std::vector<std::uint8_t>> LayerTestsCommon::CalculateRefs() {
124     // nGraph interpreter does not support f16
125     // IE converts f16 to f32
126     ngraph::pass::ConvertPrecision<ngraph::element::Type_t::f16, ngraph::element::Type_t::f32>().run_on_function(function);
127     function->validate_nodes_and_infer_types();
128     auto referenceInputs = std::vector<std::vector<std::uint8_t>>(inputs.size());
129     for (std::size_t i = 0; i < inputs.size(); ++i) {
130         const auto& input = inputs[i];
131         const auto& inputSize = input->byteSize();
132
133         auto& referenceInput = referenceInputs[i];
134         referenceInput.resize(inputSize);
135
136         auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(input);
137         IE_ASSERT(memory);
138         const auto lockedMemory = memory->wmap();
139         const auto buffer = lockedMemory.as<const std::uint8_t*>();
140         std::copy(buffer, buffer + inputSize, referenceInput.data());
141     }
142
143     auto ieOutPrc = outPrc;
144     if (outPrc == InferenceEngine::Precision::UNSPECIFIED) {
145         const auto &actualOutputs = GetOutputs();
146         ieOutPrc = actualOutputs[0]->getTensorDesc().getPrecision();
147     }
148
149     const auto &convertType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(ieOutPrc);
150     std::vector<std::vector<std::uint8_t>> expectedOutputs;
151     switch (refMode) {
152         case INTERPRETER: {
153             expectedOutputs = ngraph::helpers::interpreterFunction(function, referenceInputs, convertType);
154             break;
155         }
156         case CONSTANT_FOLDING: {
157             const auto &foldedFunc = ngraph::helpers::foldFunction(function, referenceInputs);
158             expectedOutputs = ngraph::helpers::getConstData(foldedFunc, convertType);
159             break;
160         }
161         case IE: {
162             // reference inference on device with other options and nGraph function has to be implemented here
163             break;
164         }
165         case INTERPRETER_TRANSFORMATIONS: {
166             auto cloned_function = ngraph::clone_function(*function);
167
168             // todo: add functionality to configure the necessary transformations for each test separately
169             ngraph::pass::Manager m;
170             m.register_pass<ngraph::pass::ConvertSpaceToBatch>();
171             m.register_pass<ngraph::pass::ConvertBatchToSpace>();
172             m.run_passes(cloned_function);
173             expectedOutputs = ngraph::helpers::interpreterFunction(cloned_function, referenceInputs, convertType);
174             break;
175         }
176     }
177
178     return expectedOutputs;
179 }
180
181 std::vector<InferenceEngine::Blob::Ptr> LayerTestsCommon::GetOutputs() {
182     auto outputs = std::vector<InferenceEngine::Blob::Ptr>{};
183     for (const auto &output : executableNetwork.GetOutputsInfo()) {
184         const auto &name = output.first;
185         outputs.push_back(inferRequest.GetBlob(name));
186     }
187     return outputs;
188 }
189
190 void LayerTestsCommon::Compare(const std::vector<std::vector<std::uint8_t>>& expectedOutputs, const std::vector<InferenceEngine::Blob::Ptr>& actualOutputs) {
191     for (std::size_t outputIndex = 0; outputIndex < expectedOutputs.size(); ++outputIndex) {
192         const auto& expected = expectedOutputs[outputIndex];
193         const auto& actual = actualOutputs[outputIndex];
194         Compare(expected, actual);
195     }
196 }
197
198 void LayerTestsCommon::Validate() {
199     auto expectedOutputs = CalculateRefs();
200     const auto& actualOutputs = GetOutputs();
201
202     if (expectedOutputs.empty()) {
203         return;
204     }
205
206     IE_ASSERT(actualOutputs.size() == expectedOutputs.size())
207         << "nGraph interpreter has " << expectedOutputs.size() << " outputs, while IE " << actualOutputs.size();
208
209     Compare(expectedOutputs, actualOutputs);
210 }
211
212 void LayerTestsCommon::SetRefMode(RefMode mode) {
213     refMode = mode;
214 }
215 }  // namespace LayerTestsUtils