1
// Copyright (C) 2019 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
11
#include <format_reader_ptr.h>
12
#include <samples/slog.hpp>
14
#include "inputs_filling.hpp"
16
using namespace InferenceEngine;
19
static const std::vector<std::string> supported_image_extensions = { "bmp", "dib",
27
static const std::vector<std::string> supported_image_extensions = { "bmp" };
29
static const std::vector<std::string> supported_binary_extensions = { "bin" };
31
std::vector<std::string> filterFilesByExtensions(const std::vector<std::string>& filePaths,
32
const std::vector<std::string>& extensions) {
33
std::vector<std::string> filtered;
34
auto getExtension = [](const std::string &name) {
35
auto extensionPosition = name.rfind('.', name.size());
36
return extensionPosition == std::string::npos ? "" : name.substr(extensionPosition + 1, name.size() - 1);
38
for (auto& filePath : filePaths) {
39
auto extension = getExtension(filePath);
40
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
41
if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) {
42
filtered.push_back(filePath);
48
void fillBlobImage(Blob::Ptr& inputBlob,
49
const std::vector<std::string>& filePaths,
50
const size_t& batchSize,
51
const InputInfo& info,
52
const size_t& requestId,
53
const size_t& inputId,
54
const size_t& inputSize) {
55
auto inputBlobData = inputBlob->buffer().as<uint8_t*>();
56
const TensorDesc& inputBlobDesc = inputBlob->getTensorDesc();
58
/** Collect images data ptrs **/
59
std::vector<std::shared_ptr<uint8_t>> vreader;
60
vreader.reserve(batchSize);
62
for (size_t i = 0ULL, inputIndex = requestId*batchSize*inputSize + inputId; i < batchSize; i++, inputIndex += inputSize) {
63
inputIndex %= filePaths.size();
65
slog::info << "Prepare image " << filePaths[inputIndex] << slog::endl;
66
FormatReader::ReaderPtr reader(filePaths[inputIndex].c_str());
67
if (reader.get() == nullptr) {
68
slog::warn << "Image " << filePaths[inputIndex] << " cannot be read!" << slog::endl << slog::endl;
72
/** Getting image data **/
73
TensorDesc desc = info.getTensorDesc();
74
std::shared_ptr<uint8_t> imageData(reader->getData(getTensorWidth(desc), getTensorHeight(desc)));
76
vreader.push_back(imageData);
80
/** Fill input tensor with images. First b channel, then g and r channels **/
81
const size_t numChannels = getTensorChannels(inputBlobDesc);
82
const size_t imageSize = getTensorWidth(inputBlobDesc) * getTensorHeight(inputBlobDesc);
83
/** Iterate over all input images **/
84
for (size_t imageId = 0; imageId < vreader.size(); ++imageId) {
85
/** Iterate over all pixel in image (b,g,r) **/
86
for (size_t pid = 0; pid < imageSize; pid++) {
87
/** Iterate over all channels **/
88
for (size_t ch = 0; ch < numChannels; ++ch) {
89
/** [images stride + channels stride + pixel id ] all in bytes **/
90
inputBlobData[imageId * imageSize * numChannels + ch * imageSize + pid] = vreader.at(imageId).get()[pid*numChannels + ch];
97
void fillBlobBinary(Blob::Ptr& inputBlob,
98
const std::vector<std::string>& filePaths,
99
const size_t& batchSize,
100
const size_t& requestId,
101
const size_t& inputId,
102
const size_t& inputSize) {
103
auto inputBlobData = inputBlob->buffer().as<T*>();
104
for (size_t i = 0ULL, inputIndex = requestId*batchSize*inputSize + inputId; i < batchSize; i++, inputIndex += inputSize) {
105
inputIndex %= filePaths.size();
107
slog::info << "Prepare binary file " << filePaths[inputIndex] << slog::endl;
108
std::ifstream binaryFile(filePaths[inputIndex], std::ios_base::binary | std::ios_base::ate);
110
THROW_IE_EXCEPTION << "Cannot open " << filePaths[inputIndex];
113
auto fileSize = static_cast<std::size_t>(binaryFile.tellg());
114
binaryFile.seekg(0, std::ios_base::beg);
115
if (!binaryFile.good()) {
116
THROW_IE_EXCEPTION << "Can not read " << filePaths[inputIndex];
119
auto inputSize = inputBlob->size()*sizeof(T)/batchSize;
120
if (fileSize != inputSize) {
121
THROW_IE_EXCEPTION << "File " << filePaths[inputIndex] << " contains " << std::to_string(fileSize) << " bytes "
122
"but the network expects " << std::to_string(inputSize);
124
binaryFile.read(reinterpret_cast<char *>(&inputBlobData[i*inputSize]), inputSize);
129
void fillBlobRandom(Blob::Ptr& inputBlob) {
130
auto inputBlobData = inputBlob->buffer().as<T*>();
131
for (size_t i = 0; i < inputBlob->size(); i++) {
132
inputBlobData[i] = (T) rand() / RAND_MAX * 10;
137
void fillBlobImInfo(Blob::Ptr& inputBlob,
138
const size_t& batchSize,
139
std::pair<size_t, size_t> image_size) {
140
auto inputBlobData = inputBlob->buffer().as<T*>();
141
for (size_t b = 0; b < batchSize; b++) {
142
size_t iminfoSize = inputBlob->size()/batchSize;
143
for (size_t i = 0; i < iminfoSize; i++) {
144
size_t index = b*iminfoSize + i;
146
inputBlobData[index] = static_cast<T>(image_size.first);
148
inputBlobData[index] = static_cast<T>(image_size.second);
150
inputBlobData[index] = 1;
155
void fillBlobs(const std::vector<std::string>& inputFiles,
156
const size_t& batchSize,
157
const InferenceEngine::InputsDataMap& info,
158
std::vector<InferReqWrap::Ptr> requests) {
159
std::vector<std::pair<size_t, size_t>> input_image_sizes;
160
for (const InputsDataMap::value_type& item : info) {
161
if (isImage(item.second)) {
162
input_image_sizes.push_back(std::make_pair(getTensorWidth(item.second->getTensorDesc()),
163
getTensorHeight(item.second->getTensorDesc())));
165
slog::info << "Network input '" << item.first << "' precision " << item.second->getTensorDesc().getPrecision()
166
<< ", dimensions (" << item.second->getTensorDesc().getLayout() << "): ";
167
for (const auto& i : item.second->getTensorDesc().getDims()) {
168
slog::info << i << " ";
170
slog::info << slog::endl;
173
size_t imageInputCount = input_image_sizes.size();
174
size_t binaryInputCount = info.size() - imageInputCount;
176
std::vector<std::string> binaryFiles;
177
std::vector<std::string> imageFiles;
179
if (inputFiles.empty()) {
180
slog::warn << "No input files were given: all inputs will be filled with random values!" << slog::endl;
182
binaryFiles = filterFilesByExtensions(inputFiles, supported_binary_extensions);
183
std::sort(std::begin(binaryFiles), std::end(binaryFiles));
185
auto binaryToBeUsed = binaryInputCount*batchSize*requests.size();
186
if (binaryToBeUsed > 0 && binaryFiles.empty()) {
187
std::stringstream ss;
188
for (auto& ext : supported_binary_extensions) {
189
if (!ss.str().empty()) {
194
slog::warn << "No supported binary inputs found! Please check your file extensions: " << ss.str() << slog::endl;
195
} else if (binaryToBeUsed > binaryFiles.size()) {
196
slog::warn << "Some binary input files will be duplicated: " << binaryToBeUsed <<
197
" files are required but only " << binaryFiles.size() << " are provided" << slog::endl;
198
} else if (binaryToBeUsed < binaryFiles.size()) {
199
slog::warn << "Some binary input files will be ignored: only " << binaryToBeUsed <<
200
" are required from " << binaryFiles.size() << slog::endl;
203
imageFiles = filterFilesByExtensions(inputFiles, supported_image_extensions);
204
std::sort(std::begin(imageFiles), std::end(imageFiles));
206
auto imagesToBeUsed = imageInputCount*batchSize*requests.size();
207
if (imagesToBeUsed > 0 && imageFiles.empty()) {
208
std::stringstream ss;
209
for (auto& ext : supported_image_extensions) {
210
if (!ss.str().empty()) {
215
slog::warn << "No supported image inputs found! Please check your file extensions: " << ss.str() << slog::endl;
216
} else if (imagesToBeUsed > imageFiles.size()) {
217
slog::warn << "Some image input files will be duplicated: " << imagesToBeUsed <<
218
" files are required but only " << imageFiles.size() << " are provided" << slog::endl;
219
} else if (imagesToBeUsed < imageFiles.size()) {
220
slog::warn << "Some image input files will be ignored: only " << imagesToBeUsed <<
221
" are required from " << imageFiles.size() << slog::endl;
225
for (size_t requestId = 0; requestId < requests.size(); requestId++) {
226
slog::info << "Infer Request " << requestId << " filling" << slog::endl;
228
size_t imageInputId = 0;
229
size_t binaryInputId = 0;
230
for (const InputsDataMap::value_type& item : info) {
231
Blob::Ptr inputBlob = requests.at(requestId)->getBlob(item.first);
232
if (isImage(inputBlob)) {
233
if (!imageFiles.empty()) {
235
fillBlobImage(inputBlob, imageFiles, batchSize, *item.second, requestId, imageInputId++, imageInputCount);
239
if (!binaryFiles.empty()) {
240
// Fill with binary files
241
if (item.second->getPrecision() == InferenceEngine::Precision::FP32) {
242
fillBlobBinary<float>(inputBlob, binaryFiles, batchSize, requestId, binaryInputId++, binaryInputCount);
243
} else if (item.second->getPrecision() == InferenceEngine::Precision::FP16) {
244
fillBlobBinary<short>(inputBlob, binaryFiles, batchSize, requestId, binaryInputId++, binaryInputCount);
245
} else if (item.second->getPrecision() == InferenceEngine::Precision::I32) {
246
fillBlobBinary<int32_t>(inputBlob, binaryFiles, batchSize, requestId, binaryInputId++, binaryInputCount);
247
} else if (item.second->getPrecision() == InferenceEngine::Precision::U8) {
248
fillBlobBinary<uint8_t>(inputBlob, binaryFiles, batchSize, requestId, binaryInputId++, binaryInputCount);
250
THROW_IE_EXCEPTION << "Input precision is not supported for " << item.first;
255
if (isImageInfo(inputBlob)) {
256
// Fill with image information
257
if (input_image_sizes.size() != 1)
258
THROW_IE_EXCEPTION << "Input " << item.first << " cannot be filled: please provide input binary files!";
260
auto image_size = input_image_sizes.at(0);
261
slog::info << "Fill input '" << item.first << "' with image size " << image_size.first << "x"
262
<< image_size.second << slog::endl;
263
if (item.second->getPrecision() == InferenceEngine::Precision::FP32) {
264
fillBlobImInfo<float>(inputBlob, batchSize, image_size);
265
} else if (item.second->getPrecision() == InferenceEngine::Precision::FP16) {
266
fillBlobImInfo<short>(inputBlob, batchSize, image_size);
267
} else if (item.second->getPrecision() == InferenceEngine::Precision::I32) {
268
fillBlobImInfo<int32_t>(inputBlob, batchSize, image_size);
270
THROW_IE_EXCEPTION << "Input precision is not supported for image info!";
276
slog::info << "Fill input '" << item.first << "' with random values ("
277
<< std::string((isImage(inputBlob) ? "image" : "some binary data"))
278
<< " is expected)" << slog::endl;
279
if (item.second->getPrecision() == InferenceEngine::Precision::FP32) {
280
fillBlobRandom<float>(inputBlob);
281
} else if (item.second->getPrecision() == InferenceEngine::Precision::FP16) {
282
fillBlobRandom<short>(inputBlob);
283
} else if (item.second->getPrecision() == InferenceEngine::Precision::I32) {
284
fillBlobRandom<int32_t>(inputBlob);
285
} else if (item.second->getPrecision() == InferenceEngine::Precision::U8) {
286
fillBlobRandom<uint8_t>(inputBlob);
287
} else if (item.second->getPrecision() == InferenceEngine::Precision::I8) {
288
fillBlobRandom<int8_t>(inputBlob);
289
} else if (item.second->getPrecision() == InferenceEngine::Precision::U16) {
290
fillBlobRandom<uint16_t>(inputBlob);
291
} else if (item.second->getPrecision() == InferenceEngine::Precision::I16) {
292
fillBlobRandom<int16_t>(inputBlob);
294
THROW_IE_EXCEPTION << "Input precision is not supported for " << item.first;