~iliaplatone/spacedrone.eu/inova-sis-pack

« back to all changes in this revision

Viewing changes to etc/samples/benchmark_app/inputs_filling.cpp

  • Committer: Ilia Platone
  • Date: 2022-11-15 16:19:28 UTC
  • Revision ID: git-v1:b9f4c8dff67bb705341db6a18f84a3d5f61c23ce
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2019 Intel Corporation
 
2
// SPDX-License-Identifier: Apache-2.0
 
3
//
 
4
 
 
5
#include <memory>
 
6
#include <string>
 
7
#include <vector>
 
8
#include <algorithm>
 
9
#include <utility>
 
10
 
 
11
#include <format_reader_ptr.h>
 
12
#include <samples/slog.hpp>
 
13
 
 
14
#include "inputs_filling.hpp"
 
15
 
 
16
using namespace InferenceEngine;
 
17
 
 
18
#ifdef USE_OPENCV
 
19
static const std::vector<std::string> supported_image_extensions = { "bmp", "dib",
 
20
                                                                     "jpeg", "jpg", "jpe",
 
21
                                                                     "jp2",
 
22
                                                                     "png",
 
23
                                                                     "pbm", "pgm", "ppm",
 
24
                                                                     "sr", "ras",
 
25
                                                                     "tiff", "tif" };
 
26
#else
 
27
static const std::vector<std::string> supported_image_extensions = { "bmp" };
 
28
#endif
 
29
static const std::vector<std::string> supported_binary_extensions = { "bin" };
 
30
 
 
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);
 
37
    };
 
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);
 
43
        }
 
44
    }
 
45
    return filtered;
 
46
}
 
47
 
 
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();
 
57
 
 
58
    /** Collect images data ptrs **/
 
59
    std::vector<std::shared_ptr<uint8_t>> vreader;
 
60
    vreader.reserve(batchSize);
 
61
 
 
62
    for (size_t i = 0ULL, inputIndex = requestId*batchSize*inputSize + inputId; i < batchSize; i++, inputIndex += inputSize) {
 
63
        inputIndex %= filePaths.size();
 
64
 
 
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;
 
69
            continue;
 
70
        }
 
71
 
 
72
        /** Getting image data **/
 
73
        TensorDesc desc = info.getTensorDesc();
 
74
        std::shared_ptr<uint8_t> imageData(reader->getData(getTensorWidth(desc), getTensorHeight(desc)));
 
75
        if (imageData) {
 
76
            vreader.push_back(imageData);
 
77
        }
 
78
    }
 
79
 
 
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];
 
91
            }
 
92
        }
 
93
    }
 
94
}
 
95
 
 
96
template<typename T>
 
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();
 
106
 
 
107
        slog::info << "Prepare binary file " << filePaths[inputIndex] << slog::endl;
 
108
        std::ifstream binaryFile(filePaths[inputIndex], std::ios_base::binary | std::ios_base::ate);
 
109
        if (!binaryFile) {
 
110
            THROW_IE_EXCEPTION << "Cannot open " << filePaths[inputIndex];
 
111
        }
 
112
 
 
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];
 
117
        }
 
118
 
 
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);
 
123
        }
 
124
        binaryFile.read(reinterpret_cast<char *>(&inputBlobData[i*inputSize]), inputSize);
 
125
    }
 
126
}
 
127
 
 
128
template<typename T>
 
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;
 
133
    }
 
134
}
 
135
 
 
136
template<typename T>
 
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;
 
145
            if (0 == i)
 
146
                inputBlobData[index] = static_cast<T>(image_size.first);
 
147
            else if (1 == i)
 
148
                inputBlobData[index] = static_cast<T>(image_size.second);
 
149
            else
 
150
                inputBlobData[index] = 1;
 
151
        }
 
152
    }
 
153
}
 
154
 
 
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())));
 
164
        }
 
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 << " ";
 
169
        }
 
170
        slog::info << slog::endl;
 
171
    }
 
172
 
 
173
    size_t imageInputCount = input_image_sizes.size();
 
174
    size_t binaryInputCount = info.size() - imageInputCount;
 
175
 
 
176
    std::vector<std::string> binaryFiles;
 
177
    std::vector<std::string> imageFiles;
 
178
 
 
179
    if (inputFiles.empty()) {
 
180
        slog::warn << "No input files were given: all inputs will be filled with random values!" << slog::endl;
 
181
    } else {
 
182
        binaryFiles = filterFilesByExtensions(inputFiles, supported_binary_extensions);
 
183
        std::sort(std::begin(binaryFiles), std::end(binaryFiles));
 
184
 
 
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()) {
 
190
                  ss << ", ";
 
191
              }
 
192
              ss << ext;
 
193
            }
 
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;
 
201
        }
 
202
 
 
203
        imageFiles = filterFilesByExtensions(inputFiles, supported_image_extensions);
 
204
        std::sort(std::begin(imageFiles), std::end(imageFiles));
 
205
 
 
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()) {
 
211
                ss << ", ";
 
212
            }
 
213
            ss << ext;
 
214
          }
 
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;
 
222
        }
 
223
    }
 
224
 
 
225
    for (size_t requestId = 0; requestId < requests.size(); requestId++) {
 
226
        slog::info << "Infer Request " << requestId << " filling" << slog::endl;
 
227
 
 
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()) {
 
234
                    // Fill with Images
 
235
                    fillBlobImage(inputBlob, imageFiles, batchSize, *item.second, requestId, imageInputId++, imageInputCount);
 
236
                    continue;
 
237
                }
 
238
            } else {
 
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);
 
249
                    } else {
 
250
                        THROW_IE_EXCEPTION << "Input precision is not supported for " << item.first;
 
251
                    }
 
252
                    continue;
 
253
                }
 
254
 
 
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!";
 
259
 
 
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);
 
269
                    } else {
 
270
                        THROW_IE_EXCEPTION << "Input precision is not supported for image info!";
 
271
                    }
 
272
                    continue;
 
273
                }
 
274
            }
 
275
            // Fill random
 
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);
 
293
            } else {
 
294
                THROW_IE_EXCEPTION << "Input precision is not supported for " << item.first;
 
295
            }
 
296
        }
 
297
    }
 
298
}