publish master branch snapshot, revision 9df5eb1f84e13a35720a918f88324561222ab114
[platform/upstream/dldt.git] / inference-engine / tests / ie_test_utils / functional_test_utils / layer_test_utils.cpp
1 // Copyright (C) 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() {
10     core = PluginCache::get().ie(targetDevice).get();
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() || targetDevice.find(CommonTestUtils::DEVICE_GPU) != std::string::npos) {
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     const auto &size = actual->size();
43     switch (precision) {
44         case InferenceEngine::Precision::FP32:
45             Compare(reinterpret_cast<const float *>(expectedBuffer), reinterpret_cast<const float *>(actualBuffer),
46                     size, 1e-2f);
47             break;
48         case InferenceEngine::Precision::I32:
49             Compare(reinterpret_cast<const std::int32_t *>(expectedBuffer),
50                     reinterpret_cast<const std::int32_t *>(actualBuffer), size, 0);
51             break;
52         default:
53             FAIL() << "Comparator for " << precision << " precision isn't supported";
54     }
55 }
56
57 void LayerTestsCommon::ConfigurePlugin() const {
58     if (!configuration.empty()) {
59         core->SetConfig(configuration, targetDevice);
60     }
61 }
62
63 void LayerTestsCommon::ConfigureNetwork() const {
64     for (const auto &in : cnnNetwork.getInputsInfo()) {
65         if (inLayout != InferenceEngine::Layout::ANY) {
66             in.second->setLayout(inLayout);
67         }
68         if (inPrc != InferenceEngine::Precision::UNSPECIFIED) {
69             in.second->setPrecision(inPrc);
70         }
71     }
72
73     for (const auto &out : cnnNetwork.getOutputsInfo()) {
74         if (outLayout != InferenceEngine::Layout::ANY) {
75             out.second->setLayout(outLayout);
76         }
77         if (outPrc != InferenceEngine::Precision::UNSPECIFIED) {
78             out.second->setPrecision(outPrc);
79         }
80     }
81 }
82
83 void LayerTestsCommon::LoadNetwork() {
84     cnnNetwork = InferenceEngine::CNNNetwork{function};
85     ConfigureNetwork();
86     executableNetwork = core->LoadNetwork(cnnNetwork, targetDevice);
87 }
88
89 void LayerTestsCommon::Infer() {
90     inferRequest = executableNetwork.CreateInferRequest();
91
92     for (const auto &input : cnnNetwork.getInputsInfo()) {
93         const auto &info = input.second;
94
95         auto blob = GenerateInput(*info);
96         inferRequest.SetBlob(info->name(), blob);
97         inputs.push_back(blob);
98     }
99     inferRequest.Infer();
100 }
101
102 std::vector<std::vector<std::uint8_t>> LayerTestsCommon::CalculateRefs() {
103     // nGraph interpreter does not support f16
104     // IE converts f16 to f32
105     ngraph::pass::ConvertPrecision<ngraph::element::Type_t::f16, ngraph::element::Type_t::f32>().run_on_function(function);
106     function->validate_nodes_and_infer_types();
107     auto referenceInputs = std::vector<std::vector<std::uint8_t>>(inputs.size());
108     for (std::size_t i = 0; i < inputs.size(); ++i) {
109         const auto& input = inputs[i];
110         const auto& inputSize = input->byteSize();
111
112         auto& referenceInput = referenceInputs[i];
113         referenceInput.resize(inputSize);
114
115         auto memory = InferenceEngine::as<InferenceEngine::MemoryBlob>(input);
116         IE_ASSERT(memory);
117         const auto lockedMemory = memory->wmap();
118         const auto buffer = lockedMemory.as<const std::uint8_t*>();
119         std::copy(buffer, buffer + inputSize, referenceInput.data());
120     }
121
122     const auto &actualOutputs = GetOutputs();
123     const auto &convertType = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(actualOutputs[0]->getTensorDesc().getPrecision());
124     std::vector<std::vector<std::uint8_t>> expectedOutputs;
125     switch (refMode) {
126         case INTERPRETER: {
127             expectedOutputs = ngraph::helpers::interpreterFunction(function, referenceInputs, convertType);
128             break;
129         }
130         case CONSTANT_FOLDING: {
131             const auto &foldedFunc = ngraph::helpers::foldFunction(function, referenceInputs);
132             expectedOutputs = ngraph::helpers::getConstData(foldedFunc, convertType);
133             break;
134         }
135         case IE: {
136             // reference inference on device with other options and nGraph function has to be implemented here
137             break;
138         }
139     }
140
141     return expectedOutputs;
142 }
143
144 std::vector<InferenceEngine::Blob::Ptr> LayerTestsCommon::GetOutputs() {
145     auto outputs = std::vector<InferenceEngine::Blob::Ptr>{};
146     for (const auto &output : cnnNetwork.getOutputsInfo()) {
147         const auto &name = output.first;
148         outputs.push_back(inferRequest.GetBlob(name));
149     }
150     return outputs;
151 }
152
153 void LayerTestsCommon::Compare(const std::vector<std::vector<std::uint8_t>>& expectedOutputs, const std::vector<InferenceEngine::Blob::Ptr>& actualOutputs) {
154     for (std::size_t outputIndex = 0; outputIndex < expectedOutputs.size(); ++outputIndex) {
155         const auto& expected = expectedOutputs[outputIndex];
156         const auto& actual = actualOutputs[outputIndex];
157         Compare(expected, actual);
158     }
159 }
160
161 void LayerTestsCommon::Validate() {
162     auto expectedOutputs = CalculateRefs();
163     const auto& actualOutputs = GetOutputs();
164
165     if (expectedOutputs.empty()) {
166         return;
167     }
168
169     IE_ASSERT(actualOutputs.size() == expectedOutputs.size())
170         << "nGraph interpreter has " << expectedOutputs.size() << " outputs, while IE " << actualOutputs.size();
171
172     Compare(expectedOutputs, actualOutputs);
173 }
174
175 void LayerTestsCommon::SetRefMode(RefMode mode) {
176     refMode = mode;
177 }
178 }  // namespace LayerTestsUtils